How can one tell Prolog/CLPFD to only use certain number of domain only as last resource?
E.g. : domain from 0...8. I want Prolog to use 0 only if there's no other option. I used the 'down' option for labeling, but too many 0's are assigned.
Context: Hoo-Doo game -> Generate 8x8 board solution where any column,row or diagonal have the numbers from 1-8 without repeating (Sudoku like). One must use two transparent pieces (represented by 0, which can be anywhere) in order to complete the solution.
Here's the code:
...
setDomain(H,BoardSize),
maplist(all_distinct,H),
IndexI is BoardSize - 1,
IndexJ is BoardSize - 2,
checkDiagonalsLR(H,IndexI,IndexJ,BoardSize), %calls the all_distinct
IndexJ2 is BoardSize - 1,
checkDiagonalsRL(H,1,IndexJ2,BoardSize), %calls the all_distinct
transpose(H,Columns), maplist(all_distinct,Columns),
useLabeling(Columns,BoardSize), printBoard(Columns).
useLabeling([],N).
useLabeling([H|T],N) :- labeling([down],H), useLabeling(T,N).
One way is to use Boolean variables Bs
and reified constraints so that B_i
is 1 iff V_i
is zero:
(V_i #= 0) #<==> B_i
the sum of the B_i
variables is then the number N
of zeroes that occur in your solution:
sum(Bs, #=, N)
Then, you can use labeling/2
in such a way that N
is minimal:
labeling([min(N)], Vs)
This works (with small adjustments) for example in SICStus and SWI.