Prolog列出长度受限的长度

时间:2018-01-12 06:53:02

标签: prolog clpfd

我正在使用clpfd库

?- use_module(library(clpfd)).                    
true.

然后我尝试生成长度为K的所有3个列表,其中1 <= K <= 3。

?- K in 1 .. 3, length(C, K). 
K = 1,
C = [_1302] ;
K = 2,
C = [_1302, _1308] ;
K = 3,
C = [_1302, _1308, _1314] ;
ERROR: Out of global stack

我希望查询在K = 3之后终止。例如,以下内容会终止。

?- between(1, 3, K), length(X, K).                                      
K = 1,
X = [_3618] ;
K = 2,
X = [_3618, _3624] ;
K = 3,
X = [_3618, _3624, _3630].

为什么一个终止而另一个不终止?

1 个答案:

答案 0 :(得分:2)

K in 1..3只是断言K介于1和3之间,没有绑定特定值。您需要的是indomain(K)谓词,它会回溯K域中的所有值:

K in 1..3, indomain(K), length(C, K).

在您的示例中出现堆栈的原因如下:没有任何参数绑定的length(C, K)生成不同长度的列表,从0开始,然后是1,2,3,......

每次生成解决方案时,它都会尝试将特定值绑定到K,即0,1,2,......

现在,因为对K应用了约束,任何绑定大于3的值的尝试都将失败,这意味着length(C, K)将继续尝试寻找替代解决方案,也就是说,它将保持不变生成长度为4,5,6,......等的列表,所有这些都将被丢弃。此过程将持续到您耗尽堆栈为止。