我正在努力学习Prolog。我有一个问题,并在Prolog中的解决方案。虽然我无法完全理解代码。
代码的调用就像这样 -
conc(Before,[c|After],[a,b,c,d]) .
此代码将返回
Before = [a,b]
After = [d]
我有解决方案 -
conc([],L,L).
conc([X|L1],L2,[X|L3]) :- conc(L1,L2,L3) .
我无法完全理解程序的流程。让我从干跑开始吧。为了理解代码流,我添加了一些write命令。代码现在看起来像这样 -
conc([],L,L):- write("Line1: "), write(L).
conc([X|L1],L2,[X|L3]) :-
write("Line-2: "), write(L1), write(" "),
write(L2), write(" "), write(L3), conc(L1,L2,L3) .
初次通话是 -
conc(Before,[c|After],[a,b,c,d]) .
此时,呼叫转到第2行(因为,Before是未知的术语,非空),这是:
conc([X|L1],L2,[X|L3]) :-
write("Line-2: "), write(L1), write(" "),
write(L2), write(" "), write(L3), conc(L1,L2,L3) .
此时,X = [a],l1 =未知,L2 = [c | After],L3 = [b,c,d]。这打印 -
第2行:_G481 [c | _G368] [b,c,d]
这将再次使用以下值调用递归(代码行2):
cons(L1, [c|After], [b,c,d]). (L1 is unknown still now)
并且,打印 -
第2行:_G494 [c | _G368] [c,d]
现在下一个电话会是:
cons(L1, [c|After], [c,d]).
但是,我可以在代码中打印自定义注释时看到,此时代码控制转到#line 1,我无法理解。因为,现在,
L1= unknown(just as all the previous calls).
L(parameter 2)= [c|After]
L(parameter 3) = [c,d].
但是,控件转到#line 1,然后打印:
Line1: [c,d]
我认为prolog从左到右执行代码。所以,根据我的理解,执行L的值应该是[c,d]。
我的问题是:
1。在第二次呼叫之后,L1未定义为所有呼叫,如前所述。并且,第二个和第三个参数都是L.所以,为什么,在第二次调用之后控件转到#line1。
2。我的理解在这件事上是否正确? "我认为prolog从左到右执行代码。所以,根据我的理解,执行L的值应该是[c,d]。"
提前致谢... 请帮帮我!!
答案 0 :(得分:2)
如果你在程序上看待它,你不能指望理解这里发生的一切,因为同时有太多的事情发生。如果你刚开始学习这门语言,情况尤其如此。
学习Prolog的一个好方法是认为以声明方式,然后问: 是什么使保持的条件?
另外,当你真正想写变量时,你正在写原子。请更正您的帖子,例如:
cons(L1, [c|After], [c,d])
请注意,After
是变量,after
是原子。
现在,将其他所有内容都放在一边,只需单独考虑这个目标。尝试使用:
?- cons(L1, [c|After], [c,d]).
完全按照我们的期望,我们得到了解决方案:
L1 = [],
After = [d]
因此,足以理解这个目标可以孤立地得出。另请注意您当前正在混合的X = [a]
和X = a
之间的区别。