Prolog CLPFD Bishop move

65 Views Asked by At

so I’m new to Prolog and we have this problem

Consider a chessboard of side n. You need to place 2(n-1) bishops on the chessboard so that no two bishops threaten each other. Bishops move only diagonally.

Express the problem using constraints-based terminology. Name the variables, their domains and the constraints.

Apply depth-first-search and forward checking for a problem with n=3 placing the first bishop at square (1,1). Write down the squares for the other bishops in the order you generate solutions.

I was able to use DFS, but I’m lost with CLPFD

1

There are 1 best solutions below

0
repeat On

We associate each bishop with an ordered pair X/Y—a X and Y position on the board.

Every bishop lies on one diagonal (X - Y) and on one skew diagonal (X + Y).

All bishops must be on different diagonals and on different skew diagonals.

Putting it all together:

:- use_module(library(clpz)).
:- use_module(library(lists)).

n_bishop(N,Bss) :-
   n_bishop_(N,Bss,Zs),
   labeling([],Zs).

n_bishop_(0,[],[]).
n_bishop_(1,[1/1],[]).
n_bishop_(N,Bss,Zs) :-
   N #> 1,
   L #= 2 * (N-1),
   length(Bss,L),
   bishops_n_mains_antis_zs(Bss,N,Ms,As,Zs),
   Zs ins 1..N,
   chain(#<,Ms),        % impose order on pairs
%  all_different(Ms),   % (redundant)
   all_different(As).

bishops_n_mains_antis_zs([]      ,_N,[],[],[]).
bishops_n_mains_antis_zs([X/Y|XYs],N,[M|Ms],[A|As],[X,Y|Zs]) :-
   M #= X - Y,
   A #= X + Y,
   bishops_n_mains_antis_zs(XYs,N,Ms,As,Zs).

Using Scryer Prolog:

?- n_bishop(N,Bss).
   N = 0, Bss = []
;  N = 1, Bss = [1/1]
;  N = 2, Bss = [1/1,2/1]
;  N = 2, Bss = [1/2,1/1]
;  N = 2, Bss = [1/2,2/2]
;  N = 2, Bss = [2/2,2/1]
;  N = 3, Bss = [1/2,1/1,3/2,3/1]
;  N = 3, Bss = [1/2,3/3,3/2,3/1]
;  N = 3, Bss = [1/3,1/2,1/1,3/2]
;  N = 3, Bss = [1/3,1/2,3/3,3/2]
;  N = 3, Bss = [1/3,2/3,1/1,2/1]
;  N = 3, Bss = [1/3,2/3,3/3,2/1]
;  N = 3, Bss = [2/3,1/1,2/1,3/1]
;  N = 3, Bss = [2/3,3/3,2/1,3/1]
;  N = 4, Bss = [1/3,1/2,1/1,4/3,4/2,4/1]
;  N = 4, Bss = [1/3,1/2,4/4,4/3,4/2,4/1]
;  N = 4, Bss = [1/3,3/4,1/1,2/1,4/2,4/1]
;  ... .