[英]Define list length in recursion in Coq Not sure if my function is wrong and got stuck
所以下面我試圖定義列表長度 function 的尾遞歸版本,並證明 function 與“長度”相同 function 是代碼。 證明時卡住了
Fixpoint length_tail (A: Type) (l: list A) (len: nat): nat :=
match l, len with
| [], len => len
| _ :: t, len => length_tail _ t (1 + len)
end.
Example length_rev: forall {A: Type} {l1: list A},
@length_tail _ l1 0 = @length _ l1.
Proof.
intros.
induction l1.
- simpl. reflexivity.
- simpl.
rewrite <- IHl1.
+ simpl.
Admitted.
以下是“長度”的原始 function:
Fixpoint length (l:natlist) : nat :=
match l with
| nil => O
| h :: t => S (length t)
end.
如果有人可以提供幫助或提供一些提示,將不勝感激! 謝謝!
幾件事:
首先,您在 function 中的累加器l
和len
上進行模式匹配,但您沒有查看它的形狀,以下也可以:
Fixpoint length_tail (A: Type) (l: list A) (len: nat): nat :=
match l with
| [] => len
| _ :: t => length_tail _ t (1 + len)
end.
其次,您面臨的問題是您要通過歸納證明的引理不夠普遍。 實際上,您假設累加器是0
,但正如您在遞歸調用中看到的那樣,您有1 + len
(順便說一下,這只是S len
),它永遠不會等於0
。
為了通過歸納證明這一點,您需要證明一些更強大的東西。 通常,您希望給出一個等於length_tail l len
在length l
方面的表達式,這樣當用0
實例化時,您會得到length l
。
對我來說,聽起來length_tail l len = len + length l
是一個不錯的選擇。 在使用累加器證明函數的屬性時,您必須經常這樣做。
go 關於這個有幾種方法:
assert
,然后以它結束。generalize
你的目標。 我個人不會使用它,但我會展示它來說明一個人可以做什么。Fixpoint length_tail {A : Type} (l: list A) (len: nat): nat :=
match l, len with
| [], len => len
| _ :: t, len => length_tail t (1 + len)
end.
Example length_rev : forall {A: Type} {l : list A},
length_tail l 0 = length l.
Proof.
intros A l.
change (length l) with (0 + length l).
generalize 0 as n.
(* Now the goal is forall n : nat, length_tail l n = n + length l *)
請注意,我在length_tail
中將類型標記為隱式,這樣你不認為它更具可讀性嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.