获得错误的Prolog程序:> / 2:参数没有充分实例化

时间:2013-11-19 11:41:46

标签: prolog clpfd

我创建了一个程序list(X,Y)来检查列表Y中的所有元素是否小于X.

代码如下。

list(X,[]).
list(X,[Y|Z]):-X>Y,list(X,Z).

我输入list(3,[1,2])时效果很好。但是,如果我键入list(3,Y)以查找仅包含小于3的元素的列表,则会出错。

?- list(3,[1,2]).
true .

?- list(3,Y).
Y = [] ;
ERROR: >/2: Arguments are not sufficiently instantiated

我看过一些有同样错误的帖子,但我仍然不明白我的代码哪个部分出错了。

这是一个从互联网上找到的类似例子。 greater(X,Y,Z)会返回大于Z的{​​{1}} Y部分。

X

问题是,greater(X,[],[]). greater(X,[H|Y],[H|Z]) :- H>X, greater(X,Y,Z). greater(X,[H|Y],Z) :- H=<X, greater(X,Y,Z). ?- greater(2,[1,2,3], Y). Y = [3]. greater(X,Y,Z)的代码之间有什么区别,因此在调用list(X,Y)时没有错误。

感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:3)

因为 - 根据你的评论判断 - 你似乎在推理整数:这是使用有限域约束的教科书示例,几乎所有现代Prolog实现都可以使用这些约束并推广整数运算,以便你可以在所有方向上使用它

如果您只使用有限域约束(#>)/2而不是低级算术原语{{1>,您的代码与B-Prolog,GNU Prolog,SICStus,SWI和YAP等完全一致。 }}:

(>)/2

限制条件允许您使用此谓词,您也可以使用:- use_module(library(clpfd)). list(X, []). list(X, [Y|Z]):- X#>Y, list(X,Z). 表达,如下面的查询中所示:

maplist/2

即使是最常见的查询,也没有实例化任何参数,也提供了有用的答案:

?- maplist(#>(3), [1,2]).
true.

?- maplist(#>(X), [1,2]).
X in 3..sup.

?- maplist(#>(3), [A,B]).
A in inf..2,
B in inf..2.

?- maplist(#>(X), [Y,Z]).
Z#=<X+ -1,
Y#=<X+ -1.

编辑:此外,您现在添加的示例可以通过有限域约束更加通用:

?- maplist(#>(X), Ls).
Ls = [] ;
Ls = [_G1022],
_G1022#=<X+ -1 ;
Ls = [_G1187, _G1190],
_G1190#=<X+ -1,
_G1187#=<X+ -1 ;
etc.

您现在可以在所有方向上使用它,例如:

:- use_module(library(clpfd)).

greater(_, [], []).
greater(X, [H|Y], [H|Z]) :- H #> X, greater(X, Y, Z).
greater(X, [H|Y], Z) :- H #=< X, greater(X, Y, Z).

原始版本无法做到这一点,原作者的作者可能不知道约束。