只需要一个简单的解释..试图在这里将所有东西拼凑在一起。
lastitem([X|Xs],Out) :- lastitem(Xs,Out).
这里是跟踪:lastitem([a,b,c],X)。
[trace] 8 ?- lastitem([a,b,c],X).
Call: (6) lastitem([a, b, c], _G536) ? creep
Call: (7) lastitem([b, c], _G536) ? creep
Call: (8) lastitem([c], _G536) ? creep
Exit: (8) lastitem([c], c) ? creep
Exit: (7) lastitem([b, c], c) ? creep
步骤1说如果lastitem(某事,某些东西)存在,则listem([X | Xs],Out] ..所以A被删除。 步骤2-3做同样的事情但是没有B和C. 现在问题是第4步中的空列表会发生什么? 为什么空列表不能满足lastitem(Xs,Out)?还是我解决不正确?
对回溯的口头解释也会有所帮助..因为在附加中我真的变得扭曲了。 Append没有目标可以在两个步骤之间解决..但是反向没有..我的回答也不是上面的..如果你追踪它,你可以看到X变量在反向或本例中总是相同的。附加它改变。
append([],L,L).
append([H|T],L2,[H|L3]) :- append(T,L2,L3).
append([a, b, c], [1, 2, 3], _G518) % <-- variable L3 continues to change
append([b, c], [1, 2, 3], _G587) % <-- same
append([c], [1, 2, 3], _G590) % < -- same
append([], [1, 2, 3], _G593) % <-- same
append([], [1, 2, 3], [1, 2, 3])
append([c], [1, 2, 3], [c, 1, 2, 3])
append([b, c], [1, 2, 3], [b, c, 1, 2, 3])
append([a, b, c], [1, 2, 3], [a, b, c, 1, 2, 3])
X = [a, b, c, 1, 2, 3]
答案 0 :(得分:0)
就像你一样,我对lastitem
中没有基本案例感到困惑。你确定它实际上没有被定义为
lastitem([X|[]], X).
lastitem([X|Xs],Out):- lastitem(Xs,Out).
或类似的东西?
对于所有的回溯,在查看Prolog代码时尽量不要过于强制。 例如,append可以“翻译”为更常用的功能定义:
function append(xs, ys) =
if xs is [] then
return ys
else
let [H|L] = xs
return [H | append(L, ys)]
了解Prolog版本还有很长的路要走:)
答案 1 :(得分:0)
在lastitem([X|Xs],Out) :- lastitem(Xs,Out).
中,第二个参数是Out
,所以它必须保持不变。
在append([H|T],L2,[H|L3]) :- append(T,L2,L3).
中,左侧的第三个参数是[H|L3]
,但右侧是L3
,所以当您拨打append
时,您有一个“变量“for [H|L3]
,但L3
的变量必须不同。像_G536
这样的变量名是全局的,所以当它们代表不同的东西时,它们必须是不同的。
(抱歉我的术语不精确,我有一段时间没与Prolog合作过。)