首先,我完全是Prolog的初学者。
我试图将列表的每个元素与另一个列表的每个元素进行比较。通过比较,我的意思是将这两个元素发送到我写的谓词(冲突)。到目前为止,我得到了这个:
%iterate over the first list
cmp_list([],_,_).
cmp_list([X|Y],[A|B],Result):-
cmp_list_inner(X,[A|B],Result),
cmp_list(Y,[A|B],Result).
%iterate over the second list
cmp_list_inner(_,[],_).
cmp_list_inner(X,[A|B],S):-
not(conflicts(X,A)), %compare
cmp_list_inner(X,B,[X-A|S]).%if okay, add their combination, i.e X-A to the main list which will be returned
谓词cmp_list代表外部列表的递归,而内部代表内部列表。 cmp_list(firstlist,secondlist,将返回组合后的新列表。)
这不起作用!即使它将第一个值中的单个元素的值添加到主列表中,它也不会将第二个比较(对于第一个列表中的第二个元素)附加到将返回的主列表。结果应采取以下形式: [X1-Y1],[X1-Y2],[X2-Y1],[X2-Y2] ....其中Xs来自第一个列表,Ys来自第二个列表。
任何帮助将不胜感激。谢谢!
答案 0 :(得分:1)
你只需要一个简单的谓词:
cmp_list([], [], []). % cmp_list succeeds for two empty lists
cmp_list([H1|T1], [H2|T2], [H1-H2|R]) :-
% cmp_list of [H1|T1] and [H2|T2] succeeds if...
\+ conflicts(H1, H2), % conflicts fails for H1 and H2
cmp_list(T1, T2, R). % cmp_list succeeds for T1 and T2, result R
% Otherwise, cmp_list fails (e.g., lists are diff length)
更紧凑的是使用内置谓词maplist
:
cmp_list(L1, L2, R) :- % cmp_list succeeds on L1, L2 if...
maplist(no_conflicts, L1, L2, R). % no_conflicts succeeds for every
% corresponding pair of L1, L2 elements
no_conflicts(X, Y, X-Y) :- \+ conflicts(X-Y).
如果您只想捕获所有不会发生冲突并且忽略其余对的对,那么:
cmp_list([], _, []).
cmp_list([_|_], [], []).
cmp_list([H1|T1], [H2|T2], R) :-
( conflicts(H1, H2)
-> cmp_list(T1, T2, R)
; R = [H1-H2|R1],
cmp_list(T1, T2, R1)
).
这使用" if-then-else" Prolog中的模式是通过将->
与;
分组而形成的。这将创建一个看起来像[x1-y1, x3-y3, ...]
的结果。您可以通过更改以下行来选择要形成结果元素:
R = [H1-H2|R1]
例如,R = [[H1,H2]|R1]
会产生类似[[x1,y1], [x3,y3], ...]
的结果。
%iterate over the first list
cmp_list([], _, []).
cmp_list([X|T], L2, Result):-
cmp_list_inner(X, L2, R1),
cmp_list(T, L2, R2),
append(R1, R2, Result).
%iterate over the second list
cmp_list_inner(_, [], []).
cmp_list_inner(X, [A|B], R) :-
( conflicts(X, A)
-> cmp_list_inner(X, B, R)
; R = [X-A|T],
cmp_list_inner(X, B, T)
).