'如果'在序言?

可能是一个愚蠢的问题,但我无法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”)如果…

  • 条件Plist_member([1,2],X)
  • 否定条件non_Pnon_member([1,2],X)
  • 结果QX=2 ,并且
  • 替代RX=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”的不同方式!

  1. (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。

  2. (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。

  3. (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。


(初步)总结:

  1. (P,Q ; non_P,R)是正确的,但是需要non_P的离散实现。

  2. (P -> Q ; R)在实例化不足时失去了声明性语义。

  3. (P *-> Q ; R)(P -> Q ; R)less“不完整”,但仍然有类似的困境。


幸运的是,对于我们来说,还有其他的select: input逻辑单调控制结构if_/3

我们可以使用if_/3if_/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. 

以上是条件函数的基本结构。

举例来说,这里是maxfunction:

 max(X,Y,X):-X>Y,!. max(X,Y,Y):-Y=<X. 

我build议阅读更多关于削减的文档,但总的来说,它们就像断点。 例如:如果第一个max函数返回一个真值,那么第二个函数就不会被validation。

PS:我对Prolog相当陌生,但这是我发现的。

在Prolog中,如何expressionif-then-else之类的东西基本上有三种不同的方式。 比较他们考虑char_class/2 。 对于ab类,应该是abother所有其他术语。 人们可以这样笨拙地写:

 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