在Prolog中有一种方法可以使用if语句,例如如果一个变量为0,则执行某些操作(向终端输出文本)。不需要else,但我找不到任何if的文档。
在Prolog中有一种方法可以使用if语句,例如如果一个变量为0,则执行某些操作(向终端输出文本)。不需要else,但我找不到任何if的文档。
是的,在ISO Prolog中有这样一种控制结构,称为->
。你可以像这样使用它:
( condition -> then_clause ; else_clause )
这是一个使用else-if语句链的示例:
( X < 0 ->
writeln('X is negative. That's weird! Failing now.'),
fail
; X =:= 0 ->
writeln('X is zero.')
; writeln('X is positive.')
)
请注意,如果省略 else 子句,则条件失败将意味着整个 if 语句也将失败。因此,我建议始终包括 else 子句(即使只是 true
)。
(if->then;else) == ((if->then);else)
成立。 - false一个标准的Prolog谓词可以实现这个功能。
isfive(5).
如果您使用 5 调用它,它将评估为 true,并在使用其他任何内容运行时失败(返回 false)。对于不相等,您可以使用 \=。
isNotEqual(A,B):- A\=B.
严格来说它并不是统一的,但它类似于不等于。
Learn Prolog Now 是一个很好的学习 Prolog 的网站。
编辑: 再添加一个例子。
isEqual(A,A).
Prolog谓词的“统一” -
因此,在命令式语言中,我会写
function bazoo(integer foo)
{
if(foo == 5)
doSomething();
else
doSomeOtherThing();
}
在Prolog中,我会这样写
bazoo(5) :- doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
了解两种风格之后,实际上会更清晰易懂。
“当foo为5的特殊情况,我是bazoo”
“当foo不为5的正常情况,我是bazoo”
bazoo(5+0)
会默默失败,而 bazoo(5+1)
则会执行其他操作。 - falseFoo is 5
。 - Pro Qdif(Foo, 5)
。 - false首先,让我们回顾一些经典的一阶逻辑:
“如果 P 那么 Q,否则 R”等价于“(P 且 Q) 或 (非_P 且 R)”。
让我们以以下具体示例为例:
如果
X
是列表[1,2]
的成员,则 那么X
等于2
,否则X
等于4
。
我们可以匹配上述模式(“如果 P 那么 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) ).让我们来看一下在Prolog中表达“if-then-else”的不同方法!
(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。 % 错误 ?- 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。 % 错误 ?- 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。 % 错误
正确性得分2/5。效率得分2/5。
(P *-> Q ; R)
?- (list_memberd([1,2],X) *-> X=2 ; X=4)。 X = 2 或 false。 % 错误 ?- 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。 % 错误
正确性得分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_(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。
我发现这对于在规则中使用if语句非常有帮助。
max(X,Y,Z) :-
( X =< Y
-> Z = Y
; Z = X
).
感谢http://cs.union.edu/~striegnk/learn-prolog-now/html/node89.html
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 )
。其他答案被切除了。确实不太关联。?- ( ( 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)
,适用于Scryer、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
)
).
最好的方法是使用所谓的cuts
,这个符号是!
。
if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.
if_then_else(Condition, Action1, Action2) :- Action2.
max(X,Y,X):-X>Y,!.
max(X,Y,Y):-Y=<X.
max
函数返回一个true(真)值,第二个函数就不会被验证。那个
max(X,Y,X):-X>Y,!. 在剪切之后应该设置第三个参数为steadfast - https://dev59.com/5lkT5IYBdhLWcg3wAK_w
- brebs( A == B ->
writeln("ok")
;
writeln("nok")
),
Prolog程序实际上是一个带有“if”和“then”的大条件语句,它会打印“目标已达成”,并且还有一个“else”语句,它会打印“找不到解决方案”。A,B
表示“A为真且B为真”,大多数Prolog系统将不会尝试满足“B”,如果“A”无法到达(即X=3,write('X is 3'),nl
将在X=3时打印“X是3”,如果X=2,则什么也不会发生)。
if-then-else
语法,但实际使用时它并不具备声明性。 - Willem Van OnsemmyFunc(Variable) :- Variable=0,print('OK, here is your text.').
- Topological Sort