Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog recursive program not returning values

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?

like image 842
Zenadia Groenewald Avatar asked Jun 01 '26 19:06

Zenadia Groenewald


1 Answers

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 .
like image 112
mat Avatar answered Jun 04 '26 13:06

mat