Search code examples
recursionprologclpfd

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?


Solution

  • 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 .