Если вы намерены определить f(A,X)
таким образом, чтобы g(X)
оценивалось независимо от того, не удастся ли c
, то либо:
- Вы можете закодировать это с помощью импликации (
->
) и / или дизъюнкции (;
), или
f(A,X)
не нужно определять в терминах c
. Предполагается, что c
не имеет побочных эффектов (например, утверждение фактов базы данных с использованием assert
или печать ввода-вывода в поток), которые изменяют среду и не могут быть отменены при сбое c
, в этом случае первый вариант предпочтительнее.
Существует несколько вариантов использования дизъюнкции, например:
f(A,X) :- ((a, b, c) ; (a, b)), g(X).
Это определение (выше) совсем не зависит от c
, но оно всегда будет исполнять c
(до тех пор, пока a
и b
будут успешными). Разъединение (;
) позволяет PROLOG вернуться назад, чтобы попытаться выполнить a, b
снова , если c
вообще не удалось, и продолжить на g(X)
. Обратите внимание, что это эквивалентно:
f(A,X) :- a, b, c, g(X).
f(A,X) :- a, b, g(X).
Чтобы PROLOG не возвращался назад для оценки f(A,X)
дважды из-за второго (идентичного) предиката головы f(A,X)
для каждой оценки, вы можете выбрать сокращение (!
), если ваша реализация его поддерживает , сразу после подцела c
в первом предложении. Разрез ставится после c
, потому что мы не хотим, чтобы интерпретатор подтвердил этот выбор условия f(A,X)
, если c
потерпел неудачу, вместо этого мы хотим, чтобы интерпретатор вышел из этого и попробовать следующий, чтобы эффективно игнорировать c
и продолжить обработку g(X)
.
Также обратите внимание, что это решение основано на a
и b
, не имеющих побочных эффектов, потому что, когда c
не удается, a
и b
выполняются снова. Если у всех a
, b
и c
есть побочные эффекты, вы можете попробовать использовать implication :
f(A,X) :- a, b, (c -> g(X) ; g(X)).
Это также будет эффективно всегда выполнять g(X)
независимо от того, произойдет сбой c
или нет, и не будет выполнять a
и b
снова, если произойдет сбой c
. Это определение с одним предложением также не оставит точку выбора, как предыдущее предложение.