我正在使用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
答案 0 :(得分: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
答案 1 :(得分:1)
在写完第一个答案后,我意识到你也可以使用findall
来简化你的程序 row(Row, Matrix, L) :- findall(X,cell(_,Row,Matrix,X),L).