【问题标题】:General proof strategies to show correctness of recursive functions?显示递归函数正确性的通用证明策略?
【发布时间】:2023-06-17 09:19:01
【问题描述】:

我想知道是否存在任何证明算法正确性的规则/方案?例如,我们在自然数上定义了一个函数 $F$,并定义如下:

function F(n,k)
begin
  if k=0 then return 1
  else if (n mod 2 = 0) and (k mod 2 = 1) then return 0
  else return F(n div 2, k div 2);
end;

其中 $n \ \text{div}\ 2 = \left\lfloor\frac{n}{2}\right\rfloor$

任务是证明 $F(n,k)= \begin{cases} 1 \Leftrightarrow {n \choose k} \ \text{mod} \ 2 = 1 \ 0 \text{ else } \end {案例} $

它看起来不是很复杂(我错了吗?),但我不知道这种证明应该如何构建。非常感谢您的帮助。

【问题讨论】:

    标签: algorithm math recurrence proof


    【解决方案1】:

    递归算法的正确性通常由mathematical induction 证明。该方法由两部分组成:首先,建立基础,然后使用归纳步骤。

    在您的情况下,基础是 k=0 或 k 为奇数但 n 为偶数时的所有情况。

    归纳步骤需要证明当f(n,k)正确时,f(2*n,2*k)f(2*n+1,2*k)f(2*n,2*k+1)f(2*n+1,2*k+1)都是正确的。

    【讨论】:

    • 我比我的回答更喜欢这个。最好添加一个证明,证明 4 个派生案例涵盖 NxN,以证明归纳结论是正确的。
    • 我最喜欢这种方法。但是对我来说仍然不简单,如何使用归纳基础来展示这些含义..
    • f(2*n+1,k) 有错字吗?应该是 f(2*n+1, 2*k) ?
    • @xan 是的,绝对!我在答案中修复了它。
    • @xan 基础必须自己证明,与步骤分开。它应该相当容易。该步骤的四个公式需要分别证明:你需要证明f(n,k)正确足够f(2*n,2*k)正确;然后你做其他三个。
    【解决方案2】:

    除了在数学上证明你的逻辑(例如:inductive proof)之外,还有一些与此相关的计算科学成果。

    您可以从这里开始了解主题:Correctness
    对于您的特定情况,您会对部分正确性感兴趣,以表明答案是预期的。然后完全正确地表明程序终止了。

    Hoare logic可以解决你的部分正确。

    至于这个特定问题的终止:

    如果 (n%2==0 and k%1==1) 或 (k==0) 程序终止,否则将递归到 n/2, k/2 的情况。
    在 k 上使用strong induction,我们可以证明程序总是到达 k==0 的终端节点之一。 (它可能在第一个子句之前终止,但我们只需要证明它完全终止,就是这样)

    所以我把部分正确性的证明留给了你(因为我不知道那些东西)

    【讨论】:

      【解决方案3】:

      一般来说,您会尝试通过归纳来证明其正确性。这在证明递归函数的正确性时非常有效,因为您可以直接证明基本情况,然后可以使用该函数适用于“较小”输入的事实来证明它适用于下一个最大的输入。

      在这种情况下,我会尝试通过有根据的归纳来证明。具体来说,我会证明这一点

      1. 该函数对于 (n, 0) 形式的所有输入都是正确的。
      2. 假设对于所有输入 (n', k') 使得 (n', k') 在字典顺序上小于 (n, k),则该函数是正确的,证明它对于 (n, k) 是正确的.

      这个证明的细节需要利用你的函数的细节和二项式系数的 bahvaior,但一般模板如上。

      希望这会有所帮助!

      【讨论】: