替换sicstus prolog中的列表元素

时间:2013-03-31 20:21:32

标签: list replace prolog prolog-dif

我正在编写一个带有参数(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).

现在,这有效,但似乎有点不雅。可以有更优雅的解决方案吗?

感谢。

2 个答案:

答案 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

最后一个查询对应于以下问题:AB必须具有什么样才能使两个元素列表保持不变?有四个答案:

  1. ABXY都是一样的。

  2. ABX相同,Y不同。

  3. ABY相同,X不同。

  4. XYA不同。

  5. 在较新版本的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调用展开为递归谓词。