如何检查变量是否在 Prolog 中实例化?

How to check if variable is instantiated in Prolog?

我需要知道变量是否在给定规则中被实例化,但我不允许使用 var(X),也不知道如何使用。
具体来说,我的规则有 4 个参数(P、A、B、C)。
如果 P、A、B、C 被实例化,那么我的规则应该 "return" true iff (A+B)mod(P)=C(mod(P)).
如果 A B 和 C 之一没有被实例化,我应该 return 它的什么值将保证 (A+B)mod(P)=C(mod(P))。因此,例如,如果 C 未实例化,则规则应 "return" (A+B)mod(P) 作为 C,如果 A 或 B 未实例化,则类似行为。编写每条规则很容易,但是如果我不知道变量是否被实例化,我怎么知道我处于哪种情况呢?如前所述,我不能使用 var(X) 或 number(X) 等等,我只能假设 P 总是被实例化。
提前致谢!

手动测试某些东西是否被实例化使得正确处理实践中可能出现的所有情况变得非常困难。对于您没有考虑过的某些实例化模式,您生成的代码几乎总是会出现错误行为。

幸运的是,有针对此类问题的声明式解决方案:约束 在所有情况下都能正常工作,无论实例化的是什么,未实例化的是什么。

例如,使用您的 Prolog 系统的 CLP(FD) 约束 来解决您的任务:

:- use_module(library(clpfd)).

same_sum_mod(A, B, C, P) :-
    (A+B) mod P #= C mod P.

它在各个方向都能正常工作,例如:

?- same_sum_mod(1, 2, 3, 3).
true.

?- same_sum_mod(1, B, 3, 2).
1+B#=_G823,
_G823 mod 2#=1.

?- same_sum_mod(1, 2, 3, P).
P in inf..-1\/1..sup,
3 mod P#=_G855,
3 mod P#=_G855.

还要检查以下情况,其中 B 最初 实例化,但它的 是已知的,并且约束求解器可以推导出单个可接受的解决方案:

?- B in 0..1, same_sum_mod(1, B, 3, 2).
B = 0.

这种情况无法通过简单的实例化检查来处理,但需要对约束进行推理。

有关 CLP(FD) 约束的详细信息,请参阅

我认为@mat 回答绝对是解决您问题的方法。

但是,如果你想检查一个变量是否没有被实例化而不使用内置谓词var/1,这正是(由于某些限制,例如你的老师明确禁止它)你可以使用双重否定两次来测试绑定变量的能力,如果它没有被绑定,而不真正实例化它:

not_inst(Var):-
  \+(\+(Var=0)),
  \+(\+(Var=1)).

测试用例:

?- not_inst(X).
true.
?- not_inst(a).
false.