为什么 length/2 让我离开全局堆栈?
Why is length/2 getting me out of global stack?
当我提交查询时:
?- X in 1..2, length(List,X).
returning 结果是:
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 次以了解 length/2 如何将非实例化变量作为长度:
?- X in inf..sup, length(List,X).
?- length(List,_).
?- length(List,_X).
并且一切正常。因此,如果 X 未接地,则在达到域的最高值后,length/2 会崩溃。为什么会这样?不应该 return false 吗?
Why is this happening? Shouldn't it return false
instead?
不,因为 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
已知。
当我提交查询时:
?- X in 1..2, length(List,X).
returning 结果是:
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 次以了解 length/2 如何将非实例化变量作为长度:
?- X in inf..sup, length(List,X).
?- length(List,_).
?- length(List,_X).
并且一切正常。因此,如果 X 未接地,则在达到域的最高值后,length/2 会崩溃。为什么会这样?不应该 return false 吗?
Why is this happening? Shouldn't it return
false
instead?
不,因为 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
已知。