我正在编写一个带有参数(A1,A2,L1,L2)的Prolog谓词,并且如果L1中A1的所有出现都已在L2中更改为A2,则成功。
即:
| ?- replace(a, b, [a], X).
X = [b]
这是我写的:
replace(Orig,_,[Other],[Other]) :- Other \== Orig.
replace(Orig,Repl,[Orig],[Repl]).
replace(Orig,Repl,[Other|T1],[Other|T2]) :- Other \== Orig, replace(Orig,Repl,T1,T2).
replace(Orig,Repl,[Orig|T1],[Repl|T2]) :- replace(Orig,Repl,T1,T2).
现在,这有效,但似乎有点不雅。可以有更优雅的解决方案吗?
感谢。
答案 0 :(得分:2)
SICStus Prolog功能dif/2
,因此您可以像这样以纯粹的方式定义关系:
replacement(A, B, X, Y) :-
( A = X, B = Y
; dif(A,X), X = Y
).
maplist_replacement([], [], _, _).
maplist_replacement([X|Xs], [Y|Ys], A, B) :-
replacement(A, B, X, Y),
maplist_replacement(Xs, Ys, A, B).
| ?- maplist_replacement([1,2,3],Ys, 1,x). Ys = [x,2,3] ? ; no | ?- maplist_replacement([X,Y],[X,Y],A,B). B = A, X = A, Y = A ? ; B = A, X = A, prolog:dif__int(A,Y) ? ; B = A, Y = A, prolog:dif__int(A,X) ? ; prolog:dif__int(A,X), prolog:dif__int(A,Y) ? ; no
最后一个查询对应于以下问题:A
和B
必须具有什么样才能使两个元素列表保持不变?有四个答案:
A
,B
,X
和Y
都是一样的。
A
,B
和X
相同,Y
不同。
A
,B
和Y
相同,X
不同。
X
和Y
与A
不同。
在较新版本的SICStus中,maplist/3
位于库中,但定义并非完全单调。
有关maplist/3
的定义,请参阅Prolog map procedure that applies predicate to list elements。
答案 1 :(得分:1)
怎么样:
replace(A, B, X, Y) :- ( X == A -> Y = B ; Y = X ).
示例:
?- maplist(replace(1,x), [1,2,3], Ls).
Ls = [x, 2, 3].
如果您愿意,可以很容易地将maplist/3
调用展开为递归谓词。