當我試圖證明一個關於遞歸函數定理(見下文),我在還原表現結束了如何使勒柯克評估特定歸約(或 - ?它爲什麼在這種情況下拒絕)
(fix picksome L H := match A with .... end) L1 H1 = RHS
我想展開match
表達式,但Coq拒絕。做simpl
只是將右側擴展成難以理解的混亂。 Coq爲什麼不能用simpl; reflexivity
完成證明,應該如何指導Coq精確地擴展redex,並完成證明?
功能是一個遞歸函數pick
,需要一個list nat
並採取第一nat
稱爲a
,下降從列表中選擇以下a
項目,以及遞歸其餘的名單上。即
pick [2;3;4;0;1;3])=[2; 0; 1]
我試圖證明的這個定理是函數在只包含零的列表上「什麼都不做」。下面是通向這一問題的發展:
Require Import Arith.
Require Import List.
Import ListNotations.
Fixpoint drop {T} n (l:list T) :=
match n,l with
| S n', cons _ l' => drop n' l'
| O, _ => l
| _, _ => nil
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.
二引理:
Lemma picksome_term: forall l l' (a :nat),
l = a::l' -> Acc lt (length l) -> Acc lt (length (drop a l')).
Proof.
intros; apply H0; rewrite H; simpl; apply le_lt_n_Sm; apply drop_lemma_le.
Defined.
一些更多的定義:
Fixpoint picksome (l:list nat) (H : Acc lt (length l)) {struct H}: list nat :=
match l as m return l=m -> _ with
| nil => fun _ => nil
| cons a l' => fun Hl =>
cons a (picksome (drop a l')
(picksome_term _ _ _ Hl H))
end
(eq_refl _).
Definition pick (l:list nat) : list nat := picksome l (lt_wf (length l)).
Inductive zerolist : list nat -> Prop :=
| znil : zerolist nil
| hzlist : forall l, zerolist l -> zerolist (O::l).
現在,我們可以證明我們的定理˚F我們有引理H
:
Theorem pickzero': (forall k, pick (0::k) = 0::pick k) ->
forall l, zerolist l -> pick l = l.
Proof.
intros H l H0; induction H0; [ | rewrite H; rewrite IHzerolist]; reflexivity.
Qed.
(* but trying to prove the lemma *)
Lemma pickzero_lemma : forall k, pick (0::k) = 0::pick k.
induction k; try reflexivity.
unfold pick at 1.
unfold picksome.
這是我們的目標和背景:
a : nat
k : list nat
IHk : pick (0 :: k) = 0 :: pick k
============================
(fix picksome (l : list nat) (H : Acc lt (length l)) {struct H} :
list nat :=
match l as m return (l = m -> list nat) with
| [] => fun _ : l = [] => []
| a0 :: l' =>
fun Hl : l = a0 :: l' =>
a0 :: picksome (drop a0 l') (picksome_term l l' a0 Hl H)
end eq_refl) (0 :: a :: k) (lt_wf (length (0 :: a :: k))) =
0 :: pick (a :: k)
是否有可能只是減少匹配而不是運行整個'simp'? – larsr 2014-12-08 14:35:20
我不知道任何「簡單」的方法來做到這一點。在這種情況下,我將單步縮減寫爲一個引理,大多數情況下我都會使用「簡單」和「反身性」,然後用它重寫。 – Vinz 2014-12-08 15:26:52