Есть ли способ сделать if в прологе, например, если переменная равна 0, затем выполнить некоторые действия (записать текст в терминал). Иное даже не нужно, но я не могу найти документацию, если.
'if' в прологе?
Ответ 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"
Ответ 4
Я нашел это полезным для использования оператора if в правиле.
max(X,Y,Z) :-
( X =< Y
-> Z = Y
; Z = X
).
Благодаря http://cs.union.edu/~striegnk/learn-prolog-now/html/node89.html
Ответ 5
Во-первых, вспомним некоторую классическую логику первого порядка:
"Если P, то Q else R" эквивалентно "(P и Q) или (non_P и R)".
Как мы можем выразить "if-then-else", как в Prolog?
Возьмем следующий конкретный пример:
Если
X
является членом списка[1,2]
, тоX
равно2
elseX
равно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
Ответ 10
Вы должны прочитать Learn Prolog Now! Глава 10.2 Использование обрезки. Это дает пример:
max(X,Y,Z) :- X =< Y,!, Y = Z.
Z
равно Y
IF !
истинно (что всегда) И X
есть <= Y
.