Prolog元谓词:将谓词应用于列表,传递常量

时间:2011-09-22 15:50:56

标签: list prolog

假设您需要一个谓词,将Number1替换为列表中的Number2 当然,为此编写一个递归函数是很简单的,例如:

replace(_,_,[],[]).
replace(N1,N2,[N1|T], [N2|NT]):-
    replace(N1,N2,T,NT).
replace(N1,N2,[H|T],[H|NT]):-
    replace(N1,N2,T,NT).

我的问题是,是否有办法用maplist / x(或类似的元谓词)来做到这一点 有人可能会使用全局变量来执行此操作,例如:

replace(N1,N2,L1,L2):-
    nb_setval(numbers,[N1,N2]),
    maplist(replace_in,L1,L2).

replace_in(N1,N2):-
    nb_getval(numbers,[N1,N2]).
    replace_in(X,X).

另一个想法是创建一个相同数字List_of_N1和List_of_N2的列表,并将它们传递给maplist / 4。
他们中没有一个对我有吸引力,有什么想法吗?

2 个答案:

答案 0 :(得分:4)

顺便说一句:根据您给定的定义,例如考虑以下显而易见的第二种解决方案:

?- replace(1, 4, [1,2,3], Ls).
Ls = [4, 2, 3] ;
Ls = [1, 2, 3] ;
false.

关于实际问题,请考虑:

replace(A, B, X, Y) :- ( X == A -> Y = B ; Y = X ).

示例查询:

?- maplist(replace(1,4), [1,2,3], Ls).
Ls = [4, 2, 3].


对于,我建议使用真正的关系版本,可以在所有方向使用:

replacement(A, B, A, B).
replacement(A, _, X, X) :- dif(A, X).

示例:

?- maplist(replacement(a,b), [X], Rs).
Rs = [b],
X = a ;
Rs = [X],
dif(X, a).

答案 1 :(得分:1)

这个怎么样:

replace(N1,N2,L1,L2):-
    maplist(replace_in,[N1-N2-T|T], L1,L2).

replace_in(N1-N2-T, X, Y):-
  (X=N1 -> Y=N2 ; Y=X),
  (T=[N1-N2-L|L] ; T=[]).