谓词change_pos(E1, E2,Lin,Lout).
Lin
有任意数量的元素,我需要将E1
的所有出现更改为E2
,反之亦然。并返回Lout
。
我在考虑做这样的事情:
change(X, Y, [], []).
change(X, Y, [X|L], [Y,L1]):- change(X,Y,L,L1).
change(X, Y, [Z|L], [Z,L1]:- X \== Z, change(X,Y,L,L1).
但这种方式不会刷两个列表
答案 0 :(得分:4)
我想,因为这是家庭作业,所以学习列表处理和递归是一项练习。但在Prolog中,在列表中依次处理每个术语的常用工具是maplist
:
% Rule for changing one element
change_element(X, Y, X, Y).
change_element(X, Y, Y, X).
change_element(X, Y, Z, Z) :- dif(X, Z), dif(Y, Z).
% Rule for changing a list
change(X, Y, L1, L2) :-
maplist(change_element(X, Y), L1, L2).
哪个收益率:
?- change(a, b, [a,b,c,b,a], L).
L = [b, a, c, a, b] ? ;
no
?-
<小时/> 对于确定解决方案,您可以使用if_/3:
change1(X, Y, A, B) :-
if_(=(Y, A), B = X, A = B).
change2(X, Y, A, B) :-
if_(=(X, A), B = Y, change1(X, Y, A, B)).
change(X, Y, L1, L2) :- maplist(change2(X, Y), L1, L2).
哪个收益率:
?- change(a, b, [a,b,c,b,a], L).
L = [b, a, c, a, b].
?-
答案 1 :(得分:2)
你几乎就在那里。你的基本情况(空列表)和你的第二个规则(X
的交换Y
)基本上没问题(除了评论中指出的细节)。但是,您缺少反之亦然的规则(Y
的交换X
)。在您的上一条规则中,您可能希望确保Z
不仅与X
不同,还与Y
不同,否则Z
将受到第二或第三规则的约束。
change(X, Y, [], []).
change(X, Y, [X|L], [Y|L1]) :-
change(X,Y,L,L1).
change(X, Y, [Y|L], [X|L1]) :- % <- vice versa case
change(X,Y,L,L1).
change(X, Y, [Z|L], [Z|L1]) :-
dif(X,Z), % <- neither X=Z
dif(Y,Z), % <- nor vice versa
change(X,Y,L,L1).
以下是一些示例查询。 使用 [1,2,3,4]
交换 1
之后 2
的内容是什么样,反之亦然?
?- change(1,2,[1,2,3,4],L).
L = [2,1,3,4] ? ;
no
在使用 [2,1,3,4]
交换 1
之前, 2
的内容是什么样的反之亦然?
?- change(1,2,L,[2,1,3,4]).
L = [1,2,3,4] ? ;
no
如果结果列表是 [1,2,3,4]
,则 [2,1,3,4]
中已交换了哪些元素?
?- change(X,Y,[1,2,3,4],[2,1,3,4]).
X = 1,
Y = 2 ? ;
X = 2,
Y = 1 ? ;
no