1

I'm using the clpfd library

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

Then I attempt to generate all 3 lists of length K with 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

I would expect the query to terminate after K = 3. For example, the following does terminate.

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

Why does one terminate and the other does not?

false
  • 10,264
  • 13
  • 101
  • 209
smadge
  • 11
  • 1

1 Answers1

2

K in 1..3 simply asserts that K is somewhere between 1 and 3, without binding particular value. What you need is indomain(K) predicate, which backtracks over all values in K's domain:

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

Out of stack in your example happens for the following reason: length(C, K) without any of its arguments bound generates lists of different lengths, starting with 0, then 1, 2, 3, ...

Each time it generates a solution it tries bind a particular value to K, that is 0, 1, 2, ...

Now, because there are constraints applied to K, any attempts to bind a value greater than 3 will fail, meaning that length(C, K) will continue trying to find alternative solutions, that is, it will keep generating lists of length 4, 5, 6, ... and so on, all of which will be discarded. This process will continue until you exhaust your stack.

code_x386
  • 778
  • 3
  • 5