在 Prolog -
中添加列表附加实现append([],X,X).
append([H|T1],X,[H|T2]) :-
append(T1,X,T2).
给出了 -
append([a,b,c],[d,e,f],X).
输出 -
X = [a,b,c,d,e,f].
我想知道它是如何工作的,我试图跟踪函数调用但我不明白T2
如何是列表的尾部,它可以作为X
的尾部,它在append([a,b,c],[d,e,f],X)
来电尚未确定。
你可以为我清理这个递归吗?
答案 0 :(得分:2)
归结为统一在Prolog中如何运作。基本上是:
所以你打电话:append([a, b, c], [d, e, f], Y)
这是你的第一个目标。请注意,为了便于查看,我将变量名称从X更改为Y.
这必须与事实或规则统一:让我们看看它是否会与追加([],X,X)统一?
(1) append([a, b, c], [d, e, f], Y)
(2) append([], X, X)
(1)和(2)都有相同的仿函数(追加),所以这很好,并且它们都有3个参数,所以这也很好。但统一每个相应的论点必须统一起来。因此,(1)中的第一个列表[a,b,c]将尝试与(2)中的空列表统一,但它们不能,因为(1)中的列表不是空列表。所以统一失败了。
然后我们可以尝试用append([H | T1],X,[H | T2])来统一。
(1) append([a, b, c], [d, e, f], Y)
(2) append([H|T1],X,[H|T2])
这次(1)中的列表[a,b,c]将尝试与(2)中的列表[H | T1]统一。为了使这成为可能,变量H可以与原子a(H - > a)结合,并且列表T1可以与(1)中的列表的尾部绑定,T1 - > [b,c]。所以第一个论点的作用就是我们所拥有的:
(1) append([a, b, c], [d, e, f], Y)
(2)' append([a, b, c],X,[a|T2])
第二个参数也将统一,因为X是一个变量并将绑定到任何东西。 X - > [d,e,f]所以我们有:
(1) append([a, b, c], [d, e, f], Y)
(2)'' append([a, b, c],[d, e, f],[a|T2])
最后,最后一个论点统一起因为Y - > [A | T 2]。现在,它与规则的主管相结合,我们需要制定规则的主体:我们现在最终以append([b, c], [d, e, f], T2)
为目标。
从第一个事实开始,我们再次查找此目标将绑定的子句。通过上面的相同解释,它将不与第一个条款统一,但将与具有绑定的第二个统一:H - > b,T1 - > [c],X - > [d,e,f]和T2 - >并[b | T2' ]。
我们留下目标:追加([c],[d,e,f],T2')。同样,它不与第一个子句统一,并与第二个与绑定结合:H - > c,T1 - > [],X - > [d,e,f],T2' - >并[c | T2 '']。
现在的目标是:追加([],[d,e,f],T2'')。
让我们看看当我们尝试将第1条与第1条统一起来时会发生什么:
(1) append([], [d, e, f], T2'')
(2) append([],X,X)
两个空列表统一,X - > [d,e,f]并且由于T2'' - > X,然后是T2'' - > [d,e,f]。现在,棘手的部分是跟踪到目前为止的递归调用,现在沿着递归返回以查看最终结果。回想起T2' - > [c | T2'']所以T2'实际上是[c,d,e,f]。并回想起T2 - > [B | T2']所以T2实际上是[b,c,d,e,f]。
最后Y - > [a | T2]因此Y是[a,b,c,d,e,f]。由于Y是外部变量,因此现在显示原始目标已满足。