1
votes

I am trying to make a tail recursive helper for power predicate in Prolog. So far I have this but when testing I get a message saying there is a breakpoint when trying to call helper predicate. What am I doing wrong? Ty for the help.

    trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res).
    
    trpow_helper(_, 0, Acc, Acc).
    trpow_helper(Base, Exp, Acc, Res) :-
        Exp > 0,
        Decexp is Exp - 1,
        Acc1 is Acc * Base,
        Res = Acc1,
        trpow_helper(Base, Decexp, Acc1, Res).
2

2 Answers

1
votes

Based on your code,

trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res).

trpow_helper(_, 0, Acc, Acc):- !. /*Cut to avoid bt to second clause*/
trpow_helper(Base, Exp, Acc, Res) :-
    Exp > 0,
    Decexp is Exp - 1,
    Acc1 is Acc * Base, /*removed Res = Acc1, not needed*/
    trpow_helper(Base, Decexp, Acc1, Res).

It now works !

0
votes

Using CLP such as that in swi-prolog:

:- use_module(library(clpfd)).
trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res).

trpow_helper(   _, Exp, Acc, Acc):- Exp #= 0.
trpow_helper(Base, Exp, Acc, Res) :-
    Exp #> 0,
    Decexp #= Exp - 1,
    Acc1 #= Acc * Base,
    trpow_helper(Base, Decexp, Acc1, Res).

?- trpow(1, E, 1).
E = 0 ;
E = 1 .
?- trpow(2, E, 4).
E = 2 .
?- trpow(2, E, 8).
E = 3 .
?- trpow(B, 3, 8).
B = 2 .
?- trpow(B, E, 8).
B = 8,
E = 1 ;
B = 2,
E = 3 ;
...

After which, more solutions that doesn't instanciate B. In fact it loops forever.