Генерация динамических перестановок размеров в результатах SWI-Prolog с помощью ERROR: Out of global stack - PullRequest
0 голосов
/ 05 марта 2012

Я пытаюсь сгенерировать несколько перестановок, используя этот код:

:- use_module(library(clpfd)).

p(N, Indexes) :-
    M in 1..N,
    M #=< N,
    length(Indexes, M),
    Indexes ins 1..N.

Возвращает мне все результаты, но в итоге вылетает с ERROR: Out of global stack

Ответы [ 3 ]

5 голосов
/ 05 марта 2012

Что происходит в вашем коде, так это то, что длина списка неявно устанавливается путем вызова 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]  ?- 
3 голосов
/ 05 марта 2012

Мне не понятно, что вы подразумеваете под множественными перестановками.Но, вероятно, ваша программа должна начинаться с between/3, а затем содержать ограничение all_different/1.

p(N, Indices) :-
    between(1,N,M), % or maybe rather between(0,N,M).
    length(Indices, M),
    Indices ins 1..N,
    all_different(Indices).

И затем использовать labeling/2 для генерации реальных решений.

1 голос
/ 05 марта 2012

Поскольку twinterer уже ответил на вопрос, я просто добавляю более простой способ получения (правильных) перестановок (может быть полезным?):

permutations_n(N, P) :-
  numlist(1, N, L),
  permutation(L, P).

test:

?- permutations_n(3, X).
X = [1, 2, 3] ;
X = [1, 3, 2] ;
X = [2, 1, 3] ;
X = [2, 3, 1] ;
X = [3, 1, 2] ;
X = [3, 2, 1] ;
...