Оператор if (ветвления) в Prolog

      Комментарии к записи Оператор if (ветвления) в Prolog отключены

В этой теме 1 ответ, 2 участника, последнее обновление  Васильев Владимир Сергеевич 2 года/лет, 1 месяц назад.

  • Автор
    Сообщения
  • #2158

    questioner
    Участник

    Подскажите каким образом на языке Prolog можно реализовать конструкцию if-then-else, традиционную для императивных языков программирования?
    Я не нашел ответа в документации. Если можно, объясните на простых примерах:

    если X = 0 то
      Y = 1;
    иначе
      Y = 2;

  • #2167

    В современном Visual Prolog явно выделен условный оператор, с его помощью Ваш пример мог бы быть записан следующим образом:

    clauses
      if_then_else_example(X, Y):-
        if X < 10 and X > 3 then 
          Y = 1
        else
          Y = 2
        end if.

    Я чуть-чуть изменил пример чтобы показать использование составных условий.

    Все реализации придерживающиеся стандарта ISO Prolog (в том числе SWI Prolog) для этой цели описан специальный оператор
    ( condition -> then_clause ; else_clause ):

    if_then_else_example(X, Y):-
      (X < 10, X > 3 -> Y = 1; Y = 2).

    Помимо этого, может быть использована унификация (сопоставление с образцом) предикатов, т.е. вы можете при написании функций задать значения аргументам — тогда функция начнет выполнение лишь в случае, если заданные значения получится сопоставить с фактическими значениями при вызове:

    unification_example(0, 1):-!.
    unification_example(_X, 2).

    В данном случае первое правило выполнится лишь при X равном нулю, а второе — во всех остальных случаях, т.к. ограничения на значения первого аргумента не накладываются. Пролог будет выполнять поиск функций для сопоставления сверху вниз, т.е. в данном случае он сначала подставит ноль, и если не получится — попробует следующее правило.
    После того, как функция подойдет (удастся сопоставить ее параметры) и значение будет вычислено — вычисление не заканчивается. Если в какой-либо другой функции, использующей полученное значение не получится выполнить сопоставление — то произойдет откат и попытка поиска других решений, поэтому в данном случае важно использовать отсечение (оператор !). В противном случае при нулевом значении первого аргумента функция имела бы два решения.
    Вместо отсечения мы могли бы задать дополнительное условие во второй функции:

    unification_example(0, 1).
    unification_example(X, 2):-
       X =/= 0.

    Оператор =/= означает не равно. Теперь второе правило начнет выполняться в любом случае, вернет решение (Y = 1) лишь при X не равном нулю.

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

    if_then_else_example(X, Y):-
      X < 10, X > 3, !, Y is 1.
    if_then_else_example(X, 2).

    В примере первое правило начинает выполняться всегда, при этом переменные X и Y инициализируются значениями, переданными в функцию. Если сравнения завершатся успешно, то выполнится оператор отсечения и присваивание Y значения единицы. Отсечение не позволит интерпретатору искать другие решения, т.е. перейти на следующую функцию.

    Во всех примерах функции соединялись оператором точка, означающем логическое ИЛИ, поэтому выполнение следующих строк начинается лаже если предыдущие функции завершились неудачно (например не прошла унификация). Операторы внутри функции соединялись оператором запятая, означающим логическое И, поэтому если одна из команд оказалась ложна (например операция сравнения) — то вычислять последующие команды текущей функции нет смысла.

    Наряду с этим, в Prolog доступен оператор точка с запятой, означающий логическое ИЛИ НЕ. Блок команд, следующих за ним начинает выполняться если какая-либо из предыдущих команд вернула false:

    if_then_else_example(X, Y):-
      X < 10, X > 3, !, Y is 1; Y is 2.

    В данном случае, операции сравнения переменной X, отсечение и присваивание единицы второму аргументу представляют собой первый блок команд. Если какая-либо из них завершится неудачей — управление будет передано на второй блок, выполняющий присваивание Y значения 2.

    В примерах я использовал оператор is для проверки равенства значений и присваивания, в Turbo Prolog и Visual Prolog вместо этого можно применить оператор присваивания (=).

Для ответа в этой теме необходимо авторизоваться.