Вопрос

Почему это работает:

   power(_,0,1) :- !.
   power(X,Y,Z) :-
      Y1 is Y - 1,
      power(X,Y1,Z1),
      Z is X * Z1.

И это приводит к исключению переполнения стека?

power(_,0,1) :- !.
power(X,Y,Z) :-
  power(X,Y - 1,Z1),
  Z is X * Z1.
Это было полезно?

Решение

Поскольку арифметические операции выполняются только над предложениями через is оператор.В вашем первом примере Y1 привязан к результату вычисления Y - 1.В более позднем случае система пытается доказать степень предложения (X, Y - 1, Z1), которая объединяется со степенью (X', Y', Z'), связывающей X' = X, Y' = Y - 1, Z' = Z.Затем это повторяется снова, так что Y" = Y - 1 - 1 и т.д. для бесконечности, фактически никогда не выполняя вычисление.

Prolog - это в первую очередь просто унификация терминов - вычисление в "обычном" смысле должно запрашиваться явно.

Другие советы

Оба определения не работают должным образом.

Рассмотреть

?- pow(1, 1, 2).

который выполняет цикл для обоих определений, потому что второе предложение может быть применено независимо от второго аргумента.Сокращение в первом предложении не может отменить это.Во втором пункте нужна цель Y > 0 перед рекурсивной целью.Используя (is)/2 по-прежнему это хорошая идея для получения реальных решений.

Лучше всего (для начинающих) начать с или и избегать в целом.

Смотрите , например ,: Предикат Prolog - бесконечный цикл

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top