2017-11-11 137 views
1

我试图在GNU Prolog中使用->运算符,但是我在变量作用域中遇到了一些麻烦。这里有一个例子:在Prolog中if/else的变量范围

example(A) :- 
    B = A, 
    (B == 2 -> write(B), write(' is 2'), nl); 
    (write(B), write(' is not 2'), nl). 

在序言控制台:

| ?- example(2). 
2 is 2 

true ? 

yes 
| ?- example(3). 
_282 is not 2 

yes 

当我查询example(2)B == 2成功和前导知道B的值,从而打印出2 is 2。另一方面,当我查询example(3)B == 2失败,并由于某种原因,Prolog不知道B的值,因此打印出一些变量_282。我很困惑,为什么Prolog只有在B == 2成功时才知道B的价值。我没有正确使用->运营商吗?任何帮助,将不胜感激。

回答

2

把分号(;)放在错误的地方。什么你写在语法上等同于:

example(A) :- 
    ( B=A, 
     ( B==2 
     -> write(B), 
     write(' is 2'), 
     nl 
     ) 
    ; write(B), 
     write(' is not 2'), 
     nl 
    ). 

因此,有两个分支的位置:一个在其中设置B = A,然后检查是否B == 2,如果是这样的话,你跟着一个新行write(B)然后write(' is 2') 。在B不是2的情况下,您也可以使用该分支,但if body中的呼叫(在->之后)将不会被调用。

接下来还有一个完全独立的分支,你write(B)但是请注意,在该分支,我们还没有首先通过B = A过去了,所以Prolog的B是一个不接地变量,下次你write(' is not 2')。但是你所看到的_282是一个未被接受的变量

您可以通过将分号在正确的地方解决它:

example(A) :- 
    B = A, 
    ( B == 2 
    -> (write(B), write(' is 2'), nl) 
    ; (write(B), write(' is not 2'), nl) 
    ). 

或者更简洁:

example(A) :- 
    B = A, 
    ( B == 2 
    -> write(B), 
     write(' is 2'), 
     nl 
    ; write(B), 
     write(' is not 2'), 
     nl 
    ) 
). 

此外,它是我不清楚为什么你构建了一个新的变量第一名。你可以用工作A直接

example(A) :- 
    ( A == 2 
    -> write(A), 
     write(' is 2'), 
     nl 
    ; write(A), 
     write(' is not 2'), 
     nl 
    ) 
). 
+0

谢谢!为了回答你最后的问题,我的实际代码在if/else语句之前做了很多工作。为了这个问题,我只是简化了一切。 – applemavs