Prolog:变量列表的主管没有立即生效

时间:2017-06-28 15:57:40

标签: list prolog instantiation-error

我正在编写一个简单的代码,生成一个包含5个数字的简单列表,其中第一个变量应为正数,并且我试图理解为什么此代码失败

test([H|T]) :- H > 0, length(T,4).

当我用

打电话时
 length(X,5), test(X).

它向我显示以下错误:

  

错误:参数未充分实例化

调试代码时,H中的test变量未实例化。

任何人都知道为什么?

1 个答案:

答案 0 :(得分:5)

这里的问题是test([H|T])的规则没有在Prolog中描述H是一个正整数。它仅测试H > 0H失败,因为H > 0没有实例化。只是尝试将未实例化的变量与数字(在这种情况下为H)进行比较不会导致Prolog假定您希望H为数字,而且不会实例化{{1} }。

此外,test/1的规则不会描述列表的其余部分(T),而是强制它为长度为4.因为您的查询建立了长度的规则原始列表为5,这个规定是多余的。

您似乎想要定义test(L),这意味着L是正整数的任意列表。这通常使用CLP(FD)来完成:

:- use_module(library(clpfd)).

test(X) :- X ins 1..10000.

此规则表明X是一个列表,其值在1到10000之间。生成长度为5的列表的相应查询将是:

?- length(X, 5), test(X), label(X).
X = [1, 1, 1, 1, 1] ;
X = [1, 1, 1, 1, 2] ;
X = [1, 1, 1, 1, 3] ;
X = [1, 1, 1, 1, 4] ;
X = [1, 1, 1, 1, 5] ;
...

如果您想进一步限制它并说元素必须是唯一的,您可以使用all_different/1

test(X) :- X ins 1..10000, all_different(X).

?- length(X, 5), test(X), label(X).
X = [1, 2, 3, 4, 5] ;
X = [1, 2, 3, 4, 6] ;
X = [1, 2, 3, 4, 7] ;
X = [1, 2, 3, 4, 8] ;
X = [1, 2, 3, 4, 9] ;
X = [1, 2, 3, 4, 10] ;
...