I'm trying to write a program that swaps the 1st and last elements.
The function takes 2 parameters. A list and a variable that's displayed as the newly swapped list.
I thought I was doing it the lazy way, but it's turning out to be just as hard for me.
I was going to grab the head, put it aside -- grab the last element of the tail, put it aside -- take the tail, remove the last element, put it aside also, then append all 3 together to make a list
I'm having trouble removing the last element of the tail.
I have something like this:
swap( [H|T], Y ) :-
% GET HEAD, LAST OF TAIL, AND TAIL WITH LAST ELEM REMOVED
% GET HEAD (NEW LAST ELEMENT)
H = NEW_LASTELEMENT,
% GET LAST ELEMENT (LAST OF TAIL, WILL BE NEW HEAD)
last(T,X), X = NEWHEAD,
% CUT END OF TAIL OFF
cutlast(T, Z), REST OF CODE . . .
.
% CUT LAST
cutlast([H | T], [H | T2]) :- T = [_|_], cutlast(T, T2).
I borrowed the cutlast predicate from the web, but I'm not sure how it's even supposed to work. I've been test passing parameters to it for an hour now and they all keep returning false. Any assistance is appreciated.
Could be just:
swap(A, B) :-
append([First | Mid], [Last], A),
append([Last | Mid], [First], B).
Additional facts to succeed with one element and empty lists, if it's needed:
swap([X], [X]).
swap([], []).
Here's a recursive solution that doesn't use the append/3 or reverse/2 built-ins. I think I found it to be a lot more efficient (in terms of number of inferences) than those:
swap_fl_recursive([First|A], [Last|B]) :-
swap_fl_recursive_(A, First, Last, B).
swap_fl_recursive_([Last], First, Last, [First]).
swap_fl_recursive_([X|A], First, Last, [X|B]) :-
swap_fl_recursive_(A, First, Last, B).
This solution passes the original First element down through the recursion until it can become the new last element, and instantiates the original Last back to become the new first element.
Like the others, for swap_fl_recursive([X], [X]) to be true or swap_fl_recursive([], []). to be true, those need to be added as facts/rules.
Timing/inferences for append/3 version:
?- numlist(1,10000,L), time(swap_fl_append(L, S)).
% 20,000 inferences, 0.021 CPU in 0.021 seconds (100% CPU, 950838 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
S = [10000, 2, 3, 4, 5, 6, 7, 8, 9|...] ;
% 3 inferences, 0.000 CPU in 0.000 seconds (94% CPU, 38921 Lips)
false.
Timing/inferences for reverse/2 version:
?- numlist(1,10000,L), time(swap_fl_reverse(L, S)).
% 20,055 inferences, 0.024 CPU in 0.024 seconds (100% CPU, 841265 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
S = [10000, 2, 3, 4, 5, 6, 7, 8, 9|...].
Timing/inferences for recursive version (shown in this answer):
?- numlist(1,10000,L), time(swap_fl_recursive(L, S)).
% 10,000 inferences, 0.009 CPU in 0.010 seconds (99% CPU, 1059142 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
S = [10000, 2, 3, 4, 5, 6, 7, 8, 9|...] ;
% 2 inferences, 0.002 CPU in 0.002 seconds (100% CPU, 821 Lips)
false.
All three of these approaches are linear time proportional to the length of the list.
Here's an alternative version using the built-in reverse/2 instead of append/3.
swap_first_last([First|A], [Last|B]) :-
reverse(A, [Last|RevMid]),
reverse([First|RevMid], B).
It's perhaps slightly less efficient than the version Sergey showed with append/3. Like the append/3 version, if you want swap_first_last([X], [X]). and/or swap_first_last([], []). to be true, you have to add them as facts/predicates. But they aren't needed for lists of length 2 or greater.
This predicate says, [Last|B] is the same as [First|A] with the first and last elements swapped if [Last|RevMid] is the reverse of list A, and B is the reverse of [First|RevMid].
The first reverse reverses the tail of the first list (A) yielding a list which has its own head and tail, [Last|RevMid]. At this point, Last represents the last element of the first list, and RevMid represents the "middle" list, not including the first and last elements, but in reverse order.
The second reverse then takes the first list's head, First, and uses it as the head for a new list which is [First|RevMid]. If we reverse this list, we'll end up with the "middle" list in the correct order and First slapped on the end (this list is called B) so we've got the original first element as the last element of this list and all the right middle elements. All that's left is to have the first lists last element (Last) prepended as the head, which occurs in the head of the clause as [Last|B].
By way of example, let's take the query, swap_first_last([a,b,c,d,e], S).:
Unify [First|A] with [a,b,c,d,e] yielding, First = a and A = [b,c,d,e]
Query reverse([b,c,d,e], [Last|RevMid]) which yields, [Last|T] = [e,d,c,b], or, Last = e and RevMid = [d,c,b].
Query reverse([a|[d,c,b]], B) which is reverse([a,d,c,b], B) yielding, B = [b,c,d,a]
Instantiating [Last|B] as [e|[b,c,d,a]] or [e,b,c,d,a]
Using a dcg:
swap_first_last(Xs,Ys) :-
phrase(([First],seq(Seq),[Last]), Xs),
phrase(([Last], seq(Seq),[First]), Ys).
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
But this - similarly to the other suggestions, does not terminate if only Ys is a list. A first attempt would be to constrain the lists to the same length:
same_length([], []).
same_length([_|Xs], [_|Ys]) :-
same_length(Xs, Ys).
swap_first_last(Xs,Ys) :-
same_length(Xs, Ys),
phrase(([First],seq(Seq),[Last]), Xs),
phrase(([Last], seq(Seq),[First]), Ys).
But what, if the lists differ in the second element? Like in
?- Xs = [_,a|_], Ys = [_,b|_], swap_first_last(Xs, Ys).
Xs = [b,a], Ys = [a,b]
; loops.
Our predicate still could terminate with:
swap_first_last(Xs, [Last|Ys]) :-
phrase(([First],dseq(Ys,[First]),[Last]), Xs).
dseq(Xs,Xs) --> [].
dseq([X|Xs0],Xs) --> [X], dseq(Xs0,Xs).
Related
How can I get a list of power of two until N in prolog. Such that if I write func(5,L) I will get L = [2,4,8,16,32].
This is what I do, but result is not good. Can you help me correct my code and explain what is the problem.
func(N,L):- helpstwo(N,R), reverse(R, L).
helpstwo(1,[2]):- !.
helpstwo(N,[H|[H1,T]]):- N1 is N-1, helpstwo(N1,[H1|T]), H is H1*2.
This is what I get
L = [[8, [4, [2, []]]], 16, 32]
Thanks
powers_of_2(Len, Lst) :-
% Conveniently avoids having to keep an element count
length(Lst, Len),
powers_of_2_(Lst, 1).
% Reached end of list when Tail is empty
powers_of_2_([], _).
powers_of_2_([H|T], N) :-
% Simply multiply the previous number by 2
H is N * 2,
powers_of_2_(T, H).
This is nicely performant - e.g. in swi-prolog:
?- time(powers_of_2(50_000, L)).
% 100,005 inferences, 0.434 CPU in 0.465 seconds (93% CPU, 230470 Lips)
L = [2,4,8,16,32,64,128,256,512,1024,2048,4096,8192, ...
A simple 1-liner:
powers_of_2(N , Ps ) :- findall( P , ( between(0,N,E), P is 2^E ) , Ps ) .
Adding all lengths of sublists In prolog
Using
sum([],ADD,ADD).
sum([P|R], ADD, OUTPUT):- X is ADD + P,
sum(R,X,ADD).
Avoiding the slow recursion:
sublists_len(SubLists, Length) :-
sublists_len_(SubLists, 0, Length).
sublists_len_([], Len, Len).
sublists_len_([H|T], Upto, Len) :-
length(H, LenH),
Upto1 is Upto + LenH,
sublists_len_(T, Upto1, Len).
Performance comparison in swi-prolog:
?- length(SubLists, 5000000), maplist(=([1, 2]), SubLists), time(sublists_len(SubLists, Len)).
% 20,000,002 inferences, 2.730 CPU in 2.697 seconds (101% CPU, 7326281 Lips)
?- length(SubLists, 5000000), maplist(=([1, 2]), SubLists), time(list_subsum(SubLists, Len)).
% 20,000,001 inferences, 7.581 CPU in 7.500 seconds (101% CPU, 2638194 Lips)
nestedlist_length(List, Length) :-
flatten(List, Flat),
length(Flat, Length).
Your code: sum([],ADD,ADD). says that the sum of the lengths of an empty list could be anything, as long as you repeat it enough. sum([], 50, 50). works there, so does sum([], dog, dog)..
This: sum([P|R], ADD, OUTPUT):- X is ADD + P, sum(R,X,ADD). says that you never use OUTPUT again, and that you try and add the head onto nothing and then stuff that down into the sum of the tail which can never get a value because there's nowhere that you say an empty list has length sum of 0.
list_subsum([], 0).
list_subsum([H|T], Output) :-
length(H, HLen),
list_subsum(T, TLengthSum),
Output is HLen + TLengthSum.
Empty lists are length 0, lists of things get the length of the head, get the length of the tail, then output those two added together.
The tail will eventually be [] which will have a length 0 which stops the process.
I'm trying to figure out if I have an infinite loop in my Prolog program, or if I just did a bad job of writing it, so its slow. I'm trying to solve the square sum chains problem from the dailyprogrammer subreddit. Given a number N, find an ordering of the numbers 1-N (inclusive) such that the sum of each pair of adjacent numbers in the ordering is a perfect square. The smallest N that this holds for is 15, with the ordering [8, 1, 15, 10, 6, 3, 13, 12, 4, 5, 11, 14, 2, 7, 9]. This is the code that I'm trying to use to solve the problem:
is_square(Num):- is_square_help(Num, 0).
is_square_help(Num, S):- Num =:= S * S.
is_square_help(Num, S):-
Num > S * S,
T is S+1,
is_square_help(Num, T).
is_square_help(Num, S):- Num < S * S, fail.
contains(_, []):- fail.
contains(Needle, [Needle|_]).
contains(Needle, [_|Tail]):- contains(Needle, Tail).
nums(0, []).
nums(Num, List) :- length(List, Num), nums_help(Num, List).
nums_help(0, _).
nums_help(Num, List) :-
contains(Num, List),
X is Num - 1,
nums_help(X, List).
square_sum(Num, List) :-
nums(Num, List),
square_sum_help(List).
square_sum_help([X, Y|T]) :-
Z is X + Y,
is_square(Z),
square_sum_help(T).
Currently, when I run square_sum(15, List)., the program does not terminate. I've left it alone for about 10 minutes, and it just keeps running. I know that there are problems that take a long time to solve, but others are reportedly generating answers in the order of milliseconds. What am I doing wrong here?
SWI-Prolog allows this compact implementation
square_sum(N,L) :-
numlist(1,N,T),
select(D,T,R),
adj_squares(R,[D],L).
adj_squares([],L,R) :- reverse(L,R).
adj_squares(T,[S|Ss],L) :-
select(D,T,R),
float_fractional_part(sqrt(S+D))=:=0,
adj_squares(R,[D,S|Ss],L).
that completes really fast for N=15
edit as suggested, building the list in order yields better code:
square_sum(N,L) :-
numlist(1,N,T),
select(D,T,R),
adj_squares(R,D,L).
adj_squares([],L,[L]).
adj_squares(T,S,[S|L]) :-
select(D,T,R),
float_fractional_part(sqrt(S+D))=:=0,
adj_squares(R,D,L).
edit
the code above becomes too slow when N grows. I've changed strategy, and attempt now to find an Hamiltonian path into the graph induced by the binary relation. For N=15 it looks like
(here is the code to generate the Graphviz script:
square_pairs(N,I,J) :-
between(1,N,I),
I1 is I+1,
between(I1,N,J),
float_fractional_part(sqrt(I+J))=:=0.
square_pairs_graph(N) :-
format('graph square_pairs_N_~d {~n', [N]),
forall(square_pairs(N,I,J), format(' ~d -- ~d;~n', [I,J])),
writeln('}').
)
and here the code for lookup a path
hamiltonian_path(N,P) :-
square_pairs_struct(N,G),
between(1,N,S),
extend_front(1,N,G,[S],P).
extend_front(N,N,_,P,P) :- !.
extend_front(Len,Tot,G,[Node|Ins],P) :-
arg(Node,G,Arcs),
member(T,Arcs),
\+memberchk(T,Ins),
Len1 is Len+1,
extend_front(Len1,Tot,G,[T,Node|Ins],P).
struct_N_of_E(N,E,S) :-
findall(E,between(1,N,_),As),
S=..[graph|As].
square_pairs_struct(N,G) :-
struct_N_of_E(N,[],G),
forall(square_pairs(N,I,J), (edge(G,I,J),edge(G,J,I))).
edge(G,I,J) :-
arg(I,G,A), B=[J|A], nb_setarg(I,G,B).
Here is a solution using Constraint Logic Programming:
squares_chain(N, Cs) :-
numlist(1, N, Ns),
phrase(nums_partners(Ns, []), NPs),
group_pairs_by_key(NPs, Pairs),
same_length(Ns, Pairs),
pairs_values(Pairs, Partners),
maplist(domain, Is0, Partners),
circuit([D|Is0]),
labeling([ff], Is0),
phrase(chain_(D, [_|Is0]), Cs).
chain_(1, _) --> [].
chain_(Pos0, Ls0) --> [Pos],
{ Pos0 #> 1, Pos #= Pos0 - 1,
element(Pos0, Ls0, E) },
chain_(E, Ls0).
plus_one(A, B) :- B #= A + 1.
domain(V, Ls0) :-
maplist(plus_one, Ls0, Ls),
foldl(union_, Ls, 1, Domain),
V in Domain.
union_(N, Dom0, Dom0\/N).
nums_partners([], _) --> [].
nums_partners([N|Rs], Ls) -->
partners(Ls, N), partners(Rs, N),
nums_partners(Rs, [N|Ls]).
partners([], _) --> [].
partners([L|Ls], N) -->
( { L + N #= _^2 } -> [N-L]
; []
),
partners(Ls, N).
Sample query and answers:
?- squares_chain(15, Cs).
Cs = [9, 7, 2, 14, 11, 5, 4, 12, 13|...] ;
Cs = [8, 1, 15, 10, 6, 3, 13, 12, 4|...] ;
false.
A longer sequence:
?- time(squares_chain(100, Cs)).
15,050,570 inferences, 1.576 CPU in 1.584 seconds (99% CPU, 9549812 Lips)
Cs = [82, 87, 57, 24, 97, 72, 28, 21, 60|...] .
What you are doing wrong is mainly that you generate the whole list before you start testing.
The two clauses that call fail are pointless. Removing them will not change the program. The only reason for doing that is if you do something side-effect-y, like printing output.
Your code for generating the list, and all permutations, seems to work, but it can be done much simpler by using select/3.
You don't seem to have a base case in square_sum_help/1, and you also seem to only check every other pair, which would have lead to problems in some years or whatever when your program had gotten around to checking the correct ordering.
So, by interleaving the generation and testing, like this
square_sum(Num,List) :-
upto(Num,[],List0),
select(X,List0,List1),
square_sum_helper(X,List1,[],List).
square_sum_helper(X1,Rest0,List0,List) :-
select(X2,Rest0,Rest),
Z is X1 + X2,
is_square(Z,0),
square_sum_helper(X2,Rest,[X1|List0],List).
square_sum_helper(_,[],List0,List) :- reverse(List0,List).
is_square(Num,S) :-
Sqr is S * S,
( Num =:= Sqr ->
true
; Num > Sqr,
T is S + 1,
is_square(Num,T) ).
upto(N,List0,List) :-
( N > 0 ->
M is N - 1,
upto(M,[N|List0],List)
; List = List0 ).
the correct result is produced in around 9 msec (SWI Prolog).
?- ( square_sum(15,List), write(List), nl, fail ; true ).
[8,1,15,10,6,3,13,12,4,5,11,14,2,7,9]
[9,7,2,14,11,5,4,12,13,3,6,10,15,1,8]
?- time(square_sum(15,_)).
% 37,449 inferences, 0.009 CPU in 0.009 seconds (100% CPU, 4276412 Lips)
Edit: fixed some typos.
contains/2:
clause contains(_, []):- fail. is buggy and redundant at best.
you should type in the body !, fail.
But it's not needed because that what is unprovable shouldn't be mentioned (closed world assumption).
btw contains/2 is in fact member/2 (built-in)
I want to write predicate that generates the Fibonacci series for given N.
fibon(6, X) -> X = [0,1,1,2,3,5].
I have a predicate to generate the N-th element of the Fibonacci series:
fib(0, 0).
fib(1, 1).
fib(N, F) :-
N > 1,
N1 is N - 1,
N2 is N - 2,
fib(N1, F1),
fib(N2, F2),
F is F1 + F2.
And I try to write fibon/2, but it doesn't work:
fibon(N, [H|T]) :-
fib(N, H),
N1 is N - 1,
fibon(N1, T).
I solved it like the following:
at_the_end(X, [], [X]).
at_the_end(X, [H|T], [H|T2]) :-
at_the_end(X, T, T2).
revert([], []).
revert([H|T], Out) :-
revert(T, Out1),
at_the_end(H, Out1, Out).
fib(0, 0).
fib(1, 1).
fib(N, F) :-
N > 1,
N1 is N - 1,
N2 is N - 2,
fib(N1, F1),
fib(N2, F2),
F is F1 + F2.
fibon(0, [0]).
fibon(N, [H|T]) :-
fib(N, H),
N1 is N - 1,
fibon(N1, T).
fibonacci(In, Out) :-
fibon(In, Out1),
revert(Out1, Out).
You can squeeze out a little more speed by making the recursive predicate tail recursive:
fib_seq(0,[0]). % <- base case 1
fib_seq(1,[0,1]). % <- base case 2
fib_seq(N,Seq) :-
N > 1,
fib_seq_(N,SeqR,1,[1,0]), % <- actual relation (all other cases)
reverse(SeqR,Seq). % <- reverse/2 from library(lists)
fib_seq_(N,Seq,N,Seq).
fib_seq_(N,Seq,N0,[B,A|Fs]) :-
N > N0,
N1 is N0+1,
C is A+B,
fib_seq_(N,Seq,N1,[C,B,A|Fs]). % <- tail recursion
First let's observe that your example query works as expected:
?- fib_seq(6,L).
L = [0, 1, 1, 2, 3, 5, 8] ;
false.
Note that the list doesn't have six elements, as in your example at the beginning of your post, but seven. This is because the predicate starts counting at zero (BTW this is the same behaviour as that of the predicate fibonacci/2 that you added to your post).
For comparison (with fib/2 from #Enigmativity's post) reasons, let's either remove the goal reverse/2 from fib_seq/2 (then you'd get all solutions except N=0 and N=1 in reverse order):
?- time((fib(50000,L),false)).
% 150,001 inferences, 0.396 CPU in 0.396 seconds (100% CPU, 379199 Lips)
false.
?- time((fib_seq(50000,L),false)).
% 150,002 inferences, 0.078 CPU in 0.078 seconds (100% CPU, 1930675 Lips)
false.
Or leave fib_seq/2 as it is and measure fib/2 with an additional goal reverse/2 (then R in the fib/2 solution corresponds to L in the fib_seq/2 solution):
?- time((fib(50000,L),reverse(L,R),false)).
% 200,004 inferences, 0.409 CPU in 0.409 seconds (100% CPU, 488961 Lips)
false.
?- time((fib_seq(50000,L),false)).
% 200,005 inferences, 0.088 CPU in 0.088 seconds (100% CPU, 2267872 Lips)
false.
On a side note, I would urge you to compare your predicate fibonacci/2 with the posted solutions when trying to get bigger lists, say N > 30.
If you're happy to reverse the order of the results for the sequence then this works:
fib(0, [0]).
fib(1, [1,0]).
fib(N, [R,X,Y|Zs]) :-
N > 1,
N1 is N - 1,
fib(N1, [X,Y|Zs]),
R is X + Y.
Then ?- fib(15,Z). gives me [610, 377, 233, 144, 89, 55, 34, 21, 13, 8, 5, 3, 2, 1, 1, 0].
It would be easy to throw in a reverse/3 predicate:
reverse([],Z,Z).
reverse([H|T],Z,A) :- reverse(T,Z,[H|A]).
Just for fun using scanl. and some standard dcgs.
:-use_module(library(clpfd)).
my_plus(X,Y,Z):-
Z#>=0,
Z#=<1000, % Max size optional
Z#=X+Y.
list([]) --> [].
list([L|Ls]) --> [L], list(Ls).
concatenation([]) --> [].
concatenation([List|Lists]) -->
list(List),
concatenation(Lists).
fib(Len,List1):-
X0=1,
length(List1,Len),
length(End,2),
MiddleLen #= Len - 3,
length(Middle,MiddleLen),
phrase(concatenation([[X0],Middle,End]), List1),
phrase(concatenation([[X0],Middle]), List2),
phrase(concatenation([Middle,End]), List3),
scanl(my_plus,List2,X0,List3).
If you want to collect a list of the first N elements of the Fibonacci series you can use the rule below. Just remember to initialize the first 2 predicates.
fib(0, [1]).
fib(1, [1, 1]).
fib(N, L) :-
N > 1,
N1 is N - 1,
N2 is N - 2,
fib(N1, F1),
last(F1, L1),
fib(N2, F2),
last(F2, L2),
L_new is L1 + L2,
append(F1, [L_new], L).
I need some help writing a predicate in Prolog that, given a number as input, returns a list of lists with numbers that add up to it.
Let's call the predicate addUpList/2, it should work like this:
?- addUpList(3,P).
P = [[1,2], [2,1], [1,1,1]]. % expected result
I'm having so much trouble figuring this out I'm beginning to think it's impossible. Any ideas? Thanks in advance.
Try this:
condense([], Rs, Rs).
condense([X|Xs], Ys, Zs) :-
condense(Xs, [X|Ys], Zs).
condense([X, Y|Xs], Ys, Zs) :-
Z is X + Y,
condense([Z|Xs], Ys, Zs).
condense(Xs, Rs) :-
condense(Xs, [], Rs).
expand(0, []).
expand(N, [1|Ns]) :-
N > 0,
N1 is N - 1,
expand(N1, Ns).
addUpList(N, Zs) :-
expand(N, Xs),
findall(Ys, condense(Xs, Ys), Zs).
Let me know what marks I get. :-)
The rule num_split/2 generates ways of splitting a number into a list, where the first element X is any number between 1 and N and the rest of the list is a split of N-X.
num_split(0, []).
num_split(N, [X | List]) :-
between(1, N, X),
plus(X, Y, N),
num_split(Y, List).
In order to get all such splits, just call findall/3 on num_split/2.
add_up_list(N, Splits) :-
findall(Split, num_split(N, Split), Splits).
Usage example:
?- add_up_list(4, Splits).
Splits =
[[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]].
See also the post by #hardmath which gives the same answer with a bit more explanation.
The example given in the Question suggests that compositions (ordered partitions) of any positive integer N ≤ 10 are wanted. Note however that the solution [3] for N=3 seems to have been omitted/overlooked. The number of compositions of N is 2^(N-1), so N=10 gives a long list but not an unmanageable one.
It is also desired to collect all such solutions into a list, something that findall/3 can do generically after we write a predicate composition/2 that generates them.
The idea is to pick the first summand, anything between 1 and N, subtract it from the total and recurse (stopping with an empty list when the total reaches zero). SWI-Prolog provides a predicate between/3 that can generate those possible first summands, and Amzi! Prolog provides a similar predicate for/4. For the sake of portability we write our own version here.
summand(Low,High,_) :-
Low > High,
!,
fail.
summand(Low,High,Low).
summand(Low,High,Val) :-
Now is Low + 1,
summand(Now,High,Val).
composition(0,[ ]).
composition(N,[H|T]) :-
summand(1,N,H),
M is N - H,
composition(M,T).
Given the above Prolog source code, compiled or interpreted, a list of all solutions can be had in this way:
?- findall(C,composition(3,C),L).
C = H126
L = [[1, 1, 1], [1, 2], [2, 1], [3]]
Of course some arrangement of such a list of solutions or the omission of the singleton list might be required for your specific application, but this isn't clear as the Question is currently worded.
There are plenty of great answers to this question already, but here is another solution to this problem for you to consider. This program differs from the others in that it is very efficient, and generates non-redundant solutions of lists which are assumed to represent sets of integers which add up to the specified number.
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).
Your implementation of addUpList/2 can be achieved by:
addUpList(N, P) :-
findall(L, gen(N, L), P).
Which should give you the following behaviour:
?- addUpList(4,L).
L = [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]].
Note that the list containing one 2 and two 1s only appears once in this result set; this is because gen/4 computes unique sets of integers which add up to the specified number.
This answer is somewhere between
#Kaarel's answer and
#sharky's "efficient" answer.
Like #sharky's code, we impose an ordering relation between adjacent list items to restrict the size of the solution space---knowing how to inflate it if we ever need to. So the solution sets of break_down/2 and gen/2 by #sharky are equal (disregarding list reversal).
And as for performance, consider:
?- time((break_down(40,_),false)).
% 861,232 inferences, 0.066 CPU in 0.066 seconds (100% CPU, 13127147 Lips)
false.
?- time((gen(40,_),false)).
% 8,580,839 inferences, 0.842 CPU in 0.842 seconds (100% CPU, 10185807 Lips)
false.