所以我试图在prolog中创建一个获取字符和2个列表的方法,无论在列表1中找到该字符的哪个位置,我都会在列表2中注入该字符。该方法返回新的状态清单2.即使我发现它是正确的,它似乎也不起作用。这是我的代码。
transfer([],[],_,[])
transfer([H¦T],[_¦T1],C,R):-
transfer(T,T1,C,R1),
H==C,
append([H],R1,R).
所以,如果我执行? - 转移([h,e,l,l,o],[0,0,0,0,0],e,X)。我得到结果X = [0,e,0,0,0]。有什么想法吗?
答案 0 :(得分:1)
想一想你的谓词应该描述什么样的关系。如果前两个列表为空,则无论比较元素如何,最后一个参数也是空列表。这是您已有的基本情况。否则你有两个互斥的案例:
第一个列表的头部等于比较元素。在这种情况下,比较元素位于结果列表中。
第一个列表的头部与比较元素不同。在这种情况下,第二个列表的头部位于结果列表中。
您可以使用or-predicate ;
对此案例区分进行建模。转移/ 4可能看起来像这样:
transfer([],[],_,[]).
transfer([H1|T1],[H2|T2],C,[R|Rs]):-
((H1=C,R=C);(dif(H1,C),R=H2)), % case 1 or case 2
transfer(T1,T2,C,Rs). % the relation holds for the tails as well
使用此定义,您的示例查询会产生所需的结果:
?- transfer([h,e,l,l,o],[0,0,0,0,0],e,X).
X = [0,e,0,0,0] ? ;
no
或者你也可以在一个单独的谓词中描述上面的案例区别,然后使用maplist / 4将关系应用于三个列表:
:- use_module(library(apply)).
e_x_y_z(E,X,Y,Z) :-
(X=E,Z=E);(dif(X,E),Z=Y).
transfer(L1,L2,C,R) :-
maplist(e_x_y_z(C),L1,L2,R).
我发现这个版本更容易阅读,因为实际关系的定义与递归分开。注意e_x_y_z / 4中的比较元素是第一个参数,因此谓词可以传递给maplist / 4,它们分别缺少三个参数的三个参数。