在prolog中创建只使用一个输入实例的连接谓词

时间:2014-02-11 11:04:41

标签: prolog

是否可以在Prolog中创建一个连接两个列表的谓词,并且可以在任何情况下工作:

concat(X,Y,[1,2,3,4]) 
concat(X,[2,3,4],[1,2,3,4])
concat([1,2,3],X,[1,2,3,4])

到目前为止我能做的最好的是:

concat([],[],[]).
concat([],X,X).
concat(X,[],X).
concat([X|Y],[A|B],[X|Z]) :- add(Y,[A],K) , add(K,B,Z) .

具有以下结果:

正常工作:

concat([1,2,3],X,[1,2,3,4]) 

给出正确答案,然后进入无限循环:

concat(X,[2,3,4],[1,2,3,4]) 

给出一些结果(编辑:所有结果,我相信),然后进入无限循环:

concat(X,Y,[1,2,3,4])

结果给出:

?- concat(X,Y,[1,2,3,4]).
X = [],
Y = [1,2,3,4] ? ;
X = [1,2,3,4],
Y = [] ? ;
X = [1],
Y = [2,3,4] ? ;
X = [1,2],
Y = [3,4] ? ;
X = [1,2,3],
Y = [4] ? ;

我正在努力使这个谓词更多地了解prolog。

1 个答案:

答案 0 :(得分:3)

如前所述,您只是重新定义append/3。但是,作为一种学习经验,你应该注意到你可以用更简单,更Prolog-y的方式做到这一点:

concat([],X,X).
concat([X|Y],A,[X|Z]) :- 
     concat(Y,A,Z).

如你所见,空的第二个列表的定义是不必要的,因为在第一个定义中,Prolog将第二个列表(或者更确切地说,统一)复制到第三个列表(反之亦然),即使它是一个空的。您只需要在第一个列表中处理一个空列表来停止递归。此外,使用模式匹配,您不需要额外的谓词来将头项目从列表移动到另一个列表。