我不明白你的方法。當參數是非空向量時,您總是返回一個非空向量,但take
必須返回nil
,而不管向量是否爲p=0
。
以下是建立take
的一種方法。我沒有使用假設p <= n
,而是將參數n
的長度表示爲要採用的元素的數量與尾部元素的數量m
的總和,其可能是如果p <= n
。這允許更容易的遞歸定義,因爲(S p') + m
在結構上等於S (p' + m)
。請注意,區分度取決於要採用的元素數量:如果採用0返回nil
,否則返回cons head new_tail
。
該版本的take
函數具有所需的計算行爲,所以剩下的就是定義一個具有所需證明內容的函數。我使用Program
功能來方便地執行此操作:填寫計算內容(微不足道,我只需要說我想用m = n - p
),然後完成證明義務(這是簡單的算術)。
Require Import Arith.
Require Import Vector.
Fixpoint take_plus {A} {m} (p:nat) : t A (p+m) -> t A p :=
match p return t A (p+m) -> t A p with
| 0 => fun a => nil _
| S p' => fun a => cons A (hd a) _ (take_plus p' (tl a))
end.
Program Definition take A n p (a : t A n) (H : p <= n) : t A p :=
take_plus (m := n - p) p a.
Solve Obligations using auto with arith.
爲了您newdrop : forall A n p, t A n -> p <= n -> t A (n-p)
,下面的方法工作。你需要通過告訴它什麼p
和n
成爲遞歸調用來幫助Coq。
Program Fixpoint newdrop {A} {n} p : t A n -> p <= n -> t A (n-p) :=
match p return t A n -> p <= n -> t A (n-p) with
| 0 => fun a H => a
| S p' => fun a H => newdrop p' (tl a) (_ : p' <= n - 1)
end.
Next Obligation.
omega.
Qed.
Next Obligation.
omega.
Qed.
Next Obligation.
omega.
Qed.
Next Obligation.
omega.
Qed.
我不知道爲什麼Solve Obligations using omega.
不工作,但每解決個別的義務工作。
我不知道如何回答你的問題,但是當我想要認真學習Coq時,我買了一本好書。它被稱爲「交互定理證明和發展」。此外,這個問題可能更適合cs.se,但我不確定。 – 2014-09-26 22:36:43
@PhilipWhite這不是關於[cs.se]的話題,因爲它嚴格地關於Coq中的編程,而不是理解理論基礎。這個問題在[so]上會很好。 – Gilles 2014-09-27 22:22:31
@krokodil - 這個問題在這裏是題外話,因爲它不是關於CS理論。如果您願意,我可以遷移您的問題堆棧溢出。否則,這個問題將很快關閉。 – 2014-09-28 01:20:52