Что происходит в вашем коде, так это то, что длина списка неявно устанавливается путем вызова length/2
.Это начнется со списка длины 0, который связывает M
с 0, что, в свою очередь, пробуждает ограничение M in 1..N
, которое не выполняется.Затем он возвращает список длины 1, который успешно выполняется, затем при возврате к списку длины 2, который успешно выполняется снова.После этого любой дальнейший возврат в length/2
вернет более длинные и длинные списки, но пробуждение M in 1..N
всегда будет неудачным, пока список не станет настолько большим, что вам не хватит памяти.
Что вам нужно сделать, этопоместите точку выбора перед вызовом length/2
, а не внутри нее, например, заменив
M #=< N,
(в любом случае это избыточное ограничение) на
indomain(M),
Это даст вам:
[debug] [1] ?- p(2,I).
I = [_G3025],
_G3025 in 1..2 ;
I = [_G3102, _G3105],
_G3102 in 1..2,
_G3105 in 1..2.
[debug] [1] ?-