Prolog中if / else的可变范围

时间:2017-11-11 12:33:30

标签: if-statement scope prolog

我正在尝试在GNU Prolog中使用->运算符,但我在变量范围方面遇到了一些麻烦。这是一个例子:

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

在Prolog控制台中:

| ?- example(2).
2 is 2

true ? 

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

yes

当我查询example(2)时,B == 2成功,而Prolog知道B的值是什么,从而打印出2 is 2

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

1 个答案:

答案 0 :(得分: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主体中的调用(->之后)将不会被调用。

接下来还有一个完全独立的分支,你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
    )
).