1

我已将代码简化为;

findall(T,(T > 0, T < 50),List).

为什么这会因给定错误而失败。

4

2 回答 2

3

这是您的代码进一步简化:

?- T > 0.
ERROR: >/2: Arguments are not sufficiently instantiated

“经典”比较操作喜欢<并且>需要将所有参数完全实例化为基本术语;特别是,它们不能是未绑定的变量。(运算符右侧的术语也是如此is/2。)

不能将这些运算符用作生成器。以下是一个可能的原因说明:

?- T = 1, T > 0.
T = 1.

?- T = 0.1, T > 0.
T = 0.1.

?- T = 0.01, T > 0.
T = 0.01.

?- T = 0.001, T > 0.
T = 0.001.

>运算符适用于几种不同类型的数字,包括浮点数。如果我们希望它成为一个逻辑上合理的生成器,它必须能够生成上面示例中它接受的所有浮点数。那几乎肯定不是你想要的。

有几种方法可以得到你想要的。由于您可能只需要整数,因此您可以使用between/3许多 Prolog 系统(包括 SWI)提供的谓词:

?- between(1, 49, T).
T = 1 ;
T = 2 ;
T = 3 ;
T = 4 .

?- findall(T, between(1, 49, T), List).
List = [1, 2, 3, 4, 5, 6, 7, 8, 9|...].

另一种可能性是使用约束编程库。这是 SWI-Prologclpfd库的一个示例会话:

?- use_module(library(clpfd)).
true.

?- T #> 0, T #< 50.
T in 1..49.

请注意,在这里,使用库中的 and 而不是#>and ,我们实际上可以在未绑定的变量上指定这些约束。记住这些约束以供以后使用,但它们不会枚举. 您可以在算术和比较中使用它们,系统有时会正确推理出事情,即使它没有枚举具体值!例如:#<clpfd<>T

?- T #> 0, T #< 50, X #= T - 50, X #> 50.
false.

要获取实际值,请调用枚举它们的特定谓词:

?- T #> 0, T #< 50, indomain(T).
T = 1 ;
T = 2 ;
T = 3 ;
T = 4 .

所有这些都为您的问题提供了另一种可能的解决方案:

?- findall(T, (T #> 0, T #< 50, indomain(T)), List).
List = [1, 2, 3, 4, 5, 6, 7, 8, 9|...].
于 2018-04-07T13:52:10.583 回答
0

如果要过滤,可以这样写:

bagof(T,(member(T,[0,-4,34,15,76,100,200,43,21]),T>0,T<50),List).

列表将是 [34,15,43,21]。(虽然我没有测试)

如果你只想列举1到49,忽略这个答案(其他人已经回答了)

于 2018-04-08T08:42:26.283 回答