Prolog 仅检查变量是否被实例化

Prolog only check variable is instantiated

Prolog中,是否只有当变量为instantiated.

时才可以检查variable是否为某个值
? - my_rule(X).

my_rule(X):-
    X = 4,
    write('continue'). 

我在这里尝试检查是否 X is 4,如果 X is 4 则我们继续,但如果 X 是 [=18=,我也希望规则继续],但是当它被其他东西调用时,比如 X is 3 那么它不应该继续。

所以结果应该是这样的:

?- my_rule(X).

continue
true.

?- my_rule(4).

continue
true.

?- my_rule(3).

false.
my_rule(X):-
    check(X),
    write('continue').

% A fact used to check a value.
check(4).

% A predicate that checks if X is unbound, e.g. a variable.
check(X) :-
    var(X).

验证所需结果。

?- my_rule(X).
continue
X = 4 ;
continue
true.

?- my_rule(4).
continue
true ;
false.

?- my_rule(3).
false.

你可以使用双重否定(\+(\+(...))):

在你的例子中:

my_rule(X):-
    \+(\+(X = 4)),
    write('continue'). 

看看 var/1atom/1ground/1

  • var(X) 为真当且仅当 X 是一个变量。

    ?- var(X), X= 1。 X = 1.

    ?- X=1, 变量(X)。 假的。

    ?- X=f(Y), 变量(X)。 假的。

  • 如果 X 是一个原子,
  • atom(X) 为真。

    ?-原子(a)。 是的。

    ?-原子(f(a))。 假的。

    ?-原子(X)。 假的。

  • ground(X) 如果 X 为基础(不包含变量)则为真。

    ?- 地面(f(a))。 是的。

    ?- 地面(f(X))。 假的。

这三个谓词是确定性的(即不回溯),您可以安全地否定它们。

你的代码变成这样:

my_rule(4) :-
   % handle the 4 case
my_rule(X) :-
   var(X),
   % general case

我只是不确定这是否是您想要的。在大多数程序中,应该没有必要单独处理变量唯一的情况。还要注意,此类元逻辑测试超出了经典逻辑的范围。如果比较查询 X = 1, var(X)var(X), X = 1,您会发现合取不再是可交换的,但在逻辑 A ∧ B = B ∧ A 中成立。