:- module(_,_).
:- use_package(clpfd).

% -------------------------------------------------------------------
% - The classic SEND MORE MONEY example

% Find what decimal digit (i.e., 0 to 9) each letter stands for so
% that the addition is correct:
%
%     S E N D
%   + M O R E
%   _________
%   M O N E Y
%
% - Each letter must be a different digit
% - No 0's at the left (i.e., not S or M)

% A frst version: 
   
smm_no_labeling(Vars) :-
    Vars = [S,E,N,D,M,O,R,Y], 
    domain(Vars, 0, 9),  % All digits 0..9
    0 #< S, 0 #< M,      % No leftmost zeros
    all_different(Vars), % All digits different
    % And the arithmetic constraints: 
              S*1000 + E*100 + N*10 + D +
              M*1000 + O*100 + R*10 + E #=
    M*10000 + O*1000 + N*100 + E*10 + Y.

% ?- smm_no_labeling([S,E,N,D,M,O,R,Y]).
% -> We need labeling!

% Version adding labeling (and a pretty printer):
smm(Vars) :-
    Vars = [S,E,N,D,M,O,R,Y], 
    domain(Vars, 0, 9),
    0 #< S, 0 #< M,
    all_different(Vars),
    S*1000 + E*100 + N*10 + D +
    M*1000 + O*100 + R*10 + E #=
    M*10000 + O*1000 + N*100 + E*10 + Y,
    labeling([], Vars), 
    pp_smm(Vars).

% ?- smm([S,E,N,D,M,O,R,Y]).

% A simple pretty printer: 
pp_smm([S,E,N,D,M,O,R,Y]) :-
    format("~n   ~w ~w ~w ~w~n",  [S,E,N,D]),
    format(  " + ~w ~w ~w ~w~n",  [M,O,R,E]),
    format(  " ---------~n",             []),
    format( " ~w ~w ~w ~w ~w~n",[M,O,N,E,Y]).
