Prolog用变量替换列表中常量的每个实例

时间:2014-04-02 13:15:52

标签: prolog

给定常量列表,如何用变量替换常量的每个实例?像这样:

[1,1,2,1,2,3]

=

[A,A,B,A,B,C]

这是我的版本:

f([],Seen0,Out,Out) :-
  write(Seen0).

f([H|T],Seen0,Out0,Out):-
  member(H/Var0,Seen0),
  append(Out0,[Var0],Out1),
  f(T,Seen0,Out1,Out).

f([H|T],Seen0,Out0,Out):-
  not(member(H/Var,Seen0)),
  append(Seen0,[H/Var],Seen1),
  append(Out0,[Var],Out1),
  f(T,Seen1,Out1,Out).

运行如此:

?- f([1,1,2,1,2,3],[],[],O).
[1/_G31,2/_G58,3/_G118]
O = [_G31, _G31, _G58, _G31, _G58, _G118] .

?- f([a,a,b,a,b,c],[],[],O).
[a/_G311,b/_G338,c/_G398]
O = [_G311, _G311, _G338, _G311, _G338, _G398]

其他(更好?)解决方案?

2 个答案:

答案 0 :(得分:3)

更简单一点:

ints_vars([], [], _).
ints_vars([I|Is], [V|Vs], Map) :-
    once(member(I/V, Map)),
    ints_vars(Is, Vs, Map).

,并提供:

?- ints_vars([1, 1, 2, 1, 2, 3], Vs, Map).
Vs = [_281, _281, _295, _281, _295, _315]
Map = [1 / _281, 2 / _295, 3 / _315|_321]
Yes (0.00s cpu)

答案 1 :(得分:2)

to_vars(L, R) :-
    pairs_keys_values(Ps, L, _),
    maplist(peek(Ps), L, R).
peek(Ps, K, V) :- memberchk(K-V, Ps).

产量

?- to_vars([a,a,b,c,a],L).
L = [_G2400, _G2400, _G2418, _G2427, _G2400].

编辑这个从@jschimpf(+1)获取使用自由变量作为'字典'的想法。对我来说似乎很干净......

to_vars(L, V) :- phrase(to_vars(_, V), L).

to_vars(_, []) --> [].
to_vars(Seen, [V|Vs]) --> [E], {memberchk(E-V, Seen)}, to_vars(Seen, Vs).