Functional programming Coq:用归纳法证明两个阶乘函数的相等性

Functional programming Coq:用归纳法证明两个阶乘函数的相等性,functional-programming,coq,factorial,Functional Programming,Coq,Factorial,我想用归纳法证明两个阶乘函数在Coq中是等价的 基本情况n=0很简单,但归纳情况更复杂。我明白了,如果我能把(访问fac\u v2 n'(n*a))改写成n*(访问fac\u v2 n'a),我就完了。然而,把这个想法翻译成Coq会给我带来麻烦 如何在Coq中证明这一点 定点fac_v1(n:nat):nat:= 匹配 | 0 => 1 |sn'=>n*(fac_v1 n') 结束。 固定点访问(n a:nat):nat:= 匹配 |0=>a |sn'=>访问工厂v2 n'(n*a) 结束。 定

我想用归纳法证明两个阶乘函数在Coq中是等价的

基本情况
n=0
很简单,但归纳情况更复杂。我明白了,如果我能把
(访问fac\u v2 n'(n*a))
改写成
n*(访问fac\u v2 n'a)
,我就完了。然而,把这个想法翻译成Coq会给我带来麻烦

如何在Coq中证明这一点

定点fac_v1(n:nat):nat:=
匹配
| 0 => 1
|sn'=>n*(fac_v1 n')
结束。
固定点访问(n a:nat):nat:=
匹配
|0=>a
|sn'=>访问工厂v2 n'(n*a)
结束。
定义fac_v2(n:nat):nat:=
访问工厂1号。
_fac_v1_和_fac_v2的命题等价性:
福尔n:纳特,
fac_v1 n=fac_v2 n。
证明。
中止

在归纳案例中,您可以应用归纳假设并将目标简化为:

visit_fac_v2 n 1+n*visit_fac_v2 n 1=visit_fac_v2 n(S n)
为了证明这一点,可以使用以下引理:

引理访问\u fac\u v2\u摘录:
答:纳特,
访问工厂v2 n a=a*访问工厂v2 n 1。

当证明直接式函数及其基于累加器的等价函数相等时,通常要做的一件事是声明一个更强的不变量,该不变量对于累加器可能持有的任何值都应该为真

然后,您可以将其专门化为调用函数的值,从而获得您感兴趣的语句,作为更一般的语句的推论

这里的一般声明如下:

Theorem general_equivalence_of_fac_v1_and_fac_v2 :
  forall n a : nat,
    a * fac_v1 n = visit_fac_v2 n a.
它的证明相当简单(你必须小心,确保
归纳法
导言a
之前,因为你希望归纳法假设对任何
a
都有效):

证明。
介绍n;诱导n;介绍a。
-单纯形;铃声。

-单纯形;重写什么是“简单”和“戒指”?战术
simpl
在目标中计算,并
ring
求解环上的等式。是否可以仅使用“重写”和“应用”重新布线校样?更精确一点:
ring
也求解环上的等式,这是nat
的一个实例。要使用
策略,我们需要
要求导入算术。
要求导入算术。
,因为后者导出前者。@Shuzheng当然:不用
证明等式,你可以重写或应用引理说明
(*)
的属性(例如,
apply PeanoNat.Nat.mul_1_r
可以代替第一次呼叫
ring
)。这只会有点烦人。
Proof.
intros n; induction n; intro a.
 - simpl ; ring.
 - simpl ; rewrite <- IHn ; ring.
Qed.