Sudoku in Clingo

111 views Asked by At

I am trying to write a sudoku in clingo to learn the syntax a bit more. The part that I am satisfied with correctly represents the column/row constraints:

subgrid_size(3).
number(1..S*S) :- subgrid_size(S).
sudoku(X,Y,N) :- initial(X,Y,N).
1{sudoku(X,Y,N): number(N)}1 :- number(X), number(Y). %each coordinate has to have a unique N
1{sudoku(X,Y,N): number(X)}1 :- number(N), number(Y). %a number can only appear once per row
1{sudoku(X,Y,N): number(Y)}1 :- number(X), number(N). %a number can only appear once per col

Then I had tried to do something similar to enforce the subgrid constraint:

1{sudoku(X,Y,N): subgrid((X-1/S)*S+(Y-1)/S) }1 :- number(N),number(X), number(Y),subgrid_size(S).

This did not work, after a long time looking for solutions I found this(which works):

subgrid(X,Y,((X-1)/S)*S+(Y-1)/S):- number(X), number(Y), subgrid_size(S).
:- subgrid(X1,Y1,G), subgrid(X2,Y2,G),sudoku(X1,Y1,N), sudoku(X2,Y2,N), X1!=X2, Y1!=Y2.

Is there anyway to adapt the 1{...}1:- rule1..ruleN. line for the subgrid constraint so that it works?

1

There are 1 answers

1
Ivan Uemlianin On BEST ANSWER

Interesting approach! The immediate problem is that subgrid/1 in the choice rule is not defined anywhere. I get the error message:

info: atom does not occur in any rule head: subgrid(#Arith0)

Changing the choice rule to use subgrid/3 ...

1{sudoku(X,Y,N): subgrid(X, Y, (X-1/S)*S+(Y-1)/S ) }1 :-
    number(N), number(X), number(Y), subgrid_size(S).

... and including your subgrid/3 predicate ... now doesn't return an error, but returns unsatisfiable.

Here's what worked for me:

First I changed subgrid/3 slightly -- adding +1 to the third argument, so that subgrid labels were 1-9, instead of 0-8, ie now they are numbers:

subgrid(X, Y, (((X-1)/S)*S+(Y-1)/S)+1):-
    number(X),
    number(Y),
    subgrid_size(S).

Second, I used this choice rule:

1 { sudoku(X,Y,N):
    number(X), number(Y),
    subgrid(X,Y,M)
  } 1 :-
    number(N),
    number(M).

ie for every possible (N, M) combination, there is one sudoku(X,Y,N), where (X,Y) is in subgrid M.

Does that work for you?