X = [a-A, b-B, a-A].
我使用 -
函子将一些逻辑变量与术语相关联 - 但重要的是,列表中的第一对和最后一对都具有相同的逻辑变量。假设我有一个这样的列表:
[a, b, a]
有什么办法可以从这个列表变成上面这样的列表吗?也就是说,将每个术语与一个逻辑变量配对,相同的术语具有相同的变量。
keys_keyvals(Ks, KVs) :-
keys_keyvals_(Ks, [], KVs).
keys_keyvals_([], _, []).
keys_keyvals_([K|L], S, [K-V|R]) :-
keys_keyvals_seen(S, K, V, S, S1),
keys_keyvals_(L, S1, R).
% End of list - add Key-Value pair to Seen list
keys_keyvals_seen([], K, V, S, [K-V|S]).
% Found match
keys_keyvals_seen([H-X|_], K, V, S, S) :-
( H == K
% Definite match, no need to keep looking
-> !
; H = K
),
% Unifying after cut
X = V.
% Keep looking
keys_keyvals_seen([H-_|T], K, V, S, S1) :-
dif(H, K),
keys_keyvals_seen(T, K, V, S, S1).
swi-prolog 的结果:
?- keys_keyvals([a,b,a,b,c,b,c,d], KVs).
KVs = [a-_A, b-_B, a-_A, b-_B, c-_C, b-_B, c-_C, d-_].
这也处理 var 的键,例如:
?- keys_keyvals([a,b,b,c,X,X], KVs).
X = c,
KVs = [a-_, b-_A, b-_A, c-_B, c-_B, c-_B] ;
X = b,
KVs = [a-_, b-_A, b-_A, c-_, b-_A, b-_A] ;
X = a,
KVs = [a-_A, b-_B, b-_B, c-_, a-_A, a-_A] ;
KVs = [a-_, b-_A, b-_A, c-_, X-_B, X-_B],
dif(X, c),
dif(X, a),
dif(X, b).