Debugging Prolog中递归的调试
以下是我的知识库:Debugging Prolog中递归的调试,debugging,recursion,prolog,trace,Debugging,Recursion,Prolog,Trace,以下是我的知识库: numeral(0). numeral(succ(X)) :- numeral(X). 我的问题是: numeral(X). 以下是SWI Prolog在跟踪模式下返回的内容: [trace] ?- numeral(X). Call: (8) numeral(_3806) ? creep Exit: (8) numeral(0) ? creep X = 0 ; Redo: (8) numeral(_3806) ? creep Call: (
numeral(0).
numeral(succ(X)) :- numeral(X).
我的问题是:
numeral(X).
以下是SWI Prolog在跟踪模式下返回的内容:
[trace] ?- numeral(X).
Call: (8) numeral(_3806) ? creep
Exit: (8) numeral(0) ? creep
X = 0 ;
Redo: (8) numeral(_3806) ? creep
Call: (9) numeral(_4006) ? creep
Exit: (9) numeral(0) ? creep
Exit: (8) numeral(succ(0)) ? creep
X = succ(0) ;
Redo: (9) numeral(_4006) ? creep
Call: (10) numeral(_4010) ? creep
Exit: (10) numeral(0) ? creep
Exit: (9) numeral(succ(0)) ? creep
Exit: (8) numeral(succ(succ(0))) ? creep
X = succ(succ(0))
我理解它是如何找到答案的,但我不完全理解它是如何得到答案的:X=succ(succ(0))
。我知道这是正确的答案,但我不确定序言是如何寻找它的
以下是我的想法:
当它打印时,调用:(9)数字(_4006)?蠕变
它尝试以下规则:numeric(suc(X)):-numeric(X)。
特别是它可能会替代\u 4006=suc(X)
然后它检查它是否仅在数字(X)
保持时才保持,Prolog会根据数字(0)
进行检查,因此结果是\u 4006=succ(0)
现在,如果我们要求另一个解决方案,它又会回到数字(\u 4006)
,但是当is调用数字(\u 4010)
时,它会猜到什么呢。这里的分支过程是什么
有没有办法得到更多的细节
注意:这是从以下序言中获取的。Prolog可以通过两种方式满足
数字(X)
调用:
数字(0)
,在这种情况下,它将X
与0
统一;及numeric(suc(Y)):-numeric(Y)
在这种情况下,它将X
与suc(Y)
相结合,并进行递归调用Y
,因为这也会造成混淆:子句中的变量是局部范围的,因为子句中的X
与调用中的X
不是同一个变量
现在,如果Prolog回溯并试图用子句满足谓词,那么这意味着X=succ(Y)
使用Y
变量,但它需要按照正文中的指定使用numeric(Y)
进行额外调用
同样,有两种选择:
数字(0)
,在这种情况下,它将Y
与0
统一;及numeric(suc(Z)):-numeric(Z)
在这种情况下,它将Y
与suc(Z)
相结合,并进行递归调用Y
被设置为0
,因此X=succ(Y)
因此X=succ(0)
。在后一种情况下,我们再次进行递归调用
现在,如果我们再次使用数字(0)的第一行,这意味着Z
与0
统一,因此Z=0
,因此Y=succ(0)
,因此X=succ(succ(0))