How do I prove that two Fibonacci implementations are equal in Coq?

后端 未结 6 1269
南方客
南方客 2021-01-03 16:36

I\'ve two Fibonacci implementations, seen below, that I want to prove are functionally equivalent.

I\'ve already proved properties about natural numbers, but this ex

6条回答
  •  难免孤独
    2021-01-03 16:53

    There is a very powerful library -- math-comp written in the Ssreflect formal proof language that is in its turn based on Coq. In this answer I present a version that uses its facilities. It's just a simplified piece of this development. All credit goes to the original author.

    Let's do some imports and the definitions of our two functions, math-comp (ssreflect) style:

    From mathcomp
    Require Import ssreflect ssrnat ssrfun eqtype ssrbool.
    
    Fixpoint fib_rec (n : nat) {struct n} : nat :=
      if n is n1.+1 then
        if n1 is n2.+1 then fib_rec n1 + fib_rec n2
        else 1
      else 0.
    
    Fixpoint fib_iter (a b n : nat) {struct n} : nat :=
      if n is n1.+1 then
        if n1 is n2.+1
          then fib_iter b (b + a) n1
          else b
        else a.
    

    A helper lemma expressing the basic property of Fibonacci numbers:

    Lemma fib_iter_property : forall n a b,
      fib_iter a b n.+2 = fib_iter a b n.+1 + fib_iter a b n.
    Proof.
    case=>//; elim => [//|n IHn] a b; apply: IHn.
    Qed.
    

    Now, let's tackle equivalence of the two implementations. The main idea here, that distinguish the following proof from the other proofs has been presented as of time of this writing, is that we perform kind of complete induction, using elim: n {-2}n (leqnn n). This gives us the following (strong) induction hypothesis:

    IHn : forall n0 : nat, n0 <= n -> fib_rec n0 = fib_iter 0 1 n0
    

    Here is the main lemma and its proof:

    Lemma fib_rec_eq_fib_iter : fib_rec =1 fib_iter 0 1.
    Proof.
    move=>n; elim: n {-2}n (leqnn n)=> [n|n IHn].
      by rewrite leqn0; move/eqP=>->.
    case=>//; case=>// n0; rewrite ltnS=> ltn0n.
    rewrite fib_iter_property.
    by rewrite <- (IHn _ ltn0n), <- (IHn _ (ltnW ltn0n)).
    Qed.
    

提交回复
热议问题