% Prova 1.9
% Demonstrating the use of tabling

:- eval(consult('../ContractLog/math.prova')).

shapes( X, _, 0 ) :- X<0, !. 
shapes( 0, _, 1 ) :- !. 
shapes( 1, _, 1 ) :- !. 
shapes( _, 1, 1 ) :- !. 
shapes( Cards, Suits, Result ) :- 
    math_sub(Cards,Suits,FewerCards), 
    cache(shapes( FewerCards, Suits, A )), 
    math_sub(Suits,1,FewerSuits), 
    cache(shapes( Cards, FewerSuits, B )), 
	 math_add(A,B,Result).


shapesmemo( X, _, 0 ) :- X<0. 
shapesmemo( 0, _, 1 ). 
shapesmemo( 1, _, 1 ). 
shapesmemo( _, 1, 1 ). 


shapes2( X, Y, Z ) :- cache(shapesmemo( X, Y, Z)) , !. 
shapes2( Cards, Suits, Result ) :- 
    FewerCards = Cards - Suits, 
    shapes2( FewerCards, Suits, A ), 
    FewerSuits = Suits - 1, 
    shapes2( Cards, FewerSuits, B ), 
	 Result = A + B,
    println([Result]), 
    assert(shapesmemo( Cards, Suits, Result)). 


:- solve(shapes(100,80,X)).
