我正在構建一個遞歸函數,它在列表l
上執行match
。在cons
分支中,我需要使用l = cons a l'
爲了證明遞歸函數終止的信息。但是,當我使用match l
時,信息會丟失。Coq:將信息保存在匹配語句中
如何使用match
來保存信息?
下面是函數(drop
和drop_lemma_le
在最後給出,爲便於閱讀):
Fixpoint picksome (l:list nat) (H : Acc lt (length l)) {struct H}: list nat.
refine (
match l with
nil => nil
| cons a l' => cons a (picksome (drop a l') _)
end
).
apply H.
assert (l = cons a l') by admit. (* here is where I need the information *)
rewrite H0.
simpl.
apply le_lt_n_Sm.
apply drop_lemma_le.
Defined. (* Can't end definition here because of the 'admit'. *)
我其實能夠通過refine
定義功能全像下面,但它是不是真的讀。做Print picksome.
揭示Coq如何處理這個問題,但它也是相當長,並且嵌套函數等無法閱讀。
必須有一個更可讀的方式來寫它,對吧?
Fixpoint picksome (l:list nat) (H : Acc lt (length l)) {struct H}: list nat.
Proof.
refine (_).
remember l as L.
destruct l as [| a l'].
apply nil.
apply (cons a).
apply (picksome (drop a l')).
apply H.
rewrite HeqL.
simpl.
apply le_lt_n_Sm.
apply drop_lemma_le.
Defined.
我第一次嘗試是試圖像這樣
Definition list_cons_dec {T} (l:list T) :
{exists a l', l=a::l'} + {~ exists a l', l=a::l'}.
remember l as L.
destruct l as [| a l'].
- right; subst L; intros [a [A B]]; inversion B.
- left; exists a, l'; apply HeqL.
Defined.
Fixpoint picksome (l:list nat) (H : Acc lt (length l)) {struct H}: list nat.
Proof.
refine (
match list_cons_dec l with
| right Hdec => nil
| left Hdec => cons _ (picksome (drop _ _) _)
end
).
destruct l.
inversion Hdec. (* fails *)
我無法擺脫實際a
和l'
是l
被製成。 Coq抱怨:
Error: Inversion would require case analysis on sort Set which is not allowed
for inductive definition ex.
什麼是適當的(可讀)的方式來做到這一點?
下面是drop
和drop_lemma_le
的定義。
Fixpoint drop {T} n (l:list T) :=
match n with
| O => l
| S n' => match l with
| nil => nil
| cons _ l' => drop n' l'
end
end.
Lemma drop_lemma_le : forall {T} n (l:list T), length (drop n l) <= (length l).
Proof.
intros; generalize n;
induction l; intros; destruct n0; try reflexivity.
apply le_S; apply IHl.
Defined.
很好解釋!這一定是相當普遍的模式......?這是寫它最容易讀的方法嗎? (我不抱怨,只是想知道...) – larsr 2014-12-05 15:37:42
是的,這是一個相當常見的模式。特別是在處理依賴型數據時,您需要記住指數在不同分支中的形狀,以便能夠解除其中的一些分支。例如。 [對於長度> 0的向量的安全頭](https://gist.github.com/gallais/aa0aaad9edbc9e361eb2),你希望能夠說「這個零案件永遠不會發生;承諾!」。 – gallais 2014-12-05 15:45:29