2016-01-25 117 views
1

我一直在搜索許多現有的關於分解的相關的Prolog問題,但找不到像我想要的那樣通用的一個。我想指出,我已經能夠通過在列表變量之前使用2/3/4變量來將列表拆分成2/3/4個元素的列表。這個問題不同於那只是因爲它的通用性。因此,我的列表將總是包含N * N個項目,N事先未知(通常會從4到36變化,是的,N也是一個完美的正方形)。我想將它分成N個列表,每個列表包含N個項目,因爲這可以讓我把它當作矩陣處理,從而允許轉置和某種類型的操作。由於我對聲明性編程比較陌生,因此我並沒有真正能夠理解邏輯。請參閱我下面的不完整的(錯誤的)嘗試:序言:將一個列表分成N個列表,每個列表包含N個項目

listmodel(1,L):- L = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]. 
size(L,N) :- length(L,N1), N is round(sqrt(N1)). 

% add_tail(+Liste, +Element, -ResultantList) 
add_tail([],L,[L]). 
add_tail([X|L1],L2,[X|LI]):-add_tail(L1,L2,LI). 

% partition the list containing N*N items into a list of N lists containing N elements each. 
% part(+Liste, +Size, -ResultantList) 
part([],_,DL). 
part(L,N,DL) :- 
    length(P,N), % P(refix) initialized 
    append(P,S,L), % S(uffix) contains rest of L, using append in (-,-,+) mode 
    add_tail(DL,P,DL1), %add P(first N elements) as first element of DL. 
    part(S,N,DL1). 

現在運行?- listmodel(1,L),size(L,N),part(L,N,DL).會產生DL=[]因爲這是它得到在part謂詞第一add_tail調用初始化。我似乎無法弄清楚如何將所有元素存儲在通過遞歸保存的列表中。

任何形式的幫助/方向將不勝感激。自從現在超過23小時10分鐘以來,我一直困在這裏。

謝謝。

回答

2

這應做到:

 
part([], _, []). 
part(L, N, [DL|DLTail]) :- 
    length (DL, N), 
    append (DL, LTail, L), 
    part(LTail, N, DLTail). 

基本情況是第一次/一個參數是空列表。

遞歸步驟花費N個元素的新鮮列表中,從L取前N個元素(這將是第三個參數的項中的一個),並遞歸地調用。

+1

完美!謝謝你的確切答案和簡潔的解釋。 – Donbhupi

2

想結合的多功能性有利的終止性質? 使用

 
:- use_module (library(clpfd)). 

首先,我們定義 list_prefix_n_suffix/4list_prefix_n_suffix(Zs,Xs,N,Ys)在邏輯上等於append (Xs,Ys,Zs), length (Xs,N)length (Xs,N), append (Xs,Ys,Zs),但具有比要好的通用終止行爲 one!對於list_prefix_n_suffix/4

 
list_prefix_n_suffix(Zs, Xs, N, Ys) :- 
    list_prefix_n0_n_suffix(Zs, Xs, 0,N, Ys). 

list_prefix_n0_n_suffix(Zs, Xs, N0,N, Ys) :- 
    zcompare (Order, N0, N), 
    rel_list_prefix_n0_n_suffix(Order, Zs, Xs, N0,N, Ys). 

rel_list_prefix_n0_n_suffix(=, Ys, [], _,_, Ys). 
rel_list_prefix_n0_n_suffix(<, [Z|Zs], [Z|Xs], N0,N, Ys) :- 
    N1  #= N0  + 1, 
    list_prefix_n0_n_suffix(Zs, Xs, N1,N, Ys). 

一些樣本查詢:根據以上list_prefix_n_suffix/4

 
?- list_prefix_n_suffix([a,b,c], Xs,-1, Ys). 
false.           % OK: too small 

?- list_prefix_n_suffix([a,b,c], Xs, 0, Ys). 
Xs = [], Ys = [a,b,c].       % succeeds deterministically 

?- list_prefix_n_suffix([a,b,c], Xs, 4, Ys). 
false.           % OK: too big 

?- list_prefix_n_suffix([a,b,c], Xs, N, Ys). 
    Xs = []  , N = 0, Ys = [a,b,c] 
; Xs = [a] , N = 1, Ys = [b,c] 
; Xs = [a,b] , N = 2, Ys =  [c] 
; Xs = [a,b,c], N = 3, Ys =  [] 
; false.          % terminates universally 

我們定義list_rows_width/3:使用list_rows_width/3

 
list_rows_width([], [], _N). 
list_rows_width([E|Es0], [[R|Rs]|Rss], N) :- 
    list_prefix_n_suffix([E|Es0], [R|Rs], N, Es), 
    list_rows_width(Es, Rss, N). 

示例查詢:

 
?- list_rows_width([a,b,c,d,e,f], Rows, 4). 
false.           % OK: 6 is not divisible by 4 

?- list_rows_width([a,b,c,d,e,f], Rows, 3). 
Rows = [[a,b,c],[d,e,f]].      % succeeds deterministically 

?- list_rows_width([a,b,c,d,e,f,g,h,i,j,k,l], Rows, N). 
    N = 1, Rows = [[a],[b],[c],[d],[e],[f],[g],[h],[i],[j],[k],[l]] 
; N = 2, Rows = [[a, b],[c, d],[e, f],[g, h],[i, j],[k, l]] 
; N = 3, Rows = [[a, b, c],[d, e, f],[g, h, i],[j, k, l]] 
; N = 4, Rows = [[a, b, c, d],[e, f, g, h],[i, j, k, l]] 
; N = 6, Rows = [[a, b, c, d, e, f],[g, h, i, j, k, l]] 
; N = 12, Rows = [[a, b, c, d, e, f, g, h, i, j, k, l]] 
; false.          % terminates universally 

作品就像它應該!


腳註1:沒有求助於使用替代控制流機制,例如

相關問題