In any case, I would treat the negative exponent with a predicate, as already given in the problem post, which is:
power(Base, N, P) :-
N < 0,
N1 is -N,
power(Base, N1, P1),
P is 1/P1.
So the following assume non-negative exponents.
This algorithm multiples the base N
times:
power1(Base, N, P) :-
N > 0,
N1 is N - 1,
power1(Base, N1, P1),
P is P1 * Base.
power1(Base, N, P) :-
N < 0,
N1 is N + 1,
power1(Base, N1, P1),
P is P1 / Base.
power1( _Base, 0, 1 ).
This algorithm multiples the base N
times using tail recursion:
power1t(Base, N, P) :-
N >= 0,
power1t(Base, N, 1, P).
power1t(Base, N, A, P) :-
N > 0,
A1 is A * Base,
N1 is N - 1,
power1t(Base, N1, A1, P).
power1t(_, 0, P, P).
This version uses the "power of 2" method, minimizing the multiplications:
power2(_, 0, 1).
power2(Base, N, P) :-
N > 0,
N1 is N div 2,
power2(Base, N1, P1),
( 0 is N /\ 1
-> P is P1 * P1
; P is P1 * P1 * Base
).
This version uses a "power of 2" method, minimizing multiplications, but is tail recursive. It's a little different than the one Boris linked:
power2t(Base, N, P) :-
N >= 0,
power2t(Base, N, Base, 1, P).
power2t(Base, N, B, A, P) :-
N > 0,
( 1 is N /\ 1
-> A1 is B * A
; A1 = A
),
N1 is N div 2,
B1 is B * B,
power2t(Base, N1, B1, A1, P).
power2t(_, 0, _, P, P).