如何编写使用整数/ 1查找数字的规则?

时间:2017-06-30 15:59:30

标签: prolog

我正在编写一个寻找特定整数的规则。我以为我可以写这样的东西

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).

任何人都可以解释为什么会这样吗?

2 个答案:

答案 0 :(得分:4)

您的推理完全有效 iff integer/1是一个满足基本逻辑属性的实际关系

例如,在经典逻辑中,一元谓词P满足以下属性:

如果 P(σ(T))对于任何替换σ和项T是可满足的,则那么 P(T)也是可满足的。

对于Prolog中的所有谓词,这似乎是非常明显的,当然也适用

问题是integer/1 不是纯粹的关系。

特别是,我们有例如:

?- integer(3).
true.

然而,以下更一般查询失败

?- integer(X).
false.

是否有任何整数? 否。

信不信由你,integer/1实际上是如何运作的。

显然,对于这样的谓词来说似乎不太合适,因此在所有广泛使用的现代Prolog系统中都有更好的替代方案。我强烈建议你使用这些替代品,以充分利用Prolog。

对于整数的情况,我建议您查看 CLP(FD)约束)。

例如,在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系统,您可能必须导入库才能使用此类更多声明性功能。有关详细信息,另请参阅

答案 1 :(得分:1)

你得到的只是假,因为integer/1测试输入是否是一个整数,如果它是否成功,如果它不是一个整数,或者它是一个未在你的情况下实例化的变量,那么它失败。

您可以使用between/2内置谓词:

find_number(X):-between(2,4,X).

这将返回:

?- find_number(X).
X = 2 ;
X = 3 ;
X = 4.