4

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

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

当我打电话给

 length(X,5), test(X).

它向我显示以下错误:

错误:参数没有充分实例化

当我调试代码时,H变量 intest没有被实例化。

有谁知道为什么?

4

1 回答 1

5

这里的问题是您的规则test([H|T])在 Prolog 中没有描述H为正整数。它只测试 if H > 0,因为H没有实例化而失败。仅仅试图将一个未实例化的变量与一个数字(H > 0在这种情况下)进行比较不会导致 Prolog 假设您打算H成为一个数字,并且更进一步,不会实例化H.

此外,您的规则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] ;
...
于 2017-06-29T12:03:14.753 回答