% Figure 7.2 A program for cryptoarithmetic puzzles.
% Solving cryptarithmetic puzzles
sum(N1, N2, N) :- % Numbers represented as lists of digits
sum1( N1, N2, N,
0, 0, % Carries from right and to left both 0
[0,1,2,3,4,5,6,7,8,9], _). % All digits available
sum1( [], [], [], C, C, Digits, Digits).
sum1( [D1|N1], [D2|N2], [D|N], C1, C, Digs1, Digs) :-
sum1( N1, N2, N, C1, C2, Digs1, Digs2),
digitsum( D1, D2, C2, D, C, Digs2, Digs).
digitsum( D1, D2, C1, D, C, Digs1, Digs) :-
del_var( D1, Digs1, Digs2), % Select an available digit for D1
del_var( D2, Digs2, Digs3), % Select an available digit for D2
del_var( D, Digs3, Digs), % Select an available digit for D
S is D1 + D2 + C1,
D is S mod 10, % Reminder
C is S // 10. % Integer division
del_var( A, L, L) :-
nonvar(A), !. % A already instantiated
del_var( A, [A|L], L).
del_var( A, [B|L], [B|L1]) :-
del_var(A, L, L1).
% Some puzzles
puzzle1( [D,O,N,A,L,D],
[G,E,R,A,L,D],
[R,O,B,E,R,T] ).
puzzle2( [0,S,E,N,D],
[0,M,O,R,E],
[M,O,N,E,Y] ).