题
有没有办法在序言中执行 if 操作,例如如果变量为 0,则执行一些操作(将文本写入终端)。甚至不需要 else,但我找不到 if 的任何文档。
解决方案
一个标准序言谓词将做到这一点。
isfive(5).
将评估为true,如果你用5调用它,失败(返回false),如果你有别的运行它。对于不等于使用\ =
isNotEqual(A,B):- A\=B.
技术上讲,它是不统一的,但它类似于不相等。
编辑: 要添加另一个例子。
isEqual(A,A).
其他提示
是,有在ISO的Prolog这样的对照构建体,称为->
。您可以使用这样的:
( 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.')
)
请注意,如果你省略else从句,失败的条件将意味着整个if语句将失败。因此,我建议始终包括else从句(哪怕只是true
)。
的Prolog谓词 '统一' -
因此,在一个必要的langauge我会写
function bazoo(integer foo)
{
if(foo == 5)
doSomething();
else
doSomeOtherThing();
}
在的Prolog我会写
bazoo(5) :- doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
里面,当你明白这两种风格,实际上是一个更加清晰。结果 “我的特殊情况时,鼻foo是5”结果 “我的正常情况下,当鼻foo是不是5”
我发现这有助于在规则中使用如果语句。
max(X,Y,Z) :-
( X =< Y
-> Z = Y
; Z = X
).
由于 HTTP://cs.union。 EDU /〜striegnk /学习-序言-现在/ HTML / node89.html
首先,让我们回顾一些经典的一阶逻辑:
"如果 磷 然后 问 别的 R”等价于“(P 和 问) 或者 (非_P 和 R)”。
我们如何表达“if-then-else” 那 在序言中?
我们来看下面的具体例子:
如果
X
是列表的成员[1,2]
然后X
等于2
别的X
等于4
.
我们可以匹配上面的模式(“如果 磷 然后 问 别的 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).
让我们看看在 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 ;错误的. ?- (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_(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 ;错误的. ?- 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。
做的最好的办法是使用所谓的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的,但是这是我发现了
。在 Prolog 中表达 if-then-else 之类的内容本质上有三种不同的方式。为了比较它们考虑 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 结构。Prolog 有一个内置的:
?- ( ( 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, 亚普, , 和 苏维埃. 。安装它并说:
?- 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
)
).
Prolog程序实际上是版画“达到目标”为“如果”有“那么”大条件和“其他”的版画“没有sloutions被发现”。 A, B
means“一个是真实的,B是真实的”,多数序言系统不会试图满足“B”,如果“A”是不可达(即X=3, write('X is 3'),nl
将打印“X 3”当X = 3,如果不会做任何事情X = 2)。
( A == B ->
writeln("ok")
;
writeln("nok")
),
在其他部分是必需的
您应该阅读了解现在的Prolog!章10.2使用单。这提供了一个示例:
max(X,Y,Z) :- X =< Y,!, Y = Z.
必须指出,
Z
等于Y
如果强> !
为真(它总是)和强> X
是<= Y
。