簡體   English   中英

Prolog 創建列表

[英]Prolog creating lists

我正在嘗試在 Prolog 中編寫一個程序,該程序將接收三個列表(所有列表的長度都相同)並返回一個列表列表。

我要返回的列表列表是一個三元組,其中包含來自傳入的三個列表的元素。三元組的第一個元素來自傳入的第一個列表,三元組的第二個元素來自第二個列表,三元組的第三個元素來自傳入的第三個列表。

我想要發生的是函數返回的三元組列表,以返回您可以從傳入的三個列表中創建的每個可能的組合

到目前為止,我有一些代碼可以獲取三個列表的第一個元素並從中生成一個三元組,然后獲取所有列表的第二個元素並從中生成一個三元組,依此類推。 這是下面。

   listCombos( [], [], [], []).
   listCombos( [A|AREST], [B|BREST], [C|CREST], [[A,B,C]|SOLUTION]) :-
       listCombos( AREST, BREST, CREST, SOLUTION).

我獲取每個組合的策略是獲取第一個列表的第一個元素和第二個列表中的第一個元素,然后遍歷第三個列表中的每個元素。 完成后,我將移動第一個列表中的第一個元素和第二個列表中的第二個元素,並將它們與第三個列表中的每個元素進行匹配。 然后在我瀏覽完第二個列表后移動到第一個列表。 如果需要對此進行更多說明,請告訴我。

我是 Prolog 的新手,所以我不明白如何將我打算做的事情變成代碼。 我已經嘗試了一些東西,但沒有成功,並且得到了一些我不明白的錯誤代碼,所以很難判斷我是否朝着正確的方向前進(如果需要,我可以發布一些我的嘗試)。 如果有人知道我應該朝哪個方向前進,或者對我需要做的事情有一些解釋,那將不勝感激。

非常感謝。

了解一點 Prolog 最明顯的解決方案是這樣的:

listCombos(Xs, Ys, Zs, Result) :-
    findall([X,Y,Z], 
            (member(X, Xs), member(Y, Ys), member(Z, Zs)),
            Result).

建議概括您正在尋找的構造,接受要組合的列表列表,遵循此答案中的架構:

combine(Ls,Rs) :- maplist(member,Rs,Ls).

listCombos(A,B,C, SOLUTION) :- findall(R,combine([A,B,C],R),SOLUTION).

我們首先可以解決一個相關的問題:給定一個“頭”列表Hs和一個“尾”列表Ts ,構造一個列表中Hs所有頭HTs中所有尾T所有列表。 我們可以用一個謂詞來做到這一點:

merge_all([], _, []).
merge_all([H|Hs], Ts, All) :-
    merge_single(Ts, H, All, D),
    merge_all(Hs, Ts, D).

merge_single([], _, D, D).
merge_single([T|Ts], H, [[H|T]|Rest], D) :-
    merge_single(Ts, H, Rest, D).

例如:

?- merge_all([a, b], [[1, 4], [2, 5]], R).
R = [[a, 1, 4], [a, 2, 5], [b, 1, 4], [b, 2, 5]].

現在我們可以使用它來制作所有帶有Cs和“空集”的叉積,例如,如果Cs = [a, b, c] ,則:

?- merge_all([a, b, c], [[]], RC).
RC = [[a], [b], [c]].

鑒於我們有這個結果,我們可以用這個結果做Bs的叉積。 例如,如果Bs = [1, 4] ,那么我們得到:

?- merge_all([a, b, c], [[]], RC), merge_all([1, 4], RC, RB).
RC = [[a], [b], [c]],
RB = [[1, a], [1, b], [1, c], [4, a], [4, b], [4, c]].

上面生成三組的叉積應該很簡單,我把它留作練習。

Daniel Lyons 的方法很好,因為它允許我們輕松控制列表列表的叉積中的組合順序,同時保持組合中元素的順序相同,當然:

cross( [], [[]] ).
cross( [XS | T], R ):- 
    cross(   T,                     TC),
    findall( [X | Y], (                      %       or:
                         member( Y, TC),     %  member( X, XS)  
                         member( X, XS)      %  member( Y, TC),
                      ), 
                 R).

它表現出良好的模塊化和關注點分離:呈現順序與生成順序和選擇順序無關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM