以下证明在 Coq in a Hurry 中给出:
client-side []
我一步一步地试着去理解发生了什么,但是在解决基本情况后,归纳假设是不一样的!因此,战术失败了:
Fixpoint add n m := match n with 0 => m | S p => add p (S m) end.
Lemma exercise6 : forall n m, add n (S m) = S (add n m).
Proof.
induction n; intros m; simpl.
reflexivity.
rewrite IHn; reflexivity.
Qed.
他们在盯着"重写"的线路上失败,出现以下错误:
错误:在当前目标中找不到子项匹配
Lemma exercise6' : forall n m, add n (S m) = S (add n m). Proof. induction n. intros m. simpl. reflexivity. rewrite IHn. reflexivity. Qed.
。
为什么在逐步编写时相同的代码会失败?分号和句号有什么区别?
此外,有没有办法可以查看 Coq in a Hurry 中提供的证明的逐步进展?
答案 0 :(得分:2)
简而言之:
induction n
生成2个子目标。A;B
将策略B
应用于所有 A
生成的子目标所以在这里,intros m; simpl
适用于induction
生成的2个目标。这意味着您可以通过在intros m
之前插入额外的simpl
和额外的rewrite
来修复您的第二个脚本:
Lemma exercise6' : forall n m, add n (S m) = S (add n m).
Proof.
induction n.
intros m.
simpl.
reflexivity.
intros m.
simpl.
rewrite IHn.
reflexivity.
Qed.
顺便说一句,通过使用项目符号来划分各种子目标,可以使校对脚本的结构更加清晰。这提供了以下两个脚本,您可以在exercise6
中看到intros m; simpl
在进入子目标之前执行了,而在exercise6'
中,他们已被推入每个子目标:
Lemma exercise6 : forall n m, add n (S m) = S (add n m).
Proof.
induction n; intros m; simpl.
- reflexivity.
- rewrite IHn; reflexivity.
Qed.
Lemma exercise6' : forall n m, add n (S m) = S (add n m).
Proof.
induction n.
- intros m.
simpl.
reflexivity.
- intros m.
simpl.
rewrite IHn.
reflexivity.
Qed.