«Если» в прологе?
-
27-09-2019 - |
Вопрос
Есть ли способ сделать, если в прологе, например, если переменная составляет 0, то делать некоторые действия (напишите текст на терминал). Еще не нужно даже не нужно, но я не могу найти какую-либо документацию, если.
Решение
Стандартный проловый предикат сделает это.
isfive(5).
Оцените true, если вы назовете его с 5 и не ударуетесь (возвращайте false), если вы запустите его с чем-либо еще. Для не равных вы используете =
isNotEqual(A,B):- A\=B.
Технически это не унифицирует, но оно похоже на не равно.
Узнайте пролог сейчас - хороший сайт для обучения пролога.
Редактировать: Чтобы добавить другой пример.
isEqual(A,A).
Другие советы
Да, есть такая конструкция в прологе ISO, называется ->
. Отказ Вы используете это так:
( condition -> then_clause ; else_clause )
Вот пример, который использует цепочку остальных - IF-пункты:
( X < 0 ->
writeln('X is negative. That's weird! Failing now.'),
fail
; X =:= 0 ->
writeln('X is zero.')
; writeln('X is positive.')
)
Обратите внимание, что если вы пропустите пункт остального предложения, недостаток условия будет означать, что целое IF-оператор не удастся. Следовательно, я рекомендую всегда включать остальное предложение (даже если это просто true
).
Пролог предикатов «унифицировать» -
Итак, в императивном Langauge я пишу
function bazoo(integer foo)
{
if(foo == 5)
doSomething();
else
doSomeOtherThing();
}
В прологе я пишу
bazoo(5) :- doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
Что, когда вы понимаете оба стиля, на самом деле намного понятнее.
«Я Bazoo для особого случая, когда Foo 5»
«Я Bazoo для нормального случая, когда Foo не 5»
Я нашел это полезным для использования если заявление в правиле.
max(X,Y,Z) :-
( X =< Y
-> Z = Y
; Z = X
).
Благодаря http://cs.union.edu/~striegnk/learn-Prolog-now/html/node89.html.
Во-первых, давайте вспомним какую-то классическую логику первого порядка:
"Если п тогда Q. еще R "эквивалентен" (p а также Q) или (Non_P. а также Р)".
Как мы можем выразить «если-тогда», как это в прологе?
Давайте возьмем следующий конкретный пример:
Если
X
является членом списка[1,2]
тогдаX
равняться2
ещеX
равняться4
.
Мы можем сопоставить выше шаблона (»Если п тогда Q. еще 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).
Давайте проверим разные способы выражения «если-тогда-ж» в прологе!
(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 ; ложный. ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2. X = 2 ; ложный. ?- 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). ложный. % 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. ложный. % 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. ложный. % WRONG
Оценка правильности 2/5. Оценка эффективности 2/5.
(P *-> Q ; R)
?- (list_memberd([1,2],X) *-> X=2 ; X=4). X = 2 ; ложный. % 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. X = 2 ; ложный. ?- 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. ложный. % 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
Вместе с предикатом членства из списка memberd_t/3
вот так:
? - if_ (melld_t (x, [1,2]), x = 2, x = 4). Х = 2; X = 4.? - x = 2, if_ (memberd_t (x, [2]), x = 2, x = 4), x = 2. X = 2.? - if_ (melld_t (x, [2]), x = 2, x = 4), x = 2. Х = 2. ; ложныйОтказ - x = 4, if_ (melld_t (x, [1,2]), x = 2, x = 4), x = 4. X = 4.? - if_ (melld_t (x, [1,2]), x = 2, x = 4), x = 4. Х = 4.
Оценка правильности 5/5. Оценка эффективности 4/5.
Лучшее, что нужно сделать, это использовать так называемый 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: Я довольно новичок в прологе, но это то, что я узнал.
Есть по существу три разных способа, как выразить что-то вроде, если бы, а затем-другое в прологе. Сравнить их рассмотреть 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).
Для того, чтобы писать вещи более компактно, если требуется конструкция, если необходимо. Пролог имеет встроенный:
?- ( ( 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.
В качестве альтернативы, Сиктус имеет if/3
С очень похожей семантикой:
?- if( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
Ch = a, Class = ab
; Ch = b, Class = ab.
Таким образом, последний ответ все еще подавлен. Теперь введите library(reif)
для Sicstus., Ума, а также Потрясающий. Отказ Установите его и скажите:
?- 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
скомпилирован в дико вложенный, если бы тогда и остальное для
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
)
).
Программа Prolog на самом деле является большим условием для «если», то «тогда», что «отпечатки» достигнута «и« иначе », которые печатаются« никаких шлангов ». A, B
Средства «A верно и B - это правда», большинство систем проловых не пытаются удовлетворить «B», если «A» не доступен (т.е. X=3, write('X is 3'),nl
Будет печатать 'x - 3', когда x = 3, и ничего не сделает, если x = 2).
( A == B ->
writeln("ok")
;
writeln("nok")
),
Остальная часть требуется
Вы должны прочитать Узнайте пролог сейчас! Глава 10.2 Использование разреза. Отказ Это дает пример:
max(X,Y,Z) :- X =< Y,!, Y = Z.
Быть сказанным,
Z
равно Y
ЕСЛИ !
правда (что это всегда) А ТАКЖЕ X
является <= Y
.