Reputation: 135
As a prolog newbie, I wanted to try to implement a binary sudoku solver.(Code is below, swi-prolog). Binary sudoku is explained here : https://cstheory.stackexchange.com/questions/16982/how-hard-is-binary-sudoku-puzzle
However, when performing the following query :
binarySudoku([[1,0],[0,1]]). I get "true."
binarySudoku([[1,_],[_,_]]). I get "false."
Now obviously it shouldn't return false as there is a solution... Why is this happening/how can I fix this?
:-use_module(library(clpfd)).
validRow(Row) :-
Row ins 0..1,
length(Row,L),
sum(Row,#=,L/2).
matrixNth(Matr,X,Y,El) :-
nth1(Y,Matr,CurRow),
nth1(X,CurRow,El).
allDifferent([]).
allDifferent([X|Y]) :-
not(member(X,Y)),
allDifferent(Y).
invalid(Rows,X,Y) :-
AboveY is Y-1,
BelowY is Y+1,
matrixNth(Rows,X,Y,1),
matrixNth(Rows,X,AboveY,1),
matrixNth(Rows,X,BelowY,1).
invalid(Rows,X,Y) :-
LeftX is X-1,
RightX is X+1,
matrixNth(Rows,X,Y,1),
matrixNth(Rows,LeftX,Y,1),
matrixNth(Rows,RightX,Y,1).
binarySudoku(Rows) :-
length(Rows,Height),
transpose(Rows,Cols),
length(Cols,Height),
maplist(validRow,Rows),
foreach(between(1,Height,X),foreach(between(1,Height,Y),not(invalid(Rows,X,Y)))),
allDifferent(Rows).
Upvotes: 4
Views: 781
Reputation: 40768
Instead of (\+)/1
, which is not logically sound in this case, use the pure constraint dif/2
: Your code works as expected of you change the line not(member(X,Y))
to:
maplist(dif(X), Y)
Example query (notice that I also use a_more_readable_naming_convention insteadOfMixingTheCases):
?- binary_sudoku([[1,A],[B,C]]), label([A,B,C]).
A = B, B = 0,
C = 1 ;
false.
+1 for using CLP(FD), which is a good fit for this task.
Upvotes: 4