:- use_module(library(clpfd)). % TODO: comment out!! % board_size(4). %?- poss_safe([pos(1,2),pos(2,4),pos(3,1),pos(4,3)]). /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pick a queen, make a move. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ rearrangement_(_, Ps0, [P|Ps1]) :- select(pos(R,C), Ps0, Ps1), valid_move(R, C, Ps1, P). valid_move(R0, C0, Ps, Pos) :- further(right, R0, C0, Ps, Pos). valid_move(R0, C0, Ps, Pos) :- further(left, R0, C0, Ps, Pos). valid_move(R0, C0, Ps, Pos) :- further(up, R0, C0, Ps, Pos). valid_move(R0, C0, Ps, Pos) :- further(down, R0, C0, Ps, Pos). valid_move(R0, C0, Ps, Pos) :- further(up_right, R0, C0, Ps, Pos). valid_move(R0, C0, Ps, Pos) :- further(down_right, R0, C0, Ps, Pos). valid_move(R0, C0, Ps, Pos) :- further(up_left, R0, C0, Ps, Pos). valid_move(R0, C0, Ps, Pos) :- further(down_left, R0, C0, Ps, Pos). %?- valid_move(1, 1, [], Pos). move_direction(R0, C0, down, R, C0) :- R #= R0 - 1. move_direction(R0, C0, up, R, C0) :- R #= R0 + 1. move_direction(R0, C0, left, R0, C) :- C #= C0 - 1. move_direction(R0, C0, right, R0, C) :- C #= C0 + 1. move_direction(R0, C0, up_right, R, C) :- C #= C0 + 1, R #= R0 + 1. move_direction(R0, C0, down_right, R, C) :- C #= C0 + 1, R #= R0 - 1. move_direction(R0, C0, up_left, R, C) :- C #= C0 - 1, R #= R0 + 1. move_direction(R0, C0, down_left, R, C) :- C #= C0 - 1, R #= R0 - 1. further(What, R0, C0, Ps, Pos) :- move_direction(R0, C0, What, R, C), board_size(Size), [R,C] ins 1..Size, \+ memberchk(pos(R,C), Ps), ( Pos = pos(R,C) ; further(What, R, C, Ps, Pos) ). main :- findall(pos(A,B), pos(A,B), Ps0), length(Ls, L), foldl(rearrangement_, Ls, Ps0, Ps), poss_safe(Ps), portray_clause(moves(L)). poss_safe(Ps) :- poss_to_list(Ps, Ls), n_queens(Ls). poss_to_list(Ps, Ls) :- same_length(Ps, Ls), maplist(pos_list(Ls), Ps). pos_list(Ls, pos(R,C)) :- nth1(C, Ls, R). %?- nth1(1, [a,b,c], R). %@ R = a. n_queens(Qs) :- length(Qs, N), Qs ins 1..N, safe_queens(Qs). safe_queens([]). safe_queens([Q|Qs]) :- safe_queens(Qs, Q, 1), safe_queens(Qs). safe_queens([], _, _). safe_queens([Q|Qs], Q0, D0) :- Q0 #\= Q, abs(Q0 - Q) #\= D0, D1 #= D0 + 1, safe_queens(Qs, Q0, D1).