________________ | | | Q | | |___|___|___|___| | Q | | | | |___|___|___|___| | | | | Q | |___|___|___|___| | | Q | | | |___|___|___|___|
solve(P) :- perm([1,2,3,4,5,6,7,8],P), combine([1,2,3,4,5,6,7,8],P,S,D), all_diff(S), all_diff(D). combine([X1|X],[Y1|Y],[S1|S],[D1|D]) :- S1 is X1 +Y1, D1 is X1 - Y1, combine(X,Y,S,D). combine([],[],[],[]). all_diff([X|Y]) :- \+member(X,Y), all_diff(Y). all_diff([X]).
These clauses for takeout can be paraphrased in English as follows:takeout(X,[X|R],R). takeout(X,[F|R],[F|S]) :- takeout(X,R,S).
For example,
- When X is taken out of [X|R], R results.
- When X is taken out of the tail of [X|R], [X|S] results, where S is the result of taking X out of R.
The definition for 'member' is usually written?- takeout(X,[1,2,3],L). X=1 L=[2,3] ; X=2 L=[1,3] ; X=3 L=[1,2] ; No
member(X,[X|_]). member(X,[_|R]) :- member(X,R).
The last goal reflects the fact that there are 92 distinct solutions to the queens challenge puzzle for an 8x8 board. One inefficiency that this program suffers is that each permutation is completely calculated before it is checked to see whether it represents a solution to the puzzle. It is easy to see that this is not necessary. For example, suppose that a "partial solution" P = [1,3,2, ...] is up for consideration. The row and column calculations show already the "2" is not a safe move! A solution that avoids this inefficiency is considered in section 2.13.?- solve(P). P = [5,2,6,1,7,4,8,3] ; P = [6,3,5,7,1,4,2,8] ; ... ?- setof(P,solve(P),Set), length(Set,L). ... L = 92