我已将代码简化为;
findall(T,(T > 0, T < 50),List).
为什么会因给定错误而失败。
答案 0 :(得分:3)
以下是您的代码进一步简化:
?- T > 0.
ERROR: >/2: Arguments are not sufficiently instantiated
&#34; classic&#34;像<
和>
之类的比较操作需要将所有参数完全实例化为基础术语;特别是,它们不能是未绑定的变量。 (对于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.
>
运算符适用于多种不同类型的数字,包括浮点数。如果我们希望它是一个逻辑上合理的生成器,它必须能够生成它在上面的例子中接受的所有浮点数。这几乎肯定不是你想要的。
有几种方法可以获得你想要的东西。因为你可能只想要整数,你可以使用许多Prolog系统(包括SWI)提供的between/3
谓词:
?- 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-Prolog的clpfd
库的一个示例会话:
?- use_module(library(clpfd)).
true.
?- T #> 0, T #< 50.
T in 1..49.
请注意,在这里,使用#>
库中的#<
和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|...].
答案 1 :(得分: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,请忽略这个答案(其他人已经回答)