You write: "My program compiles but the function does not execute: "
solve([A, M1, M2, P, D, Y]):- D is 1,
A/=0,
No wonder. First of all, there's no /=
operator in Prolog. I assume you meant \=
. But A \= B
means "A can not be unified with B". In your case B
is 0, but A
is a yet not set logical variable. It can be unified with anything. You should only use \=
to check inequality, after all logvars involved had been instantiated!
So, A \= 0
fails. (Another thing is, M1=M2
is superfluous, you can just use M
throughout).
A general tool to solve such puzzles is unique selection from narrowing domains:
selectM([A|As],S,Z):- select(A,S,S1),selectM(As,S1,Z).
selectM([],Z,Z).
With it, your puzzle is just
solve([A,M,P,D,Y]):-
selectM([A,P,D],[1,2,3,4,5,6,7,8,9],R), % R is the remaining domain
selectM([M,Y],[0|R],_), % don't care what remains
10*(A+P)+M+M =:= 100*D+10*A+Y.
You have a right idea of finding out the assignments before searching, where possible. Using your approach, it could be written as
solve([A,M,P,D,Y]):-
selectM([M,A],[0,1,2,3,4,5,6,7,8,9],R),
A =\= 0,
Y is (M+M) mod 10, % AM+PM=DAY
C1 is (M+M) // 10,
A is (A+P+C1) mod 10,
D is (A+P+C1) // 10,
selectM([P,D,Y],R,_), % ensure all are different
p =\= 0, D =\= 0.
Again, we must select A
before testing its value.