2012-03-05 3 views
0

글로벌 스택의 출력 :는 오류 발생 :이 코드를 사용하여 여러 순열을 생성하기 위해 노력하고있어

:- use_module(library(clpfd)). 

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

그것은 나 모든 결과를 반환을했지만 결국 충돌에 with ERROR: Out of global stack

+0

조건 'M # = CapelliC

+0

네,하지만 프롤로그가 루프를 끝내지 않아서 트레이스를 사용하여 이것이 도움이 될 거라 생각했지만, 't –

답변

5

코드에서 발생하는 일은 length/2을 호출하여 목록의 길이가 암시 적으로 설정된다는 것입니다. 이것은 M을 0으로 바인드하는 길이 0의리스트로 시작하여 차례로 실패한 M in 1..N 제한을 깨우며 실패합니다. 다음으로 길이 1의리스트를 리턴하고, 성공한 후 다시 성공한 길이 2의리스트를 역 추적합니다. 그 후에는 length/2으로 더 이상 역 추적하면 길고 긴 목록이 반환되지만 M in 1..N을 깨우면 목록이 너무 커서 메모리가 부족해질 때까지 항상 실패합니다.

당신이해야 할 것은과 (중복 제약 어쨌든)

M #=< N, 

교체, 예를 들어,에 의해 대신 내부의 length/2 호출하기 전에 choicepoint 장소입니다

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] ?- 
+0

고마워, 내 문제가 해결되었지만 왜 이해가 안되나요;) 문서에 대한 링크가있어'M'이 0이되는 이유는 무엇입니까? 나는 또한 불필요한 M => ='을 시도했지만 도움이되지 못했습니다. 'M ins 1.N '은 루프와 같다고 생각했지만, 강제로 루프에 들어간다고 가정합니다. –

+0

@ Łukasz : M **은 처음부터 twinterer (감사! +1)로 0부터 시작합니다 **. 이 쿼리를보십시오 :? - length (X, Y). – CapelliC

+0

@ Łukasz :'M ins 1..N'은 루프가 아니므로 'M'의 도메인을 1과 N 사이로 제한하는 제약 조건입니다. 제약 조건으로 'M'의 범위가 변경 될 때까지 일시 중지됩니다 그것이 깨어나고 그것의 일관성을 점검 할 때. '길이/2'는 제약 조건이 아니며, 즉 변수 'M'의 도메인은 고려되지 않습니다. 인스턴스화되지 않은 변수로'length/2'를 호출하면 빈리스트가 반환됩니다. 이것은'M'을 0으로 묶어서'M' 도메인의 경계를 바꾸고'M'에 게시 된 제약 조건을 깨 웁니다. 그런 다음 제약 조건은 일관성을 검사하고 0이 도메인에 없으므로 실패합니다. – twinterer

1

이미 twinterer는 응답했다 질문에, 난 그냥 (유용 할 수 있을까?) (적절한) 순열을 얻을 수있는 간단한 방법을 추가

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

시험 :

?- 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] ; 
3

당신이 여러 순열 무엇을 의미하는 나에게 분명하지 않다 . 그러나 아마도 프로그램은 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를 사용합니다.

+2

더 나은 해결 방법은 버그 수정이 아니라 +1입니다. ('Indices ins. 1. N'이어야 함) – twinterer

+0

@ twinterer : 고맙습니다. – false