簡體   English   中英

在 Coq 中遞歸定義列表長度不確定我的 function 是否錯誤並卡住

[英]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 中的累加器llen上進行模式匹配,但您沒有查看它的形狀,以下也可以:

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 lenlength 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM