我正在努力确切地了解证明程序正确的含义。我从零开始,在第一步/主题介绍中挂断了。
在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)
到目前为止,两者都没有帮助。谁能告诉我如何进行归纳?或链接到显示证据的页面(我搜索过,找不到任何内容)。
答案 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
中的两个值1
和f 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+1
到k
以及k+1
到k-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)以避免在每一步中重新计算,这就给你一个证明的想法,然后你将其形式化。