Почему length / 2 выводит меня из глобального стека? - PullRequest
2 голосов
/ 30 мая 2019

когда я фиксирую запрос:

?- X in 1..2, length(List,X).

возвращаемые результаты:

X = 1, List = [_1260];
X = 2, List = [_1260, _1266];
ERROR: Out of global-stack.
ERROR: No room for exception term. Aborting.
% Execution Aborted

Я думал, что это произошло, потому что X не обоснован, поэтому я выполнил еще 3 запроса, чтобы увидеть, как длина / 2 ведет себя с неинстанцированными переменными как длина:

?- X in inf..sup, length(List,X).
?- length(List,_).
?- length(List,_X).

и все работает правильно. Таким образом, если X не заземлен, после достижения доменного уровня происходит сбой длины / 2. Почему это происходит? Разве он не должен возвращать false вместо этого?

1 Ответ

2 голосов
/ 30 мая 2019

Почему это происходит?Разве он не должен возвращать 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.

...