2014-03-24 66 views
0

首先,我完全是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來自第二個列表。

任何幫助,將不勝感激。謝謝!

回答

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

這個u在Prolog通過將->;分組而形成的「if-then-else」模式。這將創建一個看起來像[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) 
    ). 
+0

謝謝!結果應該像[X1-Y3],[X2-Y4],[X5-Y1]等 其中Xs在list1中,Ys在list2中。它應該是非衝突對的列表,而對則是list1的元素和list2的元素的組合。你的解決方案不是按索引檢查索引嗎?我試圖比較X1與Y1,Y2,Y3 .. X2與Y1,Y2,Y3 ...等 – user3450161

+0

我的意思是,它應該不會失敗,如果列表是不同的長度。 – user3450161

+0

@ user3450161你想讓它捕捉所有匹配的內容,並忽略那些不匹配的內容嗎? – lurker

相關問題