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

时间:2016-01-13 10:30:29

标签: prolog instantiation

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

2 个答案:

答案 0 :(得分:5)

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

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

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

测试用例:

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

答案 1 :(得分:3)

手动测试是否实例化某些内容使得很难正确处理实际中可能出现的所有情况。几乎总是如此,您生成的代码对于您没有想过的某些实例化模式会表现不正确。

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

例如,使用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)约束的更多信息,请参阅