Подтвердить что ты не робот

'if' в прологе?

Есть ли способ сделать if в прологе, например, если переменная равна 0, затем выполнить некоторые действия (записать текст в терминал). Иное даже не нужно, но я не могу найти документацию, если.

4b9b3361

Ответ 1

Стандартный прологовый предикат сделает это.

   isfive(5). 

будет оценивать значение true, если вы вызываете его с 5 и не выполняете (возвращаете false), если вы запускаете его с чем-либо еще. Для не равных вы используете \=

isNotEqual(A,B):- A\=B.

Технически это не унифицируется, но похоже не равно.

Learn Prolog Now - хороший веб-сайт для изучения пролога.

Изменить: Чтобы добавить еще один пример.

isEqual(A,A). 

Ответ 2

Да, в ISO Prolog есть такая конструкция управления, называемая ->. Вы используете его следующим образом:

( condition -> then_clause ; else_clause )

Вот пример, который использует цепочку else-if-clauses:

(   X < 0 ->
    writeln('X is negative.  That weird!  Failing now.'),
    fail
;   X =:= 0 ->
    writeln('X is zero.')
;   writeln('X is positive.')
)

Обратите внимание, что если вы опускаете else-предложение, условие failing будет означать, что весь if-statement завершится с ошибкой. Поэтому я рекомендую всегда включать else-clause (даже если это просто true).

Ответ 3

Пролог предикаты 'unify' -

Итак, в обязательном langauge я бы написал

function bazoo(integer foo)
{
   if(foo == 5)
       doSomething();
   else
       doSomeOtherThing();
}

В Prolog я напишу

bazoo(5) :-  doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.

который, когда вы понимаете оба стиля, на самом деле намного яснее.
"Я базу для особого случая, когда foo - 5"
"Я базу для нормального случая, когда foo не 5"

Ответ 5

Во-первых, вспомним некоторую классическую логику первого порядка:

"Если P, то Q else R" эквивалентно "(P и Q) или (non_P и R)".


Как мы можем выразить "if-then-else", как в Prolog?

Возьмем следующий конкретный пример:

Если X является членом списка [1,2], то X равно 2 else X равно 4.

Мы можем сопоставить шаблон выше ( "Если P, а затем Q else R" ), если...

  • условие P - list_member([1,2],X),
  • отрицательное условие non_P - non_member([1,2],X),
  • Последствия Q - X=2 и
  • Альтернативный R - X=4.

Чтобы выразить список (не) членство в чистом виде, определим:

list_memberd([E|Es],X) :-
   (  E = X
   ;  dif(E,X),
      list_memberd(Es,X)
   ).

non_member(Es,X) :-
   maplist(dif(X),Es).

Позвольте проверить различные способы выражения "if-then-else" в Prolog!

  • (P,Q ; non_P,R)

    ?-      (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4).
    X = 2 ; X = 4.
    ?- X=2, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2.
    X = 2 ; false.
    ?-      (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2.
    X = 2 ; false.
    ?- X=4, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4.
    X = 4.
    ?-      (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4.
    X = 4.
    

    Правильность оценки 5/5. Оценка эффективности 3/5.

  • (P -> Q ; R)

    ?-      (list_memberd([1,2],X) -> X=2 ; X=4).
    false.                                                % WRONG
    ?- X=2, (list_memberd([1,2],X) -> X=2 ; X=4), X=2.
    X = 2.
    ?-      (list_memberd([1,2],X) -> X=2 ; X=4), X=2.
    false.                                                % WRONG
    ?- X=4, (list_memberd([1,2],X) -> X=2 ; X=4), X=4.
    X = 4.
    ?-      (list_memberd([1,2],X) -> X=2 ; X=4), X=4.
    false.                                                % WRONG
    

    Правильность оценки 2/5. Оценка эффективности 2/5.

  • (P *-> Q ; R)

    ?-      (list_memberd([1,2],X) *-> X=2 ; X=4).
    X = 2 ; false.                                        % WRONG
    ?- X=2, (list_memberd([1,2],X) *-> X=2 ; X=4), X=2.
    X = 2 ; false.
    ?-      (list_memberd([1,2],X) *-> X=2 ; X=4), X=2.
    X = 2 ; false.
    ?- X=4, (list_memberd([1,2],X) *-> X=2 ; X=4), X=4.
    X = 4.
    ?-      (list_memberd([1,2],X) *-> X=2 ; X=4), X=4.
    false.                                                % WRONG
    

    Правильность оценки 3/5. Оценка эффективности 1/5.


(Предварительный):

  • (P,Q ; non_P,R) является правильным, но для него требуется дискретная реализация non_P.

  • (P -> Q ; R) теряет декларативную семантику при недостаточности экземпляра.

  • (P *-> Q ; R) является "менее" неполным, чем (P -> Q ; R), но все еще имеет схожие проблемы.


К счастью для нас есть альтернативы: Введите логически монотонную конструкцию управления if_/3!

Мы можем использовать if_/3 вместе с предикатом reified list-membership memberd_t/3, таким образом

?-      if_(memberd_t(X,[1,2]), X=2, X=4).
X = 2 ; X = 4.
?- X=2, if_(memberd_t(X,[1,2]), X=2, X=4), X=2.
X = 2.
?-      if_(memberd_t(X,[1,2]), X=2, X=4), X=2.
X = 2 ; false.
?- X=4, if_(memberd_t(X,[1,2]), X=2, X=4), X=4.
X = 4.
?-      if_(memberd_t(X,[1,2]), X=2, X=4), X=4.
X = 4.

Правильность оценки 5/5. Оценка эффективности 4/5.

Ответ 6

Лучше всего использовать так называемый cuts, который имеет символ !.

if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.  
if_then_else(Condition, Action1, Action2) :- Action2.

Выше была основная структура функции условия.

Чтобы проиллюстрировать здесь, функция max:

max(X,Y,X):-X>Y,!.  
max(X,Y,Y):-Y=<X.

Я предлагаю читать дополнительную документацию по разрезам, но в целом они похожи на точки останова. Пример. Если первая функция max возвращает истинное значение, вторая функция не проверяется.

PS: Я новичок в Prolog, но это то, что я узнал.

Ответ 7

Существуют три разных способа, как выразить что-то вроде if-then-else в Prolog. Для их сравнения рассмотрим char_class/2. Для a и b класс должен быть ab и other для всех остальных членов. Можно было бы так неудобно написать:

char_class(a, ab).
char_class(b, ab).
char_class(X, other) :-
   dif(X, a),
   dif(X, b).

?- char_class(Ch, Class).
   Ch = a, Class = ab
;  Ch = b, Class = ab
;  Class = other,
   dif(Ch, a), dif(Ch, b).

Чтобы записать вещи более компактно, нужна конструкция if-then-else. Пролог имеет встроенный модуль:

?- ( ( Ch = a ; Ch = b ) -> Class = ab ; Class = other ).
   Ch = a, Class = ab.

Хотя этот ответ звучит, он неполный. Дается только первый ответ из ( Ch = a ; Ch = b ). Другие ответы отрублены. Не очень реляционные, действительно.

Лучшая конструкция, которую часто называют "мягким разрезом" (не верьте названию, разрез - это разрез), дает несколько лучшие результаты (это в YAP):

?- ( ( Ch = a ; Ch = b ) *-> Class = ab ; Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.

В качестве альтернативы, SICStus имеет if/3 с очень сходной семантикой:

?- if( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.

Итак, последний ответ все еще подавлен. Теперь введите library(reif) для SICStus, YAP, и SWI. Установите его и скажите:

?- use_module(library(reif)).

?- if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab
;  Class = other,
   dif(Ch, a), dif(Ch, b).

Обратите внимание, что все if_/3 скомпилированы в дико вложенное if-then-else для

char_class(Ch, Class) :-
   if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).

который расширяется в YAP 6.3.4 до:

char_class(A,B) :-
   ( A\=a
   ->
     ( A\=b
     ->
       B=other
     ;
       ( A==b
       ->
         B=ab
       )
     ;
       A=b,
       B=ab
     ;
       dif(A,b),
       B=other
     )
   ;
     ( A==a
     ->
       B=ab
     )
   ;
     A=a,
     B=ab
   ;
     dif(A,a),
     ( A\=b
     ->
       B=other
     ;
       ( A==b
       ->
         B=ab
       )
     ;
       A=b,
       B=ab
     ;
       dif(A,b),
       B=other
     )
   ).

Ответ 8

Программа Prolog на самом деле является большим условием для "if" с "then", который печатает "Цель достигнута" и "else", которая печатает "Нет sloutions". A, B означает, что "A истинно и B истинно", большинство прологовых систем не будут пытаться удовлетворить "B", если "A" недоступно (т.е. X=3, write('X is 3'),nl будет печатать "X равно 3", когда X = 3, и ничего не сделает, если X = 2).

Ответ 9

(  A == B ->
     writeln("ok")
;
     writeln("nok")
),

Требуется часть else