我正在编写一个寻找特定整数的规则。我以为我可以写这样的东西
find_number(X):-
integer(X),
X > 1, X < 5.
然后期望integer(X)
的查询结果导致X=2, X=3, X=4, false.
相反,我只得到false
结果。我发现编写此规则的唯一方法是使用numlist/3
,如此
find_number(X):-
numlist(2, 4, NumList),
member(X, NumList).
任何人都可以解释为什么会这样吗?
答案 0 :(得分:4)
您的推理完全有效 iff integer/1
是一个满足基本逻辑属性的实际关系。
例如,在经典逻辑中,一元谓词P满足以下属性:
如果 P(σ(T))对于任何替换σ和项T是可满足的,则那么 P(T)也是可满足的。
对于Prolog中的所有纯谓词,这似乎是非常明显的,当然也适用。
问题是integer/1
不是纯粹的关系。
特别是,我们有例如:
?- integer(3). true.
然而,以下更一般查询失败:
?- integer(X). false.
是否有任何整数? 否。
信不信由你,integer/1
实际上是如何运作的。
对于整数的情况,我建议您查看 CLP(FD)约束(clpfd)。
例如,在GNU Prolog中,您的代码可能如下所示:
good_number(X) :- X #> 1, X #< 5.
通过以下查询和答案:
| ?- good_number(X). X = _#2(2..4) | ?- good_number(X), fd_labeling([X]). X = 2 ? ; X = 3 ? ; X = 4
这与我们期望的工作关系完全一样!我已经冒昧地更改名称,以便在更具体的情况下更有意义,其中没有任何东西可以“找到”:
| ?- good_number(3). yes
根据您的Prolog系统,您可能必须导入库才能使用此类更多声明性功能。有关详细信息,另请参阅logical-purity。
答案 1 :(得分:1)
你得到的只是假,因为integer/1
测试输入是否是一个整数,如果它是否成功,如果它不是一个整数,或者它是一个未在你的情况下实例化的变量,那么它失败。
您可以使用between/2
内置谓词:
find_number(X):-between(2,4,X).
这将返回:
?- find_number(X).
X = 2 ;
X = 3 ;
X = 4.