使用ERROR生成SWI-Prolog结果中的动态大小排列:超出全局堆栈

Łuk*_*asz 0 prolog clpfd

我正在尝试使用此代码生成多个排列:

:- use_module(library(clpfd)).

p(N, Indexes) :-
    M in 1..N,
    M #=< N,
    length(Indexes, M),
    Indexes ins 1..N.
Run Code Online (Sandbox Code Playgroud)

它返回了我所有的结果,但最终崩溃了 ERROR: Out of global stack

twi*_*rer 5

您的代码中发生的是通过调用隐式设置列表的长度length/2.这将从长度为0的列表开始,该列表绑定M到0,这反过来唤醒约束M in 1..N,该约束失败.接下来,它返回一个长度为1的列表,该列表成功,然后回溯一个长度为2的列表,该列表再次成功.在此之后,任何进一步的回溯length/2将返回更长和更长的列表,但是唤醒M in 1..N将始终失败,直到列表变得如此之大以至于内存不足.

您需要做的是在length/2调用之前放置选择点而不是在其内部,例如,替换

M #=< N,
Run Code Online (Sandbox Code Playgroud)

(无论如何,这是一个多余的约束)

indomain(M),
Run Code Online (Sandbox Code Playgroud)

这给你:

[debug] [1]  ?- p(2,I).
I = [_G3025],
_G3025 in 1..2 ;
I = [_G3102, _G3105],
_G3102 in 1..2,
_G3105 in 1..2.

[debug] [1]  ?- 
Run Code Online (Sandbox Code Playgroud)