显示两种不同的斐波那契函数是等价的

时间:2011-12-08 08:51:25

标签: haskell functional-programming fibonacci correctness induction

我正在努力确切地了解证明程序正确的含义。我从零开始,在第一步/主题介绍中挂断了。

this paper总函数式编程中,给出了斐波那契函数的两个定义。传统的一个:

fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
--fib (n+2) = fib (n+1) + fib (n+2) --The definition as given in the paper 
                                    --It seems incorrect to me. Typo?

和我以前从未见过的尾递归版本:

fib' n = f n 0 1
f 0 a b = a
f n a b = f (n-1) b (a+b)

该论文随后声称,通过归纳证明两个函数对所有正整数n都返回相同的结果是“直截了当”的。这是我第一次想到分析这样的程序。认为你可以证明两个程序是等价的,这是非常有趣的,所以我立即尝试通过感应来做这个证明。要么我的数学技能都生锈了,要么任务实际上并不那么简单。

我证明了n = 1

fib' 1 = f 1 0 1
       = f 0 1 1
       = 1
fib 1  = 1 (By definition)
therefore
fib' n = fib n for n = 1

我做了n = k假设

fib' k  = fib k
f k 0 1 = fib k

我开始尝试证明如果假设成立,那么函数也等于n = k + 1(因此它们对于所有n> = 1 QED都是等价的)

fib' (k+1)  = fib (k+1)
f (k+1) 0 1 = fib k + fib (k-1)

我尝试了各种操作,在正确的时间代替假设,等等,但我不能让LHS等于RHS,因此证明函数/程序是等价的。我错过了什么?该文件提到该任务相当于证明

f n (fib p) (fib (p+1)) = fib (p+n)

通过诱导任意p。但我不明白这是怎么回事。作者是如何得出这个等式的?只有在p = 0时,这才是对等式的有效转换。我不明白这意味着它对任意p有效。要证明它是任意p需要你经历另一层归纳。当然,要证明的正确公式是

fib' (n+p)  = fib (n+p)
f (n+p) 0 1 = fib (n+p)

到目前为止,两者都没有帮助。谁能告诉我如何进行归纳?或链接到显示证据的页面(我搜索过,找不到任何内容)。

5 个答案:

答案 0 :(得分:11)

在Agda中经过机器检查的打击垫证明版本:

module fibs where

open import Data.Nat
open import Relation.Binary.PropositionalEquality

fib : ℕ → ℕ
fib 0 = 0
fib 1 = 1
fib (suc (suc n)) = fib n + fib (suc n)

f : ℕ → ℕ → ℕ → ℕ
f 0 a b = a
f (suc n) a b = f n b (a + b)

fib' : ℕ → ℕ
fib' n = f n 0 1

-- Exactly the theorem the user `pad` proposed:
Theorem : ℕ → Set
Theorem n = ∀ k → f n (fib k) (fib (suc k)) ≡ fib (k + n)

-- Helper theorems about natural numbers:
right-identity : ∀ k → k ≡ k + 0
right-identity zero = refl
right-identity (suc n) = cong suc (right-identity n)

1+m+n≡m+1+n : ∀ n k → suc (n + k) ≡ n + suc k
1+m+n≡m+1+n zero k = refl
1+m+n≡m+1+n (suc n) k = cong suc (1+m+n≡m+1+n n k)

-- The base case. 
-- Theorem 0 by definition expands to (∀ k → fib k ≡ fib (k + 0))
-- and we prove that using the right-identity theorem.
th-base : Theorem 0
th-base k = cong fib (right-identity k)

-- The inductive step.
-- The definitions are expanded automatically, so (Theorem (suc n)) is
--   (∀ k → f n (fib (suc k)) (fib (suc (suc k))) ≡ fib (k + suc n))
-- We can apply the induction hypothesis to rewrite the LHS to 
--   (fib (suc k + n))
-- which is equal to the RHS by the 1+m+n≡m+1+n theorem.
th-step : ∀ n → Theorem n → Theorem (suc n)
th-step n hyp k = trans (hyp (suc k)) (cong fib (1+m+n≡m+1+n k n))

-- The inductive proof of Theorem using th-base and th-step.
th : ∀ n → Theorem n
th zero = th-base
th (suc n) = th-step n (th n)

-- And the final proof:
fibs-equal : ∀ n → fib' n ≡ fib n
fibs-equal n = th n 0

答案 1 :(得分:10)

我无法访问上面提到的论文,但是他们的广义定理是一个很好的方法。 0中的两个值1f n 0 1听起来像魔数;但是如果你把它们推广到Fibonacci数字,就可以更容易地进行证明了。

为避免在阅读证明时出现混淆,fib k写为F(k),并且还删除了一些不必要的括号。我们有一个广义定理:forall k. fib' n F(k) F(k+1) = F(k+n)并通过n上的归纳来证明它。

n = 1的基本情况:

fib' 1 F(k) F(k+1) = F(k+1) // directly deduce from definition of fib'

归纳步骤:

我们有归纳假设:

forall k. fib' n F(k) F(k+1) = F(k+n)

我们必须证明:

forall k. fib' (n+1) F(k) F(k+1) = F(k+(n+1))

证据从左侧开始:

fib' (n+1) F(k) F(k+1)
= fib' n F(k+1) (F(k) + F(k+1)) // definition of fib'
= fib' n F(k+1) F(k+2) // definition of F (or fib)
= F((k+1)+n) // induction hypothesis
= F(k+(n+1)) // arithmetic

我们完成了广义证明。您的示例也得到了证明,因为它是k=0的上述定理的特定情况。

作为旁注,fib'并不奇怪;它是fib的尾递归版本。

答案 2 :(得分:5)

我相信使用Strong Induction更容易识别您的证据:

  

......在第二步中,我们不仅可以假设语句适用于n = m,而且对于所有小于或等于m的n都是正确的。

你被困在这里:

fib' (k+1)  = fib (k+1)
f (k+1) 0 1 = fib k + fib (k-1)

..部分原因是您需要同时执行k+1k以及k+1k-1的步骤。

对不起,这不是更有说服力,因为我已经做了真实的证据,所以

答案 3 :(得分:4)

如果论文说它等同于

Lemma:
f n (fib p) (fib (p+1)) = fib (p+n)

我们应该首先证明这一点。这里的关键是使用广义归纳,即跟踪你的forall量词。

首先我们展示

forall p, f 0 (fib p) (fib (p+1)) = fib p = fib (p + 0)

现在,我们假设归纳假设

forall p, f n (fib p) (fib (p+1)) = fib (p + n)

并显示

forall p, f (n+1) (fib p) (fib (p+1)) = f n (fib (p+1)) (fib (p+1) + fib p)
                                      = f n (fib (p+1)) (fib (p + 2)) --By def of fib
                                      = fib ((p + 1) + n) --By induction hypothesis
                                      = fib (p + (n+1))

所以,这显示了引理。

这样可以很容易地证明您的目标。如果你有

fib' n = f n 0 1
       = f n (fib 0) (fib (0 + 1)) --by def of fib
       = fib (n + 1) --by lemma
不过,如果您对此类事情感兴趣,我建议您查看Benjamin Pierce关于“软件基础”的免费书籍。它是使用Coq校对助手的编程语言课程的教科书。 Coq就像一个更丑陋,更简洁,更强大的Haskell,可以让你证明你的功能属性。做真正的数学(四色定理的证明)就足够了,但最自然的事情就是证明正确的功能程序。我觉得让电脑检查我的工作真好。而且,Coq中的所有功能都是全部......

答案 4 :(得分:3)

有时候,不要过于正式,这是一个好主意。我想一旦你看到尾递归版只是简单地传递F(n-2)和F(n-1)以避免在每一步中重新计算,这就给你一个证明的想法,然后你将其形式化。