我想证明两个因子函数在Coq中使用归纳是等效的。
基本案例n = 0
很容易,但是,归纳案例更复杂。我知道,如果我可以将(visit_fac_v2 n' (n * a))
重写为n * (visit_fac_v2 n' a)
,我就会完成。然而,将这个想法转化为Coq会让我感到麻烦。
如何才能在Coq中证明这一点?
Fixpoint fac_v1 (n : nat) : nat :=
match n with
| 0 => 1
| S n' => n * (fac_v1 n')
end.
Fixpoint visit_fac_v2 (n a : nat) : nat :=
match n with
| 0 => a
| S n' => visit_fac_v2 n' (n * a)
end.
Definition fac_v2 (n : nat) : nat :=
visit_fac_v2 n 1.
Proposition equivalence_of_fac_v1_and_fac_v2 :
forall n : nat,
fac_v1 n = fac_v2 n.
Proof.
Abort.
答案 0 :(得分:4)
当证明直接式函数及其基于累加器的等价函数相等时,一个典型的事情就是声明一个更强的不变量,对于累加器可以容纳的任何值都应该是真的。
然后,您可以将其专门化为调用函数的值,从而获得您感兴趣的语句,作为更一般的语句的推论。
这里的一般声明如下:
Theorem general_equivalence_of_fac_v1_and_fac_v2 :
forall n a : nat,
a * fac_v1 n = visit_fac_v2 n a.
它的证明非常简单(您必须小心并确保induction
出现在intro a
之前,因为您希望归纳假设对任何 {有效{1}}):
a
你的命题是这个更一般定理的直接结果。
答案 1 :(得分:1)
在归纳案例中,您可以应用归纳假设并将目标简化为:
visit_fac_v2 n 1 + n * visit_fac_v2 n 1 = visit_fac_v2 n (S n)
为了证明这一点,您可以使用以下引理:
Lemma visit_fac_v2_extract:
forall n a : nat,
visit_fac_v2 n a = a * visit_fac_v2 n 1.