如果在prolog中?

jre*_*001 51 prolog iso-prolog logical-purity

可能是一个愚蠢的问题,但我无法在任何地方找到任何文档.有没有办法在prolog中执行if,例如,如果变量为0,则执行某些操作(将文本写入终端).甚至不需要else,但我找不到if的任何实现.

Mat*_*ard 85

是的,在ISO Prolog中有这样的控制结构,称为->.你这样使用它:

( condition -> then_clause ; else_clause )
Run Code Online (Sandbox Code Playgroud)

这是一个使用else-if-clauses链的示例:

(   X < 0 ->
    writeln('X is negative.  That's weird!  Failing now.'),
    fail
;   X =:= 0 ->
    writeln('X is zero.')
;   writeln('X is positive.')
)
Run Code Online (Sandbox Code Playgroud)

请注意,如果省略else子句,则条件失败将意味着整个if语句将失败.因此,我建议始终包含else子句(即使它只是true).

  • 在ISO中,控件构造实际上被称为(;)/ 2 - if-then-else(7.8.8),因为主要的算符是(;)/ 2.这有点刺激,因为有另一个控件构造具有相同的主函子:(;)/ 2 - 析取(7.8.6).你可以看到它像`(if-> then; else)==((if-> then); else).`成功. (14认同)

sto*_*tal 50

标准的prolog谓词将会这样做.

   isfive(5). 
Run Code Online (Sandbox Code Playgroud)

如果你用5调用它将评估为true并且如果你用其他任何东西运行它将失败(返回false).如果不相等,则使用\ =

isNotEqual(A,B):- A\=B.
Run Code Online (Sandbox Code Playgroud)

从技术上讲,它不是统一的,但它类似于不相等.

Learn Prolog Now是一个很好的学习prolog的网站.

编辑:添加另一个示例.

isEqual(A,A). 
Run Code Online (Sandbox Code Playgroud)

  • +1用于执行逻辑编程风格而不是命令式:-) (7认同)

Ann*_*poo 26

Prolog谓词'统一' -

所以,在一个必要的语言中我会写

function bazoo(integer foo)
{
   if(foo == 5)
       doSomething();
   else
       doSomeOtherThing();
}
Run Code Online (Sandbox Code Playgroud)

在Prolog我会写

bazoo(5) :-  doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
Run Code Online (Sandbox Code Playgroud)

当你理解这两种风格时,它实际上更加清晰.
"当foo为5时,我就是特殊情况下的bazoo"
"当foo不是5时我正常情况下是bazoo

  • `bazoo(5 + 0)`无声地失败,而'bazoo(5 + 1)`做了其他事情 (4认同)
  • @ProQ:那将是'dif(Foo,5)` (2认同)

Tom*_*ard 12

我发现这对在规则中使用if语句很有帮助.

max(X,Y,Z) :-
    (  X =< Y
    -> Z = Y
    ;  Z = X
    ).
Run Code Online (Sandbox Code Playgroud)

感谢http://cs.union.edu/~striegnk/learn-prolog-now/html/node89.html


rep*_*eat 9

首先,让我们回顾一些经典的一阶逻辑:

" 如果 P Q 否则 R"等同于"(P Q)(non_P R)".


我们怎样才能表达"IF-THEN-ELSE"就像在Prolog的?

我们来看下面的具体例子:

如果 X是list的成员,[1,2] 那么 X equals 2 else X等于4.

如果... 我们可以匹配上面的模式(" 如果 P 然后 Q 其他 R")

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

  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 ; 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.

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

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


(初步)摘要:

  1. (P,Q ; non_P,R)是正确的,但需要一个独立的实现non_P.

  2. (P -> Q ; R) 实例化不足时会丢失声明性语义.

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


ski*_*per 5

最好的办法是使用所谓cuts的符号!.

if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.  
if_then_else(Condition, Action1, Action2) :- Action2.
Run Code Online (Sandbox Code Playgroud)

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

举例来说,这是max函数:

max(X,Y,X):-X>Y,!.  
max(X,Y,Y):-Y=<X.
Run Code Online (Sandbox Code Playgroud)

我建议阅读更多关于剪辑的文档,但总的来说它们就像断点.例如:如果第一个max函数返回一个真值,则不验证第二个函数.

PS:我对Prolog很新,但这是我发现的.

  • @ gaurav.singharoy:什么是"冷盘"?事实上,对于Prolog来说. (5认同)

fal*_*lse 5

在Prolog中,如何表达if-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).
Run Code Online (Sandbox Code Playgroud)

为了更紧凑地编写东西,需要一个if-then-else结构.Prolog有一个内置的:

?- ( ( Ch = a ; Ch = b ) -> Class = ab ; Class = other ).
   Ch = a, Class = ab.
Run Code Online (Sandbox Code Playgroud)

虽然这个答案是合理的,但它并不完整.刚刚给出了第一个答案( Ch = a ; Ch = b ).其他答案被砍掉了.确实不是很关系.

一个更好的结构,通常被称为"软切"(不相信的名字,切割是切是切),给出稍好的结果(这是YAP):

?- ( ( Ch = a ; Ch = b ) *-> Class = ab ; Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.
Run Code Online (Sandbox Code Playgroud)

或者,SICStus具有if/3非常相似的语义:

?- if( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.
Run Code Online (Sandbox Code Playgroud)

所以最后的答案仍然被压制.现在进入library(reif)SICStus,YAPSWI.安装它并说:

?- 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).
Run Code Online (Sandbox Code Playgroud)

请注意,所有这些都if_/3被编译为一个非常嵌套的if-then-else for

char_class(Ch, Class) :-
   if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
Run Code Online (Sandbox Code Playgroud)

在第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
     )
   ).
Run Code Online (Sandbox Code Playgroud)