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

Raf*_*aga 4 list prolog instantiation-error

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

test([H|T]) :- H > 0, length(T,4).
Run Code Online (Sandbox Code Playgroud)

我打电话的时候

 length(X,5), test(X).
Run Code Online (Sandbox Code Playgroud)

它向我显示以下错误:

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

当我调试代码时,H变量in test不会被实例化.

谁知道为什么?

lur*_*ker 5

这里的问题是你的规则test([H|T])没有在Prolog中描述H是一个正整数.它只测试是否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.
Run Code Online (Sandbox Code Playgroud)

此规则表明这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] ;
...
Run Code Online (Sandbox Code Playgroud)

如果您想进一步限制它并说元素必须是唯一的,您可以使用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] ;
...
Run Code Online (Sandbox Code Playgroud)

  • `all_distinct/1`具有更强的传播性,通常应该使用而不是`all_different/1`,尽管我怀疑这在这种特殊情况下有所不同. (3认同)
  • @Fatalize谢谢你,好建议.我同意,这可能在这个问题/答案场景中分裂. (2认同)