2

Я новичок в Прологе и два требования:Пролог :: е (х) рекурсии

  1. f(1) = 1

  2. f(x) = 5x + x^2 + f(x - 1)

правила:

f(1,1). f(X,Y) :- Y is 5 * X + X * X + f(X-1,Y).

запрос:

f(4,X).

Выход:

ERROR: is/2: Arguments are not sufficiently instantiated

Как я могу добавить значение F (X-1)?

ответ

4

Проблема в том, что вы пытаетесь оценить f (X-1, Y), как если бы это было число, но, конечно, это предикат, который может быть истинным или ложным. Через какое-то мастерить, я нашел это решение:

f(1,1). 
f(X,Y) :- X > 0, Z is X-1, f(Z,N), Y is 5*X + X*X + N. 

Хитрость заключается в том, чтобы позволить ему найти свой путь вниз к f(1,N) первых, без оценки ничего; затем пусть результаты будут возвращены, удовлетворяя Y is 5*X + X*X + N. В Prolog порядок имеет значение для его поиска. Он должен удовлетворять f(Z,N), чтобы иметь значение N для справки Y is 5*X + X*X + N.

Также обратите внимание на условие X > 0, чтобы избежать бесконечной рекурсии.

+0

Спасибо @BallpointBen, но он дает мне ошибку глобального хранения памяти, когда я пытаюсь это решение. Я также думаю, что мой базовый случай был неправильным и изменил его на «f (1, Y): - Y равно 1.» для удовлетворения требования f (1) = 1. – mdo123

+0

Собственно, Prolog может вывести 'Y = 1' на свой собственный. – BallpointBen

+0

, но как насчет ошибки из памяти, любые идеи по исправлению этого @BallpointBen? Или любые источники, которые я могу прочитать, вы можете порекомендовать, чтобы понять? – mdo123

5

Это можно легко решить, используя вспомогательные переменные .

Для примера рассмотрим:

 
f(1, 1). 
f(X, Y) :- 
     Y #= 5*X + X^2 + T1, 
     T2 #= X - 1, 
     f(T2, T1). 

Это прямолинейный перевод правил, которые вы даете, используя вспомогательные переменные T1 и T2, которые стоят за частичные выражения F (X-1) и X-1, соответственно. Поскольку @BallpointBen правильно отмечает, недостаточно использовать сами термины, поскольку эти термины отличаются от их арифметики оценка. В частности, -(2,1) является не целое число   1, но 2 - 1 #= 1 удержание!

В зависимости от системы Prolog, вы можете определяется в настоящее время по-прежнему импортировать библиотеку использовать предикат (#=)/2, выражающий равенство из целочисленных expressesions.

Ваш пример запроса уже сейчас дает решение:

 
?- f(4, X). 
X = 75 . 

Обратите внимание, что предикат делает не прекращать универсально в этом случае:

 
?- f(4, X), false. 
nontermination 

Мы можем легко сделать так, с дополнительным ограничение:

 
f(1, 1). 
f(X, Y) :- 
     X #> 1, 
     Y #= 5*X + X^2 + T1, 
     T2 #= X - 1, 
     f(T2, T1). 

Нет ж мы имеем:

 
?- f(4, X). 
X = 75 ; 
false. 

Обратите внимание, что мы можем использовать это в качестве истинного отношения, а также в наиболее общем случае:

 
?- f(X, Y). 
X = Y, Y = 1 ; 
X = 2, 
Y = 15 ; 
X = 3, 
Y = 39 ; 
X = 4, 
Y = 75 ; 
etc. 

версии основаны на более низком уровне арифметики обычно только крышка очень ограниченное подмножество экземпляров таких запросов. Поэтому я рекомендую вам использовать (#=)/2вместо от (is)/2. Специально для новичков, использование (is)/2 слишком сложно понять. Возьмите много связанных вопросов, поданных под номером   в качестве доказательств, и см. для декларативных решений.

+0

относительно вашего кода, если он вызван в режиме 'f (+, -)', есть ли реализация системы ограничений, позволяющая запускать ее в пространстве стека [O (1)] (https://en.wikipedia.org/wiki/ Tail_call # Tail_recursion_modulo_cons)? –

+0

Поскольку рекурсивный вызов находится в положении хвоста, и при вызове рекурсивной цели не остается никаких точек выбора, это выполняется в O (1) (локальном) пространстве стека во всех реализациях, которые выполняют эту оптимизацию. Например, в SWI-Prolog вы можете это проверить, добавив в начало второго предложения 'f/2' статистику целей (local_stack, L), portray_clause (L) '. Это также выполняется в 'f (+, +)' ​​и * также * в режимах 'f (-, -)'! – mat

+0

Обратите внимание, что накопленные ограничения сохраняются в * глобальном * стеке! Если вы этого не хотите, вы всегда можете изменить порядок целей и иметь те же свойства, что и при арифметике более низкого уровня в отношении потребления памяти. – mat