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))