显示两个不同的斐波那契函数是等价的
我正在尝试确切地了解证明程序正确意味着什么。我从头开始,并沉迷于第一步/该主题的介绍。
在 这篇关于全函数式编程的论文给出了斐波那契函数的两个定义。传统的:
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)
到目前为止,这也没有帮助。谁能告诉我如何进行诱导?或者链接到显示证明的页面(我进行了搜索,找不到任何内容)。
I'm trying to learn exactly what it means to prove a program correct. I'm starting from scratch and getting hung up on the first steps/the introduction to the topic.
In this paper on total functional programming, two definitions of the fibonacci function are given. The traditional one:
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?
and a tail recursive version I had never seen before:
fib' n = f n 0 1
f 0 a b = a
f n a b = f (n-1) b (a+b)
The paper then claimed that it is "straightforward" to prove by induction that both functions return the same result for all positive Integers n. This is the first time I've thought of analysing programs like this. It's quite interesting to think that you can prove that two programs are equivilent, so I immediately tried to do this proof by induction myself. Either my maths skills are rusty or the task is not actually all that straightforward.
I proved for 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
I made the n = k assumption
fib' k = fib k
f k 0 1 = fib k
I start trying to prove that if the assumption holds true, then the functions are also equivilant for n = k + 1 (and hence they are all equivalent for all n >= 1 QED)
fib' (k+1) = fib (k+1)
f (k+1) 0 1 = fib k + fib (k-1)
I've tried various manipulations, substituting the assumption in at the right time and so on, but I just can't get LHS to equal RHS and therefore prove that the functions/programs are equivalent. What am I missing? The paper mentions that the task is equivalent to proving
f n (fib p) (fib (p+1)) = fib (p+n)
by induction for arbitrary p. But I don't see how that's true at all. How did the authors arrive at this equation? That's a valid transformation on the equation only if p = 0
. I don't see how that means it works for arbitrary p. To prove it for arbitrary p requires you to go through another layer of induction. Surely the correct formula to prove would be
fib' (n+p) = fib (n+p)
f (n+p) 0 1 = fib (n+p)
So far that hasn't helped either. Can anyone show me how the induction would be done? Or link to a page that shows the proof (I did search, couldn't find anything).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Agda 中 pad 证明的机器检查版本:
The machine-checked version of pad's proof in Agda:
我无法访问上述论文,但他们的广义定理是一个很好的方法。
fn 0 1
中的两个值0
和1
听起来像是魔法数字;但是,如果将它们推广到斐波那契数列,则证明会更容易进行。为了避免在阅读证明时造成混淆,将
fib k
写为F(k)
,并删除了一些不必要的括号。我们有一个广义定理:forall k。 fib' n F(k) F(k+1) = F(k+n)
并通过对n
进行归纳证明。n=1 的基本情况:
归纳步骤:
我们有归纳假设,其中:
我们必须证明:
证明从左侧开始:
我们完成了广义证明。您的示例也得到了证明,因为它是上述定理
k=0
的具体情况。顺便说一句,
fib'
一点也不奇怪;它是 fib 的尾递归版本。I couldn't access to the above mentioned paper, but their generalized theorem is a good way to go. Two values
0
and1
inf n 0 1
sound like magic numbers; however if you generalize them to Fibonacci numbers, a proof is much easier to be conducted.To avoid confusion when reading the proof,
fib k
is written asF(k)
and some unnecessary parentheses are also removed. We have a generalized theorem:forall k. fib' n F(k) F(k+1) = F(k+n)
and prove it by induction onn
.Base case with n=1:
Inductive step:
We have the induction hypothesis where:
And we have to prove:
The proof starts from the left-hand side:
We completed the generalized proof. Your example is also proven because it is a specific case of the above theorem with
k=0
.As a side note,
fib'
isn't strange at all; it is a tail-recursive version offib
.我相信使用强归纳你的证明会更容易识别:
您被困在这里:
..部分原因是您需要从
k+1
到k
的步骤,而且还需要k+1
到k-1
。抱歉,这并没有更有说服力,我已经多年没有做过真正的证明了。
I believe your proof would be easier to recognize with Strong Induction:
You were getting stuck here:
.. in part because you need to have both the steps from
k+1
tok
but alsok+1
tok-1
.Sorry this isn't more convincing, it's been years since I've done real proofs.
如果论文说它等同于
我们应该从证明这一点开始。这里的关键是使用广义归纳法,即跟踪所有量词。
首先我们展示
现在,我们假设归纳假设
并展示
所以,这展示了引理。
这让你很容易证明你的目标。如果你有
顺便说一句,如果你对这类事情感兴趣,我建议你看看 Benjamin Pierce 的免费书籍《软件基础》。它是使用 Coq 证明助手的编程语言课程的教科书。 Coq 就像一个更丑陋、更简单、更强大的 Haskell,可以让你证明函数的属性。做真正的数学(证明四色定理)就足够了,但最自然的事情是证明正确的函数程序。我发现让计算机检查我的工作真是太好了。而且,Coq 中的所有函数都是完整的......
If the paper says it is equivalent to
we should start by proving that. The key here is use generalized induction, that is, keep track of your forall quantifiers.
First we show
Now, we assume the inductive hypothesis
and show
So, that shows the lemma.
That makes it easy to prove your goal. If you have
Btw, if you are interested in this kind of thing, I suggest you check out Benjamin Pierce's free book on "Software Foundations." It is the textbook for a course on programming languages that uses the Coq proof assistant. Coq is like an uglier, meaner, and more powerful Haskell that lets you prove properties of your functions. It is good enough to do real math (prove of four color theorem), but the most natural thing to do in it is proven correct functional programs. I find it nice to have a computer check my work. And, all functions in Coq are total...
有时一开始不要太正式是个好主意。我认为,一旦您看到尾递归版本只是传递 F(n-2) 和 F(n-1) 以避免在每个步骤中重新计算,这就会为您提供一个证明想法,然后将其形式化。
It is sometimes a good idea to not start out too formal. I think as soon as you see that the tail recursive version simply passes F(n-2) and F(n-1) around to avoid recalculation in each step, this gives you a proof idea, which you then formalize.