power function in prolog

32,385

Solution 1

Your Y does not get decremented, you can not use predicates like functions. You also have to unify Z with the result of the multiplication.

pow(_,0,1).

pow(X,Y,Z) :- Y1 is Y - 1,
              pow(X,Y1,Z1), Z is Z1*X.

There is also a builtin power function which will be much faster:

pow2(X,Y,Z) :- Z is X**Y.

Also note that pow is not a last call and can not be optimized to use only one stack frame. You should reformulate it to:

pow3(X,Y,Z) :- powend(X,Y,1,Z),!.

powend(_,0,A,Z) :- Z is A.
powend(X,Y,A,Z) :- Y1 is Y - 1, A1 is A*X, powend(X,Y1,A1,Z).

Solution 2

Predicates
fac(Integer,Integer,Integer).
Clauses
fac(X,N,X):- N=1,!.
fac(X,N,M):- N1=N-1,fac(X,N1,M1), M= X*M1.
Goal
fac(5,3,X).

Solution 3

DOMAINS
num=INTEGER

PREDICATES
nondeterm power(num,num,num)

CLAUSES
power(X,0,1).
power(X,P,F):-X>0,P1=P-1,power(X,P1,F1),F=X*F1.

GOAL
power(2,5,X).
Share:
32,385
TheOne
Author by

TheOne

Updated on July 17, 2020

Comments

  • TheOne
    TheOne almost 4 years

    What is wrong with my power function?

    pow(_,0,1).   
    pow(X,Y,Z) :-
        pow(X,Y-1,X*Z).
    
    ?- pow(2,3,Z).
    ERROR: Out of global stack
    
  • false
    false about 12 years
    @ebo: Your definitions pow/3 and pow3/3 do not terminate! Try pow(1,0,0). This should fail.
  • ebo
    ebo about 12 years
    The Z parameter should not be bound. Also this is an academic example. Not all edge cases are considered to lower the complexity of the implementation.
  • ebo
    ebo over 11 years
    Kind of strange, but fixed.
  • ebo
    ebo over 11 years
    All three examples terminate in SWI-Prolog 5.10.4.
  • false
    false about 10 years
    fac(5,3,1) should fail, but it loops.
  • Maik
    Maik about 10 years
    in my case fac(5,3,1) return no, without loops, I use Visual_Prolog_v52_pe.
  • false
    false about 10 years
    Impossible. You must have a different program.
  • false
    false about 10 years
    @ebo: They don't for pow3(1,0,0)