如何根据此递归函数确定度量函数?

时间:2013-03-14 00:26:05

标签: functional-programming logic acl

一个函数在ACL2中定义,我们的任务是创建一个测量函数来帮助证明终止。这是函数定义:

(defunc f (x a)
  :input-contract (and (integerp x) (listp a))
  :output-contract (integerp (f x a))
  (cond
   ((endp a)                 68)
   ((equal (len a) x)        71)
   ((equal (len a) (+ x 1))  74)
   ((< x (len a))            (f (+ x 1) (rest a)))
   (t                        (f (- x 1) (cons 1 a)))))

解决方案测量功能就是这个(简写):

(m x a) = (if (equal (len a) (+ x 1))
              0
              (abs (- (len a) x)))

我们能够根据函数中的两个递归调用确定包含measure函数的else情况。但是,我们不了解其余部分,以及确定此度量函数的过程。

供参考,测量功能:

  1. m是对f;
  2. 参数定义的可容许函数
  3. m与f;
  4. 具有相同的输入合约
  5. m有一个输出合同,表明它总是返回一个自然数;和
  6. 在每次递归调用时,m应用于该递归调用的参数减少, 在导致递归呼叫的条件下。
  7. 导致确定此度量函数的过程是什么?

1 个答案:

答案 0 :(得分:1)

在确定一个度量函数时,问自己的问题是:在每次迭代中消耗的“潜在能量”是什么,在某一点它已经消失并且迭代停止了?

首先要看的是终止条件。在这种情况下,有三个,但最后两个是最有趣的:他们说如果x(len a)之间的差异太小,我们就会停止迭代。

这给了我们一个想法:如果(len a)x之间的潜在能量差异怎么办?为了确定这是否有意义,我们需要检查递归情况并确保它们中的每一个消耗掉一些能量,即减少差异。事情看起来很不错:

  • 如果x小于(len a),我们会将x增加1并将(len a)减少1.因此,如果它们之间的差异为 n ,然后在下一次迭代中它将是 n-2 ,除非 x = (len a) - 1
  • 其他x大于(len a),我们将x减少1并将(len a)增加1.再次,如果它们之间的差异为 n < / em>,然后在下一次迭代中它将是 n-2 ,除非 x = (len a) + 1

从那里可以很容易地看出我们应该选择 x = (len a) + 1 作为我们的“低能量状态”,因为它处理了这两个的讨厌细节除非条款。