2016-01-13 81 views
4

我需要知道变量是否在给定的规则中被实例化,但我不被允许使用var(X),并且不知道如何去做。
具体来说,我的规则得到4个参数(P,A,B,C)。
如果P,A,B,C被实例化,那么我的规则应该“返回”真如果(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)或number(X)等等,我只能假设P总是被实例化。
在此先感谢!如何检查变量是否在Prolog中实例化?

+0

您不允许使用'号(X)'? – BretC

+0

@BretC OP状态,* ...我不能使用'var(X)'或'number(X)'等等。 – lurker

回答

4

手动测试是否实例化了某些东西,这使得很难正确处理实践中可能出现的所有情况。几乎总是,对于某些你没有想过的实例化模式,你的结果代码会表现不正确。

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

例如,使用您的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最初是而非已实例化,但其已知,而con straint解算器可以推断出单个允许解:

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

这种情况下不能用简单的实例化的检查处理,但是需要约约束推理。

有关CLP(FD)约束条件的更多信息,请参阅

4

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

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

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

测试用例:

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

正确的方法是用'var/1'和' nonvar/1'。我认为你应该提到,如果有人通过谷歌回答这个问题,并且不停地阅读OP说他们被禁止使用这些谓词。 –

+1

@DanielLyons:为了以防万一,以粗体添加了一些评论。也许我应该完全删除答案? – gusbro

+0

不,我喜欢这个。请保留! –

相关问题