[英]Stuck on the proof of a simple Lemma: which induction should I use?
我有以下結構:
Inductive instr : Set :=
| Select : nat -> instr
| Backspace : instr.
Definition prog := list instr.
和以下功能:
Fixpoint Forward (input output: list nat) : option prog :=
match input with
| nil => match output with
| nil => Some nil
| y::r => None
end
| x::rest => match output with
| nil => match rest with
| nil => None
| xx::rrest => match (Forward rrest nil) with
| Some pp => Some ((Select x) :: Backspace :: pp)
| None => None
end
end
| y::r => if ( beq_nat x y ) then match (Forward rest r) with
| Some pp => Some ((Select x) :: pp)
| None => None
end
else match rest with
| nil => None
| xx::rrest => match (Forward rrest output) with
| Some pp => Some ((Select x) :: Backspace :: pp)
| None => None
end
end
end
end.
現在我想證明這個簡單的引理:
Lemma app_forward :
forall (p p':prog) (input1 input2 output1 output2:list nat),
Forward input1 output1 = Some p ->
Forward input2 output2 = Some p' ->
Forward (input1 ++ input2) (output1 ++ output2) = Some (p++p').
無論我使用什么歸納原理,我都被卡住了。 一定有一些我看不到的明顯的東西。 有人不能幫我證明這個嗎?
謝謝 !!
你的問題有兩個問題。 第一個是你要證明的陳述是假的,這里是一個反例的證明。
Lemma not_app_forward :
not
(forall (p p':prog) (input1 input2 output1 output2:list nat),
Forward input1 output1 = Some p ->
Forward input2 output2 = Some p' ->
Forward (input1 ++ input2) (output1 ++ output2) = Some (p++p')).
Proof.
intros abs.
assert (tmp := abs (Select 1 :: Backspace :: nil) (Select 1 :: Select 2 :: nil)
(1 :: 2 :: nil) (1 :: 2 :: nil) nil (1 :: 2 :: nil) refl_equal refl_equal).
compute in tmp.
discriminate.
Qed.
因此,與您的說法相反,這不是一個簡單的引理。
第二個問題是函數形狀復雜,歸納證明難以組織。 我將在下面介紹這方面。
從函數Forward
的結構來看,您應該通過對input
參數進行歸納來執行證明是很自然的,因為它是在子項上發生遞歸調用的參數。 然而,遞歸調用不僅發生在直接子項上(如Forward rest ...
)而且還發生在子項的子項中(如Forward rrest ...
),這一事實使證明變得復雜。
有幾種方法可以解決這個困難,但都需要一些解釋或學習。
1 - 一種方法是使用 Coq 的Equations
插件並使用 Equations 重新定義您的Forward
函數。 然后,您可以使用功能歸納來解決您的問題:這將使用專門針對您的問題量身定制的歸納原則。
2 - 第二種方法是手動構建定制的感應原理。 這是一個嘗試。
Definition two_step_list_induction {A : Type} :
forall (P : list A -> Prop),
P nil ->
(forall a, P (a :: nil)) ->
(forall a b tl,
P (b :: tl) -> P tl -> P (a :: b :: tl)) ->
forall l, P l.
Proof.
intros P Pn P1 Prec.
fix tsli 1.
intros [ | x l].
exact Pn.
generalize (tsli l).
destruct l as [ | y tl]; intros Pl.
exact (P1 x).
apply Prec;[assumption | exact (tsli tl)].
Defined.
然后,您可以使用以下形狀的命令開始您的證明:
Lemma app_forward :
forall (p p':prog) (input1 input2 output1 output2:list nat),
Forward input1 output1 = Some p ->
Forward input2 output2 = Some p' ->
Forward (input1 ++ input2) (output1 ++ output2) = Some (p++p').
Proof.
intros p p' input1; revert p; induction input1 as [ | a | a b tl Ih1 Ih2]
using two_step_list_induction.
但是,正如我已經說過的,你想要證明的引理實際上是錯誤的,所以這個證明永遠不會奏效,我也無法說明所提出的方法會奏效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.