Пролог вышел из глобального стека - PullRequest
0 голосов
/ 08 июня 2011

Привет, ребята, я новичок в Прологе. Я пытаюсь объединить 1000 элементов в классе 3 без повторений. Я сделал код, но у меня проблема со стеком.

member(T, [T|R], R) :- !.
member(T, [_|L], R) :- member(T, L, R). 

last_element([H], H) :- !.
last_element([H|[X]], X) :- !.
last_element([H|T], R) :- last_element(T, R). 


    macronutrienti(1).
    macronutrienti(2).
    macronutrienti(3).
    and so on

percentuale_macronutrienti(Alimento, R) :-
    macronutrienti(Alimento),
    R = Alimento.

combina(NRAlimenti, RIS) :-
    findall(PM, percentuale_macronutrienti(Alimento, PM), PMR),
    f1(NRAlimenti, PMR, PMR, RIS), !.

f1(1, RParz, PMR, RParz) :- !.
f1(Index, RParz, PMR, RIS) :-
    Index1 is Index - 1,
    g2(RParz, PMR, RIS1, RIS1),
    f1(Index1, RIS1, PMR, RIS).
f1(Index, RParz, PMR, RIS) :-
    Index1 is Index - 1,
    g1(RParz, PMR, RIS1, RIS1),
    f1(Index1, RIS1, PMR, RIS).

g1([A|[TA]], A1, OldR, R) :- 
    q([A], L1, A1), 
    h1(A, L1, OldR, OldR), !.
g1([A|T], A1, Risultato,  R) :- 
    q([A], L1, A1), 
    h1(A, L1, OldR, OldR),
    append(OldR, TOldR,Risultato),
    g1(T, A1, TOldR, R).

q(A, R, A1) :- last_element(A, LastElement), member(LastElement, A1, R).

g2([A|[TA]], A1, OldR, R) :-
    q(A, L1, A1), 
    h2(A, L1, OldR, OldR), !.
g2([A|T], A1, Risultato, R) :-
    q(A, L1, A1),  
    h2(A, L1, OldR, OldR),
    append(OldR, TOldR, Risultato),
    g2(T, A1, TOldR, R).

h1(_, [], _,  _) :- !.
h1(Alimento, [Alimento1], [OldM],  R) :- append([Alimento], [Alimento1], OldM).
h1(Alimento, [Alimento1|T1], [OldM|TOldM], NewM) :- 
    append([Alimento], [Alimento1], OldM),
    h1(Alimento, T1, TOldM, NewM).

h2(_, [], _,  _) :- !.
h2(Alimento, [Alimento1], [OldM],  R) :- append(Alimento, [Alimento1], OldM).
h2(Alimento, [Alimento1|T1], [OldM|TOldM], NewM) :- 
    append(Alimento, [Alimento1], OldM),
    h2(Alimento, T1, TOldM, NewM).

:- combinew(3,R).

Что не так? Заранее спасибо

1 Ответ

0 голосов
/ 26 октября 2011

Вот гораздо более короткий код, который (я думаю) делает то же самое, что и ваш:

combine(N,L) :-
    findall(PM, macronutrienti(PM), PMR),
    findall(L0, combine0(N, PMR, L0), LL).

combine0(0, _, []) :- !.
combine0(I, PMR, [X|LR]) :-
    member(X, PMR, PMRR),
    I1 is I-1,
    combine0(I1, PMRR, LR).

member(T, [T|R], R).
member(T, [_|L], R) :- member(T, L, R). 

(я немного изменил ваш member/3 предикат)

Однако это по-прежнему не решает проблему переполнения стека. В принципе, если я правильно понял ваш вопрос, вы хотите извлечь все отсортированные подмножества длины 3 из набора из 1000 элементов. Количество подходящих наборов составляет 1000! / (1000-3) !, то есть 997.002.000 списков длиной 3. Это довольно много, так что если вам понадобится огромный стек.

Если вам не нужен полный список для продолжения, измените рабочий процесс для создания одного такого элемента за раз, затем немедленно обработайте его и переходите к следующему.

...