'如果'在序言?
可能是一个愚蠢的问题,但我无法find任何地方的任何文件。 有没有办法做一个如果序言,例如,如果一个variables是0,然后做一些行动(写入文本到terminal)。 别的甚至不需要,但我找不到if的任何实现。
一个标准的序言谓词将做到这一点。
isfive(5).
如果用5调用它,则评估为真,如果用其他任何东西运行,则评估失败(返回错误)。 对于不等于你使用\ =
isNotEqual(A,B):- A\=B.
从技术上讲是不统一的,但是不相似。
学习Prolog现在是学习Prolog的好网站。
编辑:添加另一个例子。
isEqual(A,A).
是的,ISO Prolog中有这样一个控制结构,称为->
。 你这样使用它:
( condition -> then_clause ; else_clause )
这是一个使用else-if-clause链的例子:
( X < 0 -> writeln('X is negative. That's weird! Failing now.'), fail ; X =:= 0 -> writeln('X is zero.') ; writeln('X is positive.') )
请注意,如果您省略else子句,则条件失败将意味着整个if语句将失败。 因此,我build议总是包含else子句(即使它是true
)。
Prolog谓词“统一” –
所以,我会写一个必要的语言
function bazoo(integer foo) { if(foo == 5) doSomething(); else doSomeOtherThing(); }
在Prolog我会写
bazoo(5) :- doSomething. bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
当你理解这两种风格的时候,其实它更清晰。
“如果foo是5,我就是个特例”
“如果foo不是5,我就是正常情况下的bazoo”
我发现这有助于在规则中使用if语句。
max(X,Y,Z): – (X = <Y – > Z = Y; Z = X)。
感谢http://cs.union.edu/~striegnk/learn-prolog-now/html/node89.html
首先,让我们回顾一下经典的一阶逻辑:
“ 如果 P 则 Q 否则 R”等价于“(P 和 Q) 或 (非P 和 R)”。
我们如何在Prolog中expression“if-then-else”?
我们来看下面的具体例子:
如果
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
。
为了以纯粹的方式expression列表(非)成员资格,我们定义:
list_memberd([E | Es],X): - (E = X ; DIF(E,X), list_memberd(ES,X) )。 非会员(Es,X): - MAPLIST(DIF(X),ES)。
让我们来看看在Prolog中expression“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)。 假的 。 %错误 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。 假的 。 %错误 (list_memberd([1,2],X)→X = 2; X = 4),X = 4。 X = 4。 - (list_memberd([1,2],X) - > X = 2; X = 4),X = 4。 假的 。 %错误
正确性得分2/5。 效率得分2/5。
-
(P *-> Q ; R)
- (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 ; 假的 。 - (list_memberd([1,2],X)* - > X = 2; X = 4),X = 2。 X = 2 ; 假的 。 (list_memberd([1,2],X)* - > X = 2; X = 4),X = 4。 X = 4。 - (list_memberd([1,2],X)* - > X = 2; X = 4),X = 4。 假的 。 %错误
正确性得分3/5。 效率得分1/5。
(初步)总结:
-
(P,Q ; non_P,R)
是正确的,但是需要non_P
的离散实现。 -
(P -> Q ; R)
在实例化不足时失去了声明性语义。 -
(P *-> Q ; R)
比(P -> Q ; R)
less“不完整”,但仍然有类似的困境。
幸运的是,对于我们来说,还有其他的select: input逻辑单调控制结构if_/3
!
我们可以使用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
function:
max(X,Y,X):-X>Y,!. max(X,Y,Y):-Y=<X.
我build议阅读更多关于削减的文档,但总的来说,它们就像断点。 例如:如果第一个max
函数返回一个真值,那么第二个函数就不会被validation。
PS:我对Prolog相当陌生,但这是我发现的。
在Prolog中,如何expressionif-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 )
的第一个答案。 其他的答案被砍掉了。 不是很关系,确实如此。
一个更好的结构,通常被称为“软切”(不要相信这个名称,一个切割是一个切割),给出稍微好一点的结果(这是在亚普):
?- ( ( 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.
所以最后的答案仍然被压制。 现在为SICStus , YAP和SWIinputlibrary(reif)
。 安装它并说:
?- 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 for
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程序实际上是“if”与“then”打印“Goal is reached”和“else”打印“没有findsloutions”的“if”的大条件。 A, B
意思是“A是真的,B是真的”,如果“A”不可达(即X=3, write('X is 3'),nl
将会大部分prolog系统不会试图满足“B”当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
IF !
是真的(它总是) AND X
是<= Y