I have this predicate which returns true if S is equal to some equation say K + 2N + 3L = S. The money we have are 1, 5, and 10 respectively for K, N, L.
I don't want to use :- use_module(library(clpfd))
, I want to solve this without it.
My intuition was to break this into subproblems like write a function breakMoney1(S,K) :- K is S
. and create more helpers with one more parameter added however I am struggling with the problem of getting uninstantiated variables, when I compare.
breakMoney(S,K,N,L) :-
This is easier than you think, probably. A very naive solution following @Will Ness' suggestion would be:
This will "magically" turn into a clp(fd) solution with very little effort: for example, replace
between
withX in 0..Max
, and the=:=
with#=
. Although, it should be enough to simply say thatX #>= 0
for each of the denominations. It is a good exercise to see how much of the constraints you can remove and still get an answer:Depending on how you instantiate the arguments, you might immediately get a unique answer, or you might need to use
label/1
:But as @lurker has pointed out, there is very little reason not to use constraint programming for this problem. Unless, of course, you have a very clever algorithm for solving this particular problem and you know for a fact that it will outsmart the generic clp(fd) solution. Even then, it might be possible to achieve the same effect by using the options to
labelling/2
.