Почему это происходит?Разве он не должен возвращать false
вместо этого?
Нет, поскольку length/2
не знает об этих границах, он просто предлагает значения, и проверка фиксированного ограничения каждый раз отклоняет эти значения.
length/2
[swi-doc] можно использовать «конструктивно ».Действительно, мы можем генерировать списки с соответствующей длиной, например:
?- length(L, N).
L = [],
N = 0 ;
L = [_2316],
N = 1 ;
L = [_2316, _2322],
N = 2 ;
L = [_2316, _2322, _2328],
N = 3
...
Теперь вы определили ограничение для N
, что означает, что если вы установите N
на определенное значение, интерпретатор Prolog проверит,это значение находится в диапазоне 1..2
.Таким образом, для каждого значения с N > 2
это не удастся.Но length/2
конечно, не понимает этот диапазон.Он будет продолжать предлагать списки и их соответствующие длины, и это будет каждый раз терпеть неудачу.
Это эквивалентно:
?- length(L, N), member(N, [1, 2]).
L = [_2304],
N = 1 ;
L = [_2304, _2310],
N = 2 ;
ERROR: Out of global-stack.
ERROR: No room for exception term. Aborting.
Здесь имеет смысл сделать это в обратном порядке, например:
?- member(N, [1,2]), length(L, N).
N = 1,
L = [_3372] ;
N = 2,
L = [_3372, _3378].
Или, если это не вариант, попробуйте freeze/2
[swi-doc] построение списка до тех пор, пока не станет известно N
.