You can use CLP(FD) to solve the problem. The condition
that two neighbouring cells do not have a distance of one
can be expressed even without reification:
ns(X, Y) :-
X #\= Y+1,
X+1 #\= Y.
Reification is not needed since in the present situation
a (#/\)/2 can be replaced by a (,)/2. Together with all_different/1 the problem can be expressed as follows:
riddle(L) :-
L = [A,B,C,D,E,F,G,H],
L ins 1..8,
all_different(L),
/* horizontal */
ns(B, E),
ns(A, C),
ns(C, F),
ns(F, H),
ns(D, G),
/* vertical */
ns(B, C),
ns(C, D),
ns(E, F),
ns(F, G),
/* search solution */
label(L).
Running it I get the following number of solutions:
Jekejeke Prolog 3, Runtime Library 1.3.0
(c) 1985-2018, XLOG Technologies GmbH, Switzerland
?- riddle([7,4,1,3,6,8,5,2]).
Yes
?- findall(hit,riddle(_),L), length(L,N),
write(N), nl, fail; true.
1656
Yes
Edit 31.07.2018:
This is left as a homework. If you add constraints for the diagonals from bottomleft to topright, and the diagonals from
topleft to bottomright, the system gets more tight and only generates the following four solutions:
?- riddle(L).
L = [2,5,8,6,3,1,4,7] ;
L = [2,6,8,5,4,1,3,7] ;
L = [7,3,1,4,5,8,6,2] ;
L = [7,4,1,3,6,8,5,2] ;
No