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

时间:2016-11-13 07:26:38

标签: functional-programming coq factorial

我想证明两个因子函数在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.

2 个答案:

答案 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.