На этот вопрос уже есть много отличных ответов, но вот еще одно решение этой проблемы, которое вы должны рассмотреть. Эта программа отличается от других тем, что она очень эффективна и генерирует не избыточные решения списков, которые, как предполагается, представляют наборы целых чисел, которые складываются в указанное число.
gen(N, L) :-
gen(N-1, N, N, FL),
dup_n(FL, L).
gen(C-F, M, M, [C-F]).
gen(C-F, S, M, [C-F|R]) :-
S < M, C > 1,
C0 is C - 1,
F0 is floor(M / C0),
S0 is S + (C0 * F0),
gen(C0-F0, S0, M, R).
gen(C-F, S, M, R) :-
F > 0,
F0 is F - 1,
S0 is S - C,
gen(C-F0, S0, M, R).
dup_n([], []).
dup_n([_-0|R], L) :-
!, dup_n(R, L).
dup_n([V-F|R], [V|L]) :-
F0 is F - 1,
dup_n([V-F0|R], L).
Ваша реализация addUpList/2
может быть достигнута:
addUpList(N, P) :-
findall(L, gen(N, L), P).
Что должно дать вам следующее поведение:
?- addUpList(4,L).
L = [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]].
Обратите внимание, что список, содержащий один 2
и два 1
с, появляется только один раз в этом наборе результатов; это потому, что gen/4
вычисляет уникальные наборы целых чисел, которые складываются в указанное число.