As @lurker already said in his comment, use CLP(FD) constraints.
In addition, I recommend:
- instead of
solve/1
, use a declarative name like solution/1
. You should describe what holds for a solution, so that the relation makes sense in all directions, also for example if the solution is already given and you want to validate it.
- By convention, it makes sense to let variables that stand for lists end with an
s
.
- Separate side-effects from pure code. In fact, remove side-effects altogether. Let the prolog-toplevel do the printing for you!
For example:
:- use_module(library(clpfd)).
solution(Ls) :-
Ls = [A,B,C,E,F,G,J,K,L,N,O,P],
A #= 24-B-C,
B #= 26-F-J-N,
C #= 15-G-K-O,
E #= 11-F-G,
E #= 17-A,
J #= 22-K-L,
N #= 14-O-P,
L #= 13-P.
This already works for queries like:
?- solution(Ls), Ls ins 0..sup, label(Ls).
Ls = [6, 3, 15, 11, 0, 0, 9, 0, 13, 14, 0, 0] ;
Ls = [6, 3, 15, 11, 0, 0, 10, 0, 12, 13, 0, 1] ;
Ls = [6, 3, 15, 11, 0, 0, 11, 0, 11, 12, 0, 2] ;
etc.
I leave completing this as an easy exercise.
A + B + C #= 24
instead ofA is 24-B-C
. Theis/2
requires that variables in the second expression all be instantiated. – Hillell