Prolog - 限制 - 点亮/ Akari

时间:2014-12-04 08:51:04

标签: prolog constraints clpfd sicstus-prolog

我试图解决一个Light-Up谜题,并且我遇到了制约这些限制的麻烦。

我的主要谓词是:

akari(Rows, Size) :-
   length(Rows, Size), maplist(length_list(Size), Rows),
   append(Rows, Board),
   domain(Board, 0, 2),
   processRows(Rows, Rows, 0-0, Size),
   % transpose(Rows, Columns),
   % processRows(Columns, Columns, 0-0, Size),
   labeling([], Board),
   write(Board), nl,
   printBoard(Board, Size).

Rows采用矩阵形式,例如,每个自由方格的情况:

start :-
   akari([[_,_,_],
          [_,_,_],
          [_,_,_]], 3).

处理我使用的每一行:

processRows([], _Board, _Row-_Col, _Size).
processRows([H|T], Board, Row-Col, Size) :-
   processRow(H, Board, Row-Col, Size, []),
   NewRow is Row + 1,
   processRows(T, Board, NewRow-0, Size).

processRow([], _Board, _Row-_Col, _Size, _VarList).
processRow([H|T], _Board, _Row-Col, _Size, _VarList) :-
   H == 2,
   NewCol is Col + 1,
   processRow(T, Board, Row-NewCol, Size, []).          
processRow([H|T], Board, Row-Col, Size, VarList) :-
   gatherLeft(Board, Row-Col, Row-Col, Size, VarList).
   NewCol is Col + 1,
   processRow(T, Board, Row-NewCol, Size, []).

所以我浏览矩阵的每个元素,然后我从gatherLeft开始 - 它召唤其他主要的集合,右,上,下 - 广场的行和列我是处理。 这个想法是行和列的每个交叉点 - 如果你愿意的话,十字架 - 最多只能有一个灯泡。

但如果我这样做:

count2([],0).           
count2([H|T], Count) :-
   H #= 1 #<=> C,
   count2(T, C2),
   Count #= C + C2.

或者这个     sum(VarList,#=&lt;,1)

我的意图是&#34;每个十字架最多只能有一个灯泡&#34;但我最终选择了每一个空间,我最终会说&#34;整个电路板最多只能有一个灯泡&#34; 。我最终得到一块空板。

修改

对于子孙后代,我想出的解决方案是:

每个方格最多只能有一盏灯,sum([H], #=<, 1)

取一个正方形,它的列和行最多只能有一个亮点,所以sum(Row, #=<, 1)

正方形的邻域必须至少有一个灯光,所以sum(VarList, #>=, 1)

现在似乎正在发挥作用。

0 个答案:

没有答案