2011-10-16 56 views
0

我在做一些實驗用的Prolog並具有以下規則困難的幹法:序言:創建列表聲明

row(Row, Matrix, [R1,R2,R3,R4]) :- 
    cell(1, Row, Matrix, R1), 
    cell(2, Row, Matrix, R2), 
    cell(3, Row, Matrix, R3), 
    cell(4, Row, Matrix, R4). 

這條規則從提取的矩陣一行,鑑於其行號。例如,

row(2, [1,2,3,4,5,6,7,8], X) 
X = [5,6,7,8] 

讓我感到不快的是,代碼中有很多重複。在用4x4矩陣完成後,我將不得不處理9x9矩陣。代碼可以非常乾燥。

有沒有辦法提取重複出?

謝謝。

編輯:完整的代碼給我的麻煩就在這裏:https://github.com/kikito/7-languages-in-7-weeks/blob/master/3-prolog/day-3/sudoku-refactor.pl

回答

1

寫我的第一個回答後,我意識到,你也可以使用的findall

row(Row, Matrix, L) :- findall(X,cell(_,Row,Matrix,X),L). 
+0

試圖在此之後簡化程序,我得到了一個未捕獲異常:錯誤(instantiation_error,(是)/ 2)。我在原帖 – kikito

+1

中添加了完整代碼的鏈接。異常意味着您使用的是沒有完全實例化的右側。這是因爲在我findall我使用一個變量(下劃線)。如果你用輸入進行算術運算,findall不起作用。 你可以重寫單元格使用遞歸,或者你可以使用我在另一個回答中提出的方法 –

+0

對不起,我之前沒有回過頭來。感謝您的反饋,這是我所需要的。 – kikito

1

我會考慮改變表示要列出清單,而不是一個平面列表,然後選擇行變得非常容易。你可以使用內置的NTH1/3:

:- use_module(library(lists)). % I use Sicstus Prolog 
row(N,M,X) :- nth1(N,M,X). 
cell(R,C,M,X) :- nth1(R,M,Y), nth1(C,Y,X). 
column(N,M,X) :- findall(Y,(nth1(_,M,Z), nth1(N,Z,Y)),X). 

m([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]). 
example(Row,Cell,Column) :- m(M), row(2,M,Row), cell(2,3,M,Cell), column(2,M,Column). 

%| ?- example(A,B,C). 
%A = [5,6,7,8], 
%B = 7, 
%C = [2,6,10,14] ? ; 
%no