% fadder(A,B,C,D,E) :-  A + B + C = 10E + D  
:-dynamic(fadder/5).
fadder0(A,B,C,D,E) :- between(0,9,A),between(0,9,B),between(0,1,C),
	D is (A + B + C) mod 10, E is floor((A +B + C)/ 10), asserta(fadder(A,B,C,D,E)).
:- setof(fadder(A,B,C,D,E),fadder0(A,B,C,D,E),L), member(X,L),asserta(X),fail;true.
:- compile_predicates([fadder/5]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fukumen(A,B,C) :-
	setof(V,varof([A,B,C],V),Vars),
	setof([A,B,C],(fukumen0(A,B,C,0),alldifferent(Vars)),L),member([A,B,C],L). 

fukumen0([A|X],[B|Y],[D|Z],E) :- fadder(A,B,C,D,E), D \= 0, fukumen1(X,Y,Z,C).
fukumen1([],[],[],0) :- !. 
fukumen1([A|X],[B|Y],[D|Z],E) :- fadder(A,B,C,D,E), fukumen1(X,Y,Z,C).

varof(T,T) :- var(T),!.
varof(T,_) :- ground(T),!,fail.
varof(T,V) :- arg(_,T,A),varof(A,V). 

alldifferent(X) :- nth0(I,X,A),nth0(J,X,B),A==B, I \= J,!,fail.
alldifferent(_).
%% ----------------------------------------------
:- write('SEND + MORE = MONEY'), nl,fukumen([0,S,E,N,D],[0,M,O,R,E],[M,O,N,E,Y]) ,
	write([S,E,N,D]+[M,O,R,E]=[M,O,N,E,Y]),nl,fail;nl.
:- write('WWWDOT - GOOGLE = DOTCOM'),nl,fukumen([D,O,T,C,O,M],[G,O,O,G,L,E],[W,W,W,D,O,T]),
	write([W,W,W,D,O,T]-[G,O,O,G,L,E]=[D,O,T,C,O,M]),nl,fail;true.
