#prolog
Вопрос:
Я пытаюсь придумать запрос в Прологе, где я спрашиваю, есть ли значение, где x^2=25. Но я хочу, чтобы он возвращался yes
только в том случае, если в базе знаний есть только один случай, когда x^2 равно 25.
У меня есть это в моей базе знаний:
squared(5,25)
squared((-5),25)
Я хочу, чтобы программа вернулась no
, потому что есть два ответа x
, где x^2=25, когда мне нужен только один.
До сих пор у меня есть это:
squared(x,25),squared(x,25), x=x.
Комментарии:
1. То, что у вас внизу, что оно делает?
Ответ №1:
Вы можете использовать forall/2
следующее:
squared(X, 25), forall(squared(Y, 25), X = Y).
Этот запрос выполняется успешно только в том случае, если все решения squared(X, 25)
имеют одинаковое значение.
Чтобы немного уточнить:
squared(X, 25), % we have a single solution, X
forall(squared(Y, 25), X = Y). % we are asserting all solutions are equal to X
Если вы не знакомы с forall/2
:
forall(Condition, Action)
преуспевает, если для всех альтернативных привязок Условия Действие может быть доказано. Это эквивалентно(Condition, Action)
.
Таким образом, это работает для предикатов, которые имеют корни с множественностью > 1
(это может быть не то, что вы хотите, и в этом случае findall
может помочь). Следующее гарантирует, что у вас есть ровно один корень:
findall(X, squared(X, 25), [_]).
Давайте рассмотрим пример X^2 = 0
, который имеет двойной корень в 0:
squared(0, 0).
squared(0, 0).
Так что у вас будет:
|?- findall(X, squared(X, 0), [_]). % check for exactly one root
no
|?- squared(X, 0), forall(squared(Y, 0), X = Y). % same root with any multiplicity
X = 0 ?
yes
Также переменные в прологе начинаются с заглавных букв (или _).
ИЗМЕНИТЬ: более оптимальный поиск
squared(X, 25), !, forall(squared(Y, 25), X = Y).
Разрез после squared(X, 25)
гарантирует, что мы пройдем через все корни только один раз. Если forall
итерация завершается неудачно, то существует Y
с squared(Y, 25)
и Y = X
. Поэтому нам не нужно проверять наличие каких — либо различий X
.
Комментарии:
1. @DavidTonhofer : Да, нужен разрез. Иначе, если у нас будут
n
неравные корни, аO(n)
не у нас будутO(n^2)
.2. Большое вам спасибо, это очень помогло!! Кстати, вы знаете другой способ, которым я мог бы решить эту проблему, не меняя базу знаний.
3. Как изменяется база знаний? Это все еще
squared(5, 25). squared(-5, 25).
так . Я только предоставил запросsquared(X, 25), forall(squared(Y, 25), X = Y).