Use clpfd!
:- use_module(library(clpfd)).
All we need to express change/4
is one equation:
change(Money,Pennies,Nickels,Dimes) :-
Money #= Pennies + Nickels*5 + Dimes*10.
Let's run the ground query given by the OP!
?- change(100,10,8,5).
true.
Next up, four queries having exactly one variable:
?- change(Money,10,8,5).
Money = 100.
?- change(100,Pennies,8,5).
Pennies = 10.
?- change(100,10,Nickels,5).
Nickels = 8.
?- change(100,10,8,Dimes).
Dimes = 5.
As we are using clpfd, we can also ask more general queries, like this one with three variables:
?- change(100,Pennies,Nickels,Dimes).
100 #= Pennies + 5*Nickels + 10*Dimes.
Note that this does not (yet) enumerate all possible combinations... to do so takes two steps:
State that "all counts are non-negative" by using ins/2
:
?- [Pennies,Nickels,Dimes] ins 0..sup,
change(100,Pennies,Nickels,Dimes).
100 #= Pennies + 5*Nickels + 10*Dimes,
Pennies in 0..100,
Nickels in 0..20,
Dimes in 0..10.
Use the enumeration predicate labeling/2
:
?- Zs = [Pennies,Nickels,Dimes],
Zs ins 0..sup,
change(100,Pennies,Nickels,Dimes),
labeling([],Zs).
Pennies = 0 , Nickels = 0, Dimes = 10
; Pennies = 0 , Nickels = 2, Dimes = 9
; Pennies = 0 , Nickels = 4, Dimes = 8
% the next 115 answers were omitted for the sake of brevity
; Pennies = 90 , Nickels = 2, Dimes = 0
; Pennies = 95 , Nickels = 1, Dimes = 0
; Pennies = 100, Nickels = 0, Dimes = 0
; false.