什么输入会导致此功能无法终止?

时间:2013-12-03 00:11:48

标签: scheme lisp stack-overflow termination

我试图在ACL2s / Lisp中证明这个函数,但是它返回了一个堆栈溢出错误,虽然我看不到代码中的缺陷。

(defunc foo (x y)
 :input-contract (and (natp x) (natp y))
 :output-contract (natp (foo x y))
 (cond ((equal 0 x) (+ y 1))
       ((equal 0 y) (foo (- x 1) 1))
       (t (foo (- x 1) (foo x (+ y 1))))))

1 个答案:

答案 0 :(得分:5)

任何正面xy都不会导致此溢出吗?我们来看看(foo 1 1)

xy都不为零,因此它会转到cond的t分支,然后调用:

(foo 0
     (foo 1 2))

好的,让我们评估内部foo电话:

(foo 1 2)

同样,它进入cond的t分支,并调用:

(foo 0
     (foo 1 3))

让我们评估内部foo

(foo 1 3)

你可以看到它的发展方向。 t分支调用:

(foo 0
     (foo 1 4))

等等。只要xy都非零,就会发生这种情况。你从哪里得到这段代码?你想用它做什么?运行它也是一个好主意,看看溢出了什么。在这种情况下,几乎每次可能的调用都会导致堆栈溢出。