1

我正在编写一个 Prolog 谓词,它接受参数(A1,A2,L1,L2),如果 L1 中所有出现的 A1 都已更改为 L2 中的 A2,则成功。

IE:

| ?- 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).

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

谢谢。

4

2 回答 2

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] ?;
不
| ?- maplist_replacement([X,Y],[X,Y],A,B)。
B = A,
X = A,
Y = A ? ;
B = A,
X = A,
序言:dif__int(A,Y) ?;
B = A,
Y = A,
序言:dif__int(A,X) ?;
序言:dif__int(A,X),
序言:dif__int(A,Y) ?;
不

最后一个查询对应的问题是:什么必须AB看起来像这样才能使两个元素列表保持不变?有四个答案:

  1. A, B, X, 和Y都是一样的。

  2. A, B, 和X是相同的,并且Y是不同的。

  3. A, B, 和Y是相同的,并且X是不同的。

  4. X并且Y都不同于A

在较新版本的 SICStus 中,maplist/3位于库中,但定义并不完全单调。有关将谓词应用于列表元素的maplist/3Prolog映射过程的定义。

于 2013-04-01T13:56:05.670 回答
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调用展开为递归谓词。

于 2013-03-31T20:41:28.947 回答