Если вы намереваетесь определить 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)
для каждой оценки, вы можете разместить вырезку (!
), если ваша реализация поддерживает это, сразу после em > c
подзадача в первом пункте. Вырезка помещается после c
, потому что мы не хотим, чтобы интерпретатор выполнял этот выбор предложения f(A,X)
, если c
потерпел неудачу, вместо этого мы хотим, чтобы интерпретатор вышел из этого предложения и попробовал следующий, чтобы эффективно игнорировать c
и продолжить обработку g(X)
.
Также обратите внимание, что это решение полагается на a
и b
, не имеющее побочных эффектов, потому что при сбое c
a
и b
выполняются снова. Если все a
, b
и c
имеют побочные эффекты, вы можете попробовать использовать импликацию:
f(A,X) :- a, b, (c -> g(X) ; g(X)).
Это также будет эффективно всегда выполнять g(X)
независимо от c
сбоя или нет, и не будет выполнять a
и b
снова, если c
завершится сбоем. Это определение с одним предложением также не оставит точки выбора, как предыдущее предложение.
person
Community
schedule
06.11.2010