Пролог: СУХОЙ способ создания списков декларативно - PullRequest
0 голосов
/ 17 октября 2011

Я провожу некоторые эксперименты с Прологом и испытываю трудности со следующим правилом:

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]

Меня беспокоит то, что в этом коде много повторений.Закончив с матрицами 4х4, мне придется иметь дело с матрицами 9х9.И код может стать совсем не СУХИМЫМ.

Есть ли способ извлечь это повторение?

Спасибо.

Редактировать: Полный код, доставляющий мне проблемы, находится здесь:https://github.com/kikito/7-languages-in-7-weeks/blob/master/3-prolog/day-3/sudoku-refactor.pl

Ответы [ 2 ]

1 голос
/ 17 октября 2011

После написания моего первого ответа я понял, что вы также можете упростить вашу программу, используя findall

 row(Row, Matrix, L) :- findall(X,cell(_,Row,Matrix,X),L).
1 голос
/ 17 октября 2011

Я бы подумал об изменении представления в виде списка списков, а не простого списка, тогда выбор строки становится очень простым.Вы можете просто использовать встроенный 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
...