Here's a direct recursive implementation using simple integer arithmetic and backtracking:
break_down(N,L) :- break_ref_down(N,1,L). % reference item is initially 1 break_ref_down(0,_,[]). break_ref_down(N,Z0,[Z|Zs]) :- between(Z0,N,Z), % multiple choices N0 is NZ, break_ref_down(N0,Z,Zs). % pass on current item as reference
Request example:
?- break_down(8,Zs). Zs = [1,1,1,1,1,1,1,1] ; Zs = [1,1,1,1,1,1,2] ; Zs = [1,1,1,1,1,3] ; Zs = [1,1,1,1,2,2] ; Zs = [1,1,1,1,4] ; Zs = [1,1,1,2,3] ; Zs = [1,1,1,5] ; Zs = [1,1,2,2,2] ; Zs = [1,1,2,4] ; Zs = [1,1,3,3] ; Zs = [1,1,6] ; Zs = [1,2,2,3] ; Zs = [1,2,5] ; Zs = [1,3,4] ; Zs = [1,7] ; Zs = [2,2,2,2] ; Zs = [2,2,4] ; Zs = [2,3,3] ; Zs = [2,6] ; Zs = [3,5] ; Zs = [4,4] ; Zs = [8] ; false.