【问题标题】:prolog - why this strange traceprolog - 为什么这个奇怪的痕迹
【发布时间】:2009-11-19 12:39:51
【问题描述】:

这是序言代码(我有点遵循)。

len([],0).
len([_|T],N) :- len(T,X), N is X+1.

这是它的踪迹(我正在运行 linux,swi)

    [trace]  ?- len([d,f,w,c],X).
   Call: (7) len([d, f, w, c], _G314) ? 
   Call: (8) len([f, w, c], _L182) ? 
   Call: (9) len([w, c], _L201) ? 
   Call: (10) len([c], _L220) ? 
   Call: (11) len([], _L239) ? 
   Exit: (11) len([], 0) ? 
^  Call: (11) _L220 is 0+1 ? 
^  Exit: (11) 1 is 0+1 ? 
   Exit: (10) len([c], 1) ? 
^  Call: (10) _L201 is 1+1 ? 
^  Exit: (10) 2 is 1+1 ? 
   Exit: (9) len([w, c], 2) ? 
^  Call: (9) _L182 is 2+1 ? 
^  Exit: (9) 3 is 2+1 ? 
   Exit: (8) len([f, w, c], 3) ? 
^  Call: (8) _G314 is 3+1 ? 
^  Exit: (8) 4 is 3+1 ? 
   Exit: (7) len([d, f, w, c], 4) ? 
X = 4.

我知道 prolog 会沿着这些“树”运行,但我无法弄清楚为什么仅在变量退出时才对变量进行增量 - 对此机制有何解释?

非常感谢!

【问题讨论】:

  • 你可以试试gtrace。您可能必须安装xpce,并且在某些机器上,它会中断咨询,所以当您在trace 中时不要加载您的文件。

标签: logic prolog


【解决方案1】:

原因是N is X+1 是谓词的最后一部分。

可以这样想:要计算N is X+1,我们需要知道X的值,它是通过调用len(T,X)来计算的。但是计算X 的过程需要再次调用len,直到最终得到一个空列表。

此时列表长度是已知的,即 0。因此该值被“返回”。只有这样 0 + 1 才能计算并“返回”。然后是 1 + 1。等等。

换一种方式考虑,观察任何两个谓词ab,如果ab 都为真,a, b 产生真。在 Prolog 中,只有在已知 a 为真时才会评估 b(否则评估 b 没有意义,因为已知结果为假)。

因此,所有添加都在 递归调用 len 之后完成。

【讨论】:

  • 不客气!如果它有帮助,那么您也可以为答案投票(只是说,因为我在您的个人资料中看到您没有在此网站上投票)。
猜你喜欢
  • 2010-11-04
  • 2018-05-13
  • 2021-07-26
  • 2012-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
相关资源
最近更新 更多