I'm still new to Prolog, and I've encountered an error I have no idea how to fix. I've written a simple exponentiation program that looks like this:
exp(b, 0, R) :- R is 1. % non-recursive case: exponent is 0
exp(0, e, R) :- R is 0. % non-recursive case: base is 0
exp(Base, Exponent, Result) :- % recurse if base and exponent are non-negative
Base >= 0,
Exponent >= 0,
E1 is Exponent-1,
exp(Base, E1, R1),
Result is Base*R1.
This compiles fine, but when I run it and give it a query like, say, exp(2, 4, X)
. I'm met with the following output:
?- exp(2, 4, X).
false.
Is there something I've done wrong? Or is it a matter of formatting the result in some way I'm unaware of?
You are confusing variables with atoms. It works as expected if you simple change the two nonrecusive clauses to:
exp(_, 0, 1). exp(0, _, 0).
In fact, I recommend to change the whole program to use CLP(FD) constraints throughout:
exp(_, 0, 1). exp(0, _, 0). exp(Base, Exponent, Result):- Base #>= 0, Exponent #>= 0, E1 #= Exponent-1, exp(Base, E1, R1), Result #= Base*R1.
Now for example the following at least yields a solution:
?- exp(2, X, 16). X = 4
whereas we previously had:
?- exp(2, X, 16). >=/2: Arguments are not sufficiently instantiated
Note also the most general query:
?- exp(X, Y, Z). Y = 0, Z = 1 ; X = Z, Z = 0 ; X = Z, Y = 1, Z in 0..sup ; X = Z, Z = 0, Y in 0..sup, _G801+1#=Y, _G801 in -1..sup .