Во-первых, нужно подумать, как определить 0 0 . Формально говоря, это неопределенно . Это может быть ноль или может быть 1. Как говорит Mathworld Вольфрама в своей статье о силах и в статье о нуле :
0 0 (от нуля до нулевой степени) сам по себе не определен. Отсутствие четко определенного значения для этой величины следует из взаимно противоречивых фактов, что a 0 всегда равно 1, поэтому 0 0 должно равняться 1, но 0 a всегда равно 0 (для a > 0), поэтому 0 a должно быть равно 0. выбор определения для 0 0 обычно определяется как неопределенный, хотя определение 0 0 = 1 позволяет просто выразить некоторые формулы (Knuth 1992; Knuth 1997, p. 57).
Итак, вы должны сначала выбрать, как определить особый случай 0 0 : это 0? Это 1? Это неопределенно?
Я предпочитаю смотреть на это как на неопределенное.
При этом вы можете смотреть на положительный показатель как указанное повторное умножение (например, 10 3 равно 10 * 10 * 10 или 1000), и вы можете смотреть на отрицательный показатель как на повторяющийся деление (например, 10 -3 равно (((1/10) / 10) / 10) или 0,001). Моя склонность, отчасти потому, что мне нравится симметрия этого подхода, а отчасти, чтобы избежать срезов (поскольку срез часто является сигналом того, что вы не определили решение правильно), будет выглядеть примерно так:
% -----------------------------
% The external/public predicate
% -----------------------------
pow( 0 , 0 , _ ) :- ! , fail .
pow( X , N , R ) :-
pow( X , N , 1 , R )
.
% -----------------------------------
% the tail-recursive worker predicate
% -----------------------------------
pow( _ , 0 , R , R ).
pow( X , N , T , R ) :-
N > 0 ,
T1 is T * X ,
N1 is N-1 ,
pow( X , N1 , T1 , R )
.
pow( _ , 0 , R , R ) :-
N < 0 ,
T1 is T / X ,
N1 is N+1 ,
pow( X , N1 , T1 , R )
.
Другой подход, как отмечали другие, заключается в определении положительного показателя как показателя повторного умножения, а отрицательного показателя - как обратного значения положительного показателя, поэтому 10 3 равно 10 * 10 * 10 или 1000, и 10 -3 равно 1 / (10 3 ), или 1/1000 или 0,001. Чтобы использовать это определение, я бы снова избежал порезов и сделал что-то вроде этого:
% -----------------------------
% the external/public predicate
% -----------------------------
pow( 0 , 0 , _ ) :- % 0^0 is indeterminate. Is it 1? Is it 0? Could be either.
! ,
fail
.
pow( X , N , R ) :-
N > 0 ,
pow( X , N , 1 , R )
.
pow( X , N , R ) :-
N < 0 ,
N1 = - N ,
pow( X , N1 , 1 , R1 ) ,
R is 1 / R1
.
% -----------------------------------
% The tail-recursive worker predicate
% -----------------------------------
pow( _ , 0 , R , R ).
pow( X , N , T , R ) :-
N > 0 ,
T1 is T * X ,
N1 is N-1 ,
pow( X , N1 , T1 , R )
.