簡體   English   中英

在prolog中減去或添加列表列表?

[英]Subtracting or adding lists of lists in prolog?

我對prolog很新,我試圖搞清楚列表清單。 我很好奇如何添加兩個列表列表或減去它們導致一個列表列表。 如果我有兩個列表列表可以說,

SomeList = [[1,2,3,4],[5,6,7,8]]  
SomeList2 = [[1,2,3,4],[5,6,7,8]]

我如何添加或減去SomeListSomeList2來創建列表列表? 結果說了一筆

sumList([[2,4,6,8],[10,12,14,16]]) 

反之亦然? 任何幫助將不勝感激,不是尋找代碼,而是為了洞察力!

最簡單的方法是使用maplist

add(X, Y, Z) :- Z is X + Y.

op_lists(L1, L2, R) :-
    maplist(maplist(add), L1, L2, R).

這使:

| ?- op_lists([[1,2,3,4],[5,6,7,8]], [[1,2,3,4],[5,6,7,8]], R).

R = [[2,4,6,8],[10,12,14,16]]

yes
| ?-

在表達式中:

maplist(maplist(add), L1, L2, R).

maplist(G, L1, L2, R)L1L2每個元素上調用G ,從而得到R每個元素。 由於L1L2每個元素都是一個列表,因此在這種情況下Gmaplist(add) ,它在子列表的每個元素上調用add

顯然,您可以將add(X, Y, Z)修改為您希望在每對元素上執行的任何操作。 您還可以使用CLP(FD)使添加更“關系”:

add(X, Y, Z) :- Z #= X + Y.

然后你也會得到,例如:

| ?- op_lists([[1,2,3,4],[5,6,7,8]], L, [[3,6,9,12],[10,12,14,16]]).

L = [[2,4,6,8],[5,6,7,8]]

yes
| ?-

如果你想在沒有maplist情況下這樣做,你仍然可以使用add/3並使用兩層方法:

op_lists([], [], []).
op_lists([LX|LXs], [LY|LYs], [LR|LRs]) :-
    op_elements(LX, LY, LR),
    op_lists(LXs, LYs, LRs).

op_elements([], [], []).
op_elements([X|Xs], [Y|Ys], [R|Rs]) :-
    add(X, Y, R),
    op_elements(Xs, Ys, Rs).

您可以在此處查看簡單列表處理模式,使用maplist為您處理。

除了@lurker(+1)提供的解決方案之外,我還會添加使用DCG的可能性,因為您正在處理列表。 對於可用的操作,我建議定義一個稍微更一般的謂詞opfd / 4而不是add / 3。 以下是您問題中提到的加法和減法的示例性規則,您可以使用這些作為模板來添加其他兩位算術運算:

opfd(+,X,Y,Z) :-
   Z #= X+Y.
opfd(-,X,Y,Z) :-
   Z #= X-Y.

由於所需的操作是一個參數,您只需要一個DCG規則來覆蓋所有操作(在相應的目標上標記為(1))。 當然,這樣一來,您必須在關系中指定所需的操作作為參數,並將其傳遞給DCG。 這些DCG的結構與@lurker提出的最后一個解決方案非常相似,不同之處在於結果列表不作為參數出現,因為這是DCG描述的內容。 為了便於比較,我將堅持使用名稱op_lists // 3和op_elements // 3,調用謂詞應該被稱為lists_op_results / 4:

lists_op_results(L1,L2,Op,Rs) :-
   phrase(op_lists(Op,L1,L2),Rs).

op_lists(_Op,[],[]) -->
   [].
op_lists(Op,[X|Xs],[Y|Ys]) -->
   {phrase(op_elements(Op,X,Y),Rs)},
   [Rs],
   op_lists(Op,Xs,Ys).

op_elements(_Op,[],[]) -->
   [].
op_elements(Op,[X|Xs],[Y|Ys]) -->
   {opfd(Op,X,Y,R)},                    % <-(1)
   [R],
   op_elements(Op,Xs,Ys).

示例查詢:

   ?- lists_op_results([[1,2,3,4],[5,6,7,8]], [[1,2,3,4],[5,6,7,8]], +, R).
R = [[2,4,6,8],[10,12,14,16]]
   ?- lists_op_results([[1,2,3,4],[5,6,7,8]], [[1,2,3,4],[5,6,7,8]], -, R).
R = [[0,0,0,0],[0,0,0,0]]

@ lurker的例子:

   ?- lists_op_results([[1,2,3,4],[5,6,7,8]], L, +, [[3,6,9,12],[10,12,14,16]]).
L = [[2,4,6,8],[5,6,7,8]]

您還可以詢問是否存在適合給定列表的操作:

   ?- lists_op_results([[1,2,3,4],[5,6,7,8]], L, Op, [[3,6,9,12],[10,12,14,16]]).
L = [[2,4,6,8],[5,6,7,8]],
Op = + ? ;
L = [[-2,-4,-6,-8],[-5,-6,-7,-8]],
Op = -

旁注:由於操作是opfd / 4的第一個參數,你也可以像@ lurker的第一個解決方案中的建議一樣使用maplist。 你必須傳遞它缺少最后三個參數:

   ?- maplist(maplist(opfd(Op)),[[1,2,3,4],[5,6,7,8]], L, [[3,6,9,12],[10,12,14,16]]).
L = [[2,4,6,8],[5,6,7,8]],
Op = + ? ;
L = [[-2,-4,-6,-8],[-5,-6,-7,-8]],
Op = -

暫無
暫無

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

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