Prolog - 参数未充分实例化

时间:2018-04-20 13:42:16

标签: prolog instantiation-error

我是prolog的新手,我已经构建了以下示例函数:

bar(Fruit) :-
   Fruit = fruit(apple, X),
   A is abs(X) + 0,
   between(0,10,A).

foo(L) :-
   findall(X, bar(fruit(apple, X)), L).

致电foo(L)会收到错误:ERROR: is/2: Arguments are not sufficiently instantiated

现在,我已经阅读了多个线程,其中重复解决方案是使用clpfd A #= abs(X) + 0。但是,在使用该解决方案时,我不一定得到我想要的列表:

L = [0, _G9407, _G9410, _G9413, _G9416, _G9419, _G9422, _G9425, _G9428|...],
clpfd:in(_G9407, -1\/1),
clpfd:in(_G9410, -2\/2),
clpfd:in(_G9413, -3\/3),
clpfd:in(_G9416, -4\/4),
clpfd:in(_G9419, -5\/5),
clpfd:in(_G9422, -6\/6),
clpfd:in(_G9425, -7\/7),
clpfd:in(_G9428, -8\/8),
clpfd:in(_G9431, -9\/9),
clpfd:in(_G9434, -10\/10).

特别是当使用更复杂的功能时,它也变得非常难以阅读。我期望的输出基本上是一个清晰而简单的列表: [-10...10]。< / strong>没有clpfd有没有替代方案?我还通过这个过程了解到,使用<, >, >=, =<之类的逻辑运算符可以使用between来获取类似的错误。我来自OOP背景,我很难掌握逻辑上的缺陷......

感谢您的帮助,

1 个答案:

答案 0 :(得分:1)

Prolog主要是关系型的,你通常可以在两个方向上计算,但不能用数学计算。 is/2要求RHS是一个值(没有未实例化的变量)。并且你不能使用abs(X)同时获得+ X和-X,这正是你所期望的。 + 0没有用,但我想你刚刚从其他东西中简化了。

这有效:

bar(Fruit) :-
  Fruit = fruit(apple, X),
  between(0,5,A),
  ( X = A ; X is -A ).

?- foo(L).
L = [0, 0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5].

但听起来你可能想要使用CLP(FD)来做你想做的事。