我是Prolog和计算机编程的新手。我一直在学习Prolog的练习!我一直相处得很好,但偶尔,当我遇到困难时,我会尝试使用跟踪功能来跟踪线路的程序行,看看它是如何工作或出了什么问题,但我不能做头或尾通过跟踪列出的内容。我举个例子......
其中一个练习是填充带有谓词填字游戏/ 6的填字游戏网格。这些都是答案中的所有事实和规则:
word(abalone,a,b,a,l,o,n,e).
word(abandon,a,b,a,n,d,o,n).
word(enhance,e,n,h,a,n,c,e).
word(anagram,a,n,a,g,r,a,m).
word(connect,c,o,n,n,e,c,t).
word(elegant,e,l,e,g,a,n,t).
crossword(V1,V2,V3,H1,H2,H3):-
word(H1,_,H12V12,_,H14V22,_,H16V32,_),
word(H2,_,H22V14,_,H24V24,_,H26V34,_),
word(H3,_,H32V16,_,H34V26,_,H36V36,_),
word(V1,_,H12V12,_,H22V14,_,H32V16,_),
word(V2,_,H14V22,_,H24V24,_,H34V26,_),
word(V3,_,H16V32,_,H26V34,_,H36V36,_).
这很好用。但我想知道它是如何工作的,我想看看计算机如何逐步完成规则。所以我在查询填字游戏(V1,V2,V3,H1,H2,H3)上使用了trace。以下是产生的前十行左右。
[trace] ?- crossword(V1,V2,V3,H1,H2,H3).
Call: (8) crossword(_5238, _5240, _5242, _5244, _5246, _5248) ? creep
Call: (9) word(_5244, _5658, _5660, _5662, _5664, _5666, _5668, _5670) ? creep
Exit: (9) word(abalone, a, b, a, l, o, n, e) ? creep
Call: (9) word(_5246, _5658, _5660, _5662, _5664, _5666, _5668, _5670) ? creep
Exit: (9) word(abalone, a, b, a, l, o, n, e) ? creep
Call: (9) word(_5248, _5658, _5660, _5662, _5664, _5666, _5668, _5670) ? creep
Exit: (9) word(abalone, a, b, a, l, o, n, e) ? creep
Call: (9) word(_5238, _5658, b, _5662, b, _5666, b, _5670) ? creep
Fail: (9) word(_5238, _5658, b, _5662, b, _5666, b, _5670) ? creep
Redo: (9) word(_5248, _5658, _5660, _5662, _5664, _5666, _5668, _5670) ? creep
Exit: (9) word(abandon, a, b, a, n, d, o, n) ? creep
Call: (9) word(_5238, _5658, b, _5662, b, _5666, b, _5670) ? creep
Fail: (9) word(_5238, _5658, b, _5662, b, _5666, b, _5670) ? creep
我知道第一行只是对查询的重述,但变量变为任意数字。然后它转到规则的第一个目标,再次,变量被简单地实例化为任意数字。该目标将程序发送到数据库中的第一个事实,即word(鲍鱼,a,b,a,l,o,n,e)。
现在我开始感到困惑。为什么在那之后的下一行,第一个目标,但第一个变量从_5244变为_5246?然后我得到一个退出:单词(鲍鱼,a,b,a,l,o,n,e) - 顺便说一下,我不确定Call:和退出:意思是两个 - 再次跟着同一行但是第一个变量从_5246变为_5248。这里发生了什么?为什么所有其他变量都是常数,而第一个变量只是在改变?
再远一点,我变得更加困惑。用线调用:(9)字(_5238,_5658,b,_5662,b,_5666,b,_5670)?蠕动,b来自哪里,为什么有三个?我认为第一个是因为它是鲍鱼的第二个字母,因此填充了填字游戏中的那个位置,但为什么接下来的两个b呢?它们不应该是'我'和'n'吗?
我意识到这对于了解Prolog的人来说可能非常简单,但我不知道发生了什么。这是一个问题,因为跟踪功能可能是学习Prolog的最有用的工具。如果我不能使用它并理解它,那么在我学习的过程中,我将无法检查一切是如何工作的。如果有人能够为我清除这一点,并且可能建议我更好地阅读和理解痕迹,我会非常感激。
答案 0 :(得分:0)
如果您使用的是SWI-Prolog,我建议使用gtrace(键入" gtrace。"并调用谓词)
_5238表示变量。
当你调用word / 6时,变量与第一个候选者进行模式匹配,并生成一个选择点。 在这种情况下,假设6(字数/ 8个定义)"或"生成了句子。
如果pattenmatch失败,prolog会尝试下一个候选人。 如果pattenmatch成功,则prolog转到下一行(并生成下一个选择点) 如果所有选择都失败了,prolog会回到之前的选择点并尝试下一个候选人(回溯)
通知选择点是在每个单词/ 8单独调用时生成的。
在所有选择点,prolog记得现在正在测试哪个候选人。并注意当回溯发生时,选择点上的所有变量都变为空闲(不允许更改prolog变量。值或免费)