Printing minimum answer as list? - prolog

I have a predicate min1([4,2,3,5],L). I want it to return the minimum number for each time the list is sent back as a tail. Example:
List Head|Tail Tail L
[4,2,3,5] [4,2,3,5] [2,3,5] 2
[2,3,5] [2,3,5] [3,5] 2
[3,5] [3,5] [5] 3
[5] [5] [] 5
My code:
min([X],[X]).
min([H|T],Min):-
min(T,TMin),
H=<TMin,
Min is H.
min([H|T],Min):-
min(T,TMin),
H>TMin,
Min is TMin.
min1([],[]).
min1([H|T],L):-
min([H|T],R),
write(R),
min1(T,R).
The problem that I am facing is with L. It does not print anything. When I use write(R), it's showing me the right result but I am unable to print it as a List in L. What should I correct?
?-min1([4,2,3,5],L).
223[5]
L = []
By removing write(R):
?-min1([4,2,3,5],L).
false

One of your problems is trying to understand your program using I/O. This is often not a very useful thing to do in Prolog. If you are interested in the suffixes of the list, even just for debugging, expose those suffixes as an argument of the predicate. This is much clearer than trying to print intermediate results. Because Prolog backtracks, it can be hard to understand what an intermediate result means, at what point it exists, and whether you can actually use it before backtracking makes it disappear.
Your other problem is trying to do too much at once. Take things step by step. Prolog is a language that is well suited for decomposing problems into tiny bits. It also often forces you to decompose a problem into tiny bits.
So, first: Enumerating a list's suffixes (including the list itself as a trivial suffix).
list_suffix(List, List).
list_suffix([_ | Suffix], SuffixOfSuffix) :-
list_suffix(Suffix, SuffixOfSuffix).
?- list_suffix([4, 2, 3, 5], Suffix).
Suffix = [4, 2, 3, 5] ;
Suffix = [2, 3, 5] ;
Suffix = [3, 5] ;
Suffix = [5] ;
Suffix = [].
Then, separately, computing the minimum of a list. Your implementation is almost OK for this, the first clause needed to unwrap [X] (though it could be more efficient by using an accumulator):
list_minimum([X], X).
list_minimum([H | T], Min):-
list_minimum(T, TMin),
H =< TMin,
Min is H.
list_minimum([H | T], Min):-
list_minimum(T, TMin),
H > TMin,
Min is TMin.
?- list_minimum([4, 2, 3, 5], Minimum).
Minimum = 2 ;
false.
Now, and only now, we are in a position to tackle the combined problem:
?- list_suffix([4, 2, 3, 5], Suffix), list_minimum(Suffix, Minimum).
Suffix = [4, 2, 3, 5],
Minimum = 2 ;
Suffix = [2, 3, 5],
Minimum = 2 ;
Suffix = [3, 5],
Minimum = 3 ;
Suffix = [5],
Minimum = 5 ;
false.
You can pack this up in a predicate definition:
list_suffix_suffixminimum(List, Suffix, SuffixMinimum) :-
list_suffix(List, Suffix),
list_minimum(Suffix, SuffixMinimum).
?- list_suffix_suffixminimum([4, 2, 3, 5], Suffix, SuffixMinimum).
Suffix = [4, 2, 3, 5],
SuffixMinimum = 2 ;
Suffix = [2, 3, 5],
SuffixMinimum = 2 ;
Suffix = [3, 5],
SuffixMinimum = 3 ;
Suffix = [5],
SuffixMinimum = 5 ;
false.
Maybe even without exposing the suffix:
list_suffixminimum(List, SuffixMinimum) :-
list_suffix(List, Suffix),
list_minimum(Suffix, SuffixMinimum).
?- list_suffixminimum([4, 2, 3, 5], SuffixMinimum).
SuffixMinimum = 2 ;
SuffixMinimum = 2 ;
SuffixMinimum = 3 ;
SuffixMinimum = 5 ;
false.
Now, and only now that the problem has been solved, you can add I/O if you feel like it. Although at this point, why would you?

Related

Write a program in prolog that determines if there are exactly three values in such a way that they add upto a sum of N

Eg:
List[1,2,3,4,5,6] with N equal to 6 should print true because there are exactly 3 values that add upto 6. 1+2+3.
List[2,5,7,9] with N equal to 12 should print false as there are no 3 elements that add upto 12.
Let's maybe start with a more general predicate that describes the relation between a list, a sublist of said list and the sum of numbers in the sublist. To make it obvious which argument is what, it is opportune to chose a descriptive name for the predicate, say sum_ofsub_fromlist/3. Now let's observe that if the first argument is the sum of the numbers in the sublist, then successively subtracting those numbers from the sum yields zero, e.g.: X=A+B → X-A-B=0. So there will be a base case that contains 0 as the sum and [] as the sublist (rule 1) and a recursive rule that subtracts the elements of the sublist from the sum (rule 2). And since a sublist does not contain all elements of the list it's taken from in general, there will be a recursive rule for skipping elements of the list that do not occur in the sublist (rule 3). This rule is only needed as long as there are still elements in the sublist, so a constraint would be beneficial, that prevents this rule from succeeding once the sublist is empty. These ideas can be realized in Prolog like so:
sum_ofsub_fromlist(0,[],_L). % rule 1
sum_ofsub_fromlist(X,[A|Bs],[A|As]) :- % rule 2
X0 is X-A,
sum_ofsub_fromlist(X0,Bs,As).
sum_ofsub_fromlist(X,Bs,[_A|As]) :- % rule 3
dif(Bs,[]), % constraint: sublist not empty
sum_ofsub_fromlist(X,Bs,As).
You can query this predicate to assure yourself that it delivers all sublists for the given sum in your examples:
?- sum_ofsub_fromlist(6,S,[1,2,3,4,5,6]).
S = [1, 2, 3] ;
S = [1, 5] ;
S = [2, 4] ;
S = [6] ;
false.
?- sum_ofsub_fromlist(12,S,[2,5,7,9]).
S = [5, 7] ;
false.
Building on this you can then write a calling predicate that only succeeds for sublists of length three:
sum_oftriple_fromlist(S,T,L) :-
T=[_,_,_], % T has to be a triple
sum_ofsub_fromlist(S,T,L).
This predicate yields the answers you desire:
?- sum_oftriple_fromlist(6,T,[1,2,3,4,5,6]).
T = [1, 2, 3] ;
false.
?- sum_oftriple_fromlist(12,T,[2,5,7,9]).
false.
Note that the predicate is also working with negative numbers:
?- sum_oftriple_fromlist(6,T,[-5,-3,-1,2,4,7,8,9]).
T = [-5, 2, 9] ;
T = [-5, 4, 7] ;
T = [-3, 2, 7] ;
false.
?- sum_oftriple_fromlist(-6,T,[-6,-5,-4,-3,-2,-1,2,4]).
T = [-6, -4, 4] ;
T = [-6, -2, 2] ;
T = [-5, -3, 2] ;
T = [-3, -2, -1] ;
false.
However, due to the use of is/2, the predicate only works if the first and the third arguments are ground:
?- sum_oftriple_fromlist(S,T,[1,2,3,4,5,6]).
ERROR: is/2: Arguments are not sufficiently instantiated
Exception: (7) sum_ofsub_fromlist(_G918, [_G1016, _G1019, _G1022], [1, 2, 3, 4, 5, 6]) ?
?- sum_oftriple_fromlist(6,T,[A,B,C,D,E,F]).
ERROR: is/2: Arguments are not sufficiently instantiated
Exception: (7) sum_ofsub_fromlist(6, [_G2121, _G2124, _G2127], [_G1945, _G1948, _G1951, _G1954, _G1957, _G1960]) ?
If that's fine with you, you can stop here. Alternatively, you could opt to make the predicate more versatile by using CLP(FD). Just apply these minor changes to your code:
:- use_module(library(clpfd)). % <- new
sum_oftriple_fromlist(S,T,L) :-
T=[_,_,_],
sum_ofsub_fromlist(S,T,L).
sum_ofsub_fromlist(0,[],_L).
sum_ofsub_fromlist(X,[A|Bs],[A|As]) :-
X0 #= X-A, % <- change
sum_ofsub_fromlist(X0,Bs,As).
sum_ofsub_fromlist(X,Bs,[_A|As]) :-
dif(Bs,[]),
sum_ofsub_fromlist(X,Bs,As).
Now the above queries deliver answers:
?- sum_oftriple_fromlist(S,T,[1,2,3,4,5,6]).
S = 6,
T = [1, 2, 3] ;
S = 7,
T = [1, 2, 4] ;
S = 8,
T = [1, 2, 5] ;
. % another
. % seventeen
. % results here
The second query, however, yields residual goals (see documentation for details) as results:
?- sum_oftriple_fromlist(6,T,[A,B,C,D,E,F]).
T = [A, B, C],
_G2424+A#=6,
C+B#=_G2424 ;
T = [A, B, D],
_G2424+A#=6,
D+B#=_G2424 ;
.
.
.
To get actual numbers, you have to restrict the range of the numbers and subsequently label the variables in the list:
?- L=[A,B,C,D,E,F], sum_oftriple_fromlist(6,T,L), L ins 1..6, label(L).
L = [1, 1, 4, 1, 1, 1],
A = B, B = D, D = E, E = F, F = 1,
C = 4,
T = [1, 1, 4] ;
L = [1, 1, 4, 1, 1, 2],
A = B, B = D, D = E, E = 1,
C = 4,
F = 2,
T = [1, 1, 4] ;
.
.
.
Possibly you are only interested in lists where every number only appears once:
?- L=[A,B,C,D,E,F], all_distinct(L), sum_oftriple_fromlist(6,T,L), L ins 1..6, label(L).
L = [1, 2, 3, 4, 5, 6],
A = 1,
B = 2,
C = 3,
D = 4,
E = 5,
F = 6,
T = [1, 2, 3] ;
L = [1, 2, 3, 4, 6, 5],
A = 1,
B = 2,
C = 3,
D = 4,
E = 6,
F = 5,
T = [1, 2, 3] ;
.
.
.
Or maybe you don't even want to restrict the sum:
?- L=[A,B,C,D,E,F], all_distinct(L), sum_oftriple_fromlist(S,T,L), L ins 1..6, label(L).
L = [1, 2, 3, 4, 5, 6],
A = 1,
B = 2,
C = 3,
D = 4,
E = 5,
F = S, S = 6, % sum = 6
T = [1, 2, 3] ;
.
.
.
L = [1, 2, 4, 3, 5, 6],
A = 1,
B = 2,
C = 4,
D = 3,
E = 5,
F = 6,
S = 7, % sum = 7
T = [1, 2, 4] ;
.
.
.
As you can see the CLP(FD) version of the predicate resembles a true relation as opposed to the non-CLP(FD) version. And of course your example queries yield the same answers with both versions.
Your code only considers the first 3 items in the list, and not any other combinations.
The most natural way to structure a solution involving a list is to base your recursion on the structure of the list. So:
If the first element of the list (say, X) is to be included in the 3 values that sum to N, we need to find a way to find 2 values in the rest of the list that sum to N-X.
If it isn't, just try to solve the problem using the rest of the list.
Note that you may need a "helper" version of your predicate that allows you to add other parameters. In this case, knowing how many values you need to add up would be helpful.

How would I modify my predicate to jumble my output result?

So I'm experimenting with some stuff. I have the following simple predicate:
insert([],Y,[Y]).
insert([H|T],Y,[H,Y|T]).
So this'll insert my element Y into my list. However this always puts it in the same place, which is in the middle. But say I wanted it to be more like the following:
?- insert([1,2,3], 4, Zs).
should succeed four times and give the following answers:
Zs = [4, 1, 2, 3]
Zs = [1, 4, 2, 3]
Zs = [1, 2, 4, 3]
Zs = [1, 2, 3, 4].
How would I modify my predicate accordingly?
another useful builtin, extended in SWI-Prolog to handle insertion as well as selection:
?- nth1(_,X,a,[1,2,3]).
X = [a, 1, 2, 3] ;
X = [1, a, 2, 3] ;
X = [1, 2, a, 3] ;
X = [1, 2, 3, a] ;
false.
just ignore first argument (the index itself)
If you want to find possible position of an element in a list, then you have to find all possible concatenation of this list containing the element to insert. This can be described using append/3 predicate:
insert(X,Y,Z):- append(A, B, X), append(A, [Y|B], Z).
This predicate states that exists a concatenation of two sublist that returns list X, and this two sublist concatenated with the value Y in the head of the second sublist, returns list Z.
?- insert([1,2,3], 4, Z).
Z = [4, 1, 2, 3]
Z = [1, 4, 2, 3]
Z = [1, 2, 4, 3]
Z = [1, 2, 3, 4]
false

Find cycle of permutation in Prolog

I'm new in Prolog world. I want to find out if a permutation is 'one-cycle'.
I'm trying to write a predicate to generate cycle from permutation. Here is my code (not working):
find_next([E|_], [N|_], E, N).
find_next([_|L1], [_|L2], E, N) :-
find_next(L1, L2, E, N).
find_cycle(L1, L2, E, C) :-
append(C, [E], C1),
find_next(L1, L2, E, N),
find_cycle(L1, L2, N, C1).
Permutations are represented by two lists (for example: [1, 2, 3, 4], [3, 4, 2, 1]).
find_next generates next cycle element (N) for element (E) (for example: E=1, N=3).
find_cycle looks for cycle (C) starting from element E.
Unfortunately I don't know how to stop my recurrence when find_next returns N same as first element of cycle C.
EDIT: some examples.
find_cycle([1, 2, 3, 4], [3, 4, 2, 1], 1, X).
should return:
X = [1, 3, 2, 4];
false.
and:
find_cycle([1, 2, 3, 4], [4, 2, 1, 3], 1, X).
should return:
X = [1, 4, 3];
false.
Why?
It is simple decomposition of permutation into disjointed cycles.
Let's analyze second permutation: [1, 2, 3, 4], [4, 2, 1, 3].
Take first element: 1.
1 goes into 4
4 goes into 3
3 goes into 1
end of cycle.
This permutation is not decomposable into one cycle (length of generated cycle is smaller than length of permutation).
To find all the cycles of the permutation:
perm_to_cycles(Perm, NPerm, Cycles):-
perm_struct(Perm, NPerm, PermS),
perm_to_cycles(PermS, [], [], Cycles),
!.
perm_to_cycles([], _, Cycles, Cycles).
%perm_to_cycles([p(Id, Id)|PermS], _, InCycles, Cycles):-
% perm_to_cycles(PermS, [], InCycles, Cycles). % This clause would remove fixed elements
perm_to_cycles([p(Id, Item)|PermS], Cycle, InCycles, Cycles):-
(select(p(Item, NId), PermS, NPermS) ->
perm_to_cycles([p(Item, NId)|NPermS], [Id|Cycle], InCycles, Cycles) ;
(
reverse([Id|Cycle], RCycle),
perm_to_cycles(PermS, [], [RCycle|InCycles], Cycles)
)
).
perm_struct([], [], []).
perm_struct([Item|Perm], [NItem|NPerm], [p(Item, NItem)|PermS]):-
perm_struct(Perm, NPerm, PermS).
The commented clause would remove fixed elements of list of cycles.
To get only one-cycle permutations you can constrain the third argument to be a one-element list. For example:
?- perm_to_cycles([1, 2, 3, 4], [3, 4, 2, 1], [X]).
X = [1, 3, 2, 4]
?- perm_to_cycles([1, 2, 3, 4], [4, 2, 1, 3], [X]).
false.
?- perm_to_cycles([1, 2, 3, 4], [4, 2, 1, 3], X).
X = X = [[2], [1, 4, 3]].
-Hi Dave, here is my solution to the problem. I followed your instructions like 1 goes to 4 , 4 goes to 3 etc and here is what I came up with. First I create arcs between the elements of the two lists(permutations) and then I simply move through the created graph using find_cycle (until our nodes start repeating ). I tried to use variable names that are self explanatory but if have hard time understanding the code let me know.
create_arcs([],[],[]).
create_arcs([H|T],[H1|T1],[arc(H,H1)|RezArc]) :- create_arcs(T,T1,RezArc).
find_cycle(Perm,Perm2,E,X) :- create_arcs(Perm,Perm2,Arcs),
find_cycle(E,Arcs,[],X).
find_cycle(StartNode,Arcs,LocRez,LocRez) :- member(arc(StartNode,NextNode),Arcs),
member(StartNode,LocRez).
find_cycle(StartNode,Arcs,LocRez,FinalRez) :- member(arc(StartNode,NextNode),Arcs),
not(member(StartNode,LocRez)),
append(LocRez,[StartNode],LocRezNew),
find_cycle(NextNode,Arcs,LocRezNew,FinalRez).

Get list of sets where the sum of each set is X

I'm trying to figure out how to generate a list of sets, where each set has a length of N and the sum of each set is X.
I found this code:
num_split(0,[]).
num_split(N, [X | List]):-
between(1,N,X),
plus(X,Y,N),
num_split(Y,List).
And I can use that to get a list of sets with sum X:
num_split(6,List),length(List,5).
List = [1, 1, 1, 1, 2] ;
List = [1, 1, 1, 2, 1] ;
List = [1, 1, 2, 1, 1] ;
List = [1, 2, 1, 1, 1] ;
List = [2, 1, 1, 1, 1] ;
false.
The problem is that those are all permutations, and I'm looking for combinations. The output I'm looking for should be something like get_combos(Sum,Length,List):
get_combos(6,2,List).
List = [5,1];
List = [4,2];
List = [3,3];
false.
Any pointers?
If you have access to a CLP(FD) library, you can use this code:
:- [library(clpfd)].
get_combos(Sum, Length, List) :-
length(List, Length),
List ins 1 .. Sum,
% all_distinct(List), not really useful here
sum(List, #=, Sum),
chain(List, #<),
label(List).
test:
?- get_combos(10,3,L).
L = [1, 2, 7] ;
L = [1, 3, 6] ;
L = [1, 4, 5] ;
L = [2, 3, 5] ;
Maybe I misunderstood your question. Use this chain
...
chain(List, #=<),
....
to get possible duplicates values:
?- get_combos(10,3,L).
L = [1, 1, 8] ;
L = [1, 2, 7] ;
L = [1, 3, 6] ;
L = [1, 4, 5] ;
L = [2, 2, 6] ;
L = [2, 3, 5] ;
L = [2, 4, 4] ;
L = [3, 3, 4] ;
false.
Enforce an "equal or greater" restriction between successive values in the array.
You can add it on as another predicate:
is_combination([]).
is_combination([_]).
is_combination([A,B|List]) :- A =< B, is_combination([B|List]).
get_combos(Sum, Length, List) :-
num_split(Sum, Length, List),
is_combination(List).
Unfortunately, tacking it on the end of the num_split/3 does not necessarily increase its performance, so adding it directly into the algorithm would be marginally better:
get_combos(_, 0, []).
get_combos(Sum, 1, [Sum]).
get_combos(Sum, Length, [A, B|List]) :-
between(1, Sum, A),
plus(A, NextSum, Sum),
plus(1, NextLength, Length),
get_combos(NextSum, NextLength, [B|List]),
A =< B.
I'm not sure just how much more performance this gets, as the comparison has to be after the recursion, due to the less-than-or-equals operator (=<) requiring both operands to be fully instantiated for it to work.

members predicate in Prolog

I'd like to define a members predicate.
members(A, B) means that all members of the list A are members of list B.
top(N) defines how long A can be.
This is my try:
top(5).
members([X], L):-
member(X, L).
members([X| Xs], L):-
member(X, L),
members(Xs, L),
length(Xs, M),
top(N),
M < N.
I'd like to use it as follow:
members(L, [1,2,3]).
The problem with my implementation is that if I ; to get new answers, I'll finish with an ERROR: Out of local stack
?- members(I, [1,2,3]).
I = [1] ;
I = [2] ;
I = [3] ;
I = [1, 1] ;
I = [1, 2] ;
I = [1, 3] ;
I = [1, 1, 1] ;
I = [1, 1, 2] ;
I = [1, 1, 3] ;
I = [1, 1, 1, 1] ;
I = [1, 1, 1, 2] ;
I = [1, 1, 1, 3] ;
I = [1, 1, 1, 1, 1] ;
I = [1, 1, 1, 1, 2] ;
I = [1, 1, 1, 1, 3] ;
;ERROR: Out of local stack
How can I change my code to prevent this out of memory?
As already mentioned, your problem is that you do the length check after the recursive call, meaning that the recursion is unbounded. Unfortunately, just moving the length check above the recursive call like this...
members([X], L):-
member(X, L).
members([X|Xs], L):-
length(Xs, M),
top(N), M < N,
member(X, L),
members(Xs, L).
...is not so good as we get this:
L = [3, 1, 2, 3, 3] ;
L = [3, 2, 2, 3, 3] ;
L = [3, 3, 2, 3, 3] ;
L = [3, 1, 3, 3, 3] ;
L = [3, 2, 3, 3, 3] ;
L = [3, 3, 3, 3, 3] ;
ERROR: Out of global stack
While this gets us the answer, it's not that useful as it can't be put inside a larger predicate since it breaks. It breaks because we have only pushed the problem further along. Here's why:
The problem is that you are constructing the list in a top-down manner. In other words, we define the list like this: List = [Head|Tail] where we stipulate some constraints on Head and state that Tail is made up of a list of elements defined by the same constraints and bounded by a base case. This means that while we are in the middle of the recursive call, we actually only have access to Head - we cannot access the contents of Tail as it is only constructed once the interpreter has gone all the way down and reached the base case (i.e. members([X], L) :-) and then has successively added each Tail to its Head until the final List is constructed.
It may look like we have access to the length, since the length/2 call is sitting there in the middle of the recursive predicate, however since the variable being passed into length/2 for the list is at this stage not bound to anything, Prolog waits until it has finished the recursive calls beneath this point before calculating the length. The problem of course is that the length check is what is bounding the recursion, so it will just continue until it runs out of memory.
While top-down recursion tends to be the default way of constructing Prolog predicates, as this example shows, sometimes we need access to the data structure we are creating. The solution is to use bottom-up recursion. This is implemented in Prolog by means of an accumulator predicate, which starts with an empty list and proceeds to build the list up one by one, by passing the accumulator list (which is a fully ground list) through the recursive predicate. Here's how I would write an accumulator predicate for this problem:
members(I,L) :-
members_accumulator([],I,L).
members_accumulator(Tail,I,L) :-
length(Tail, M),
top(N),
M < N,
member(X, L),
members_accumulator([X|Tail],I,L).
members_accumulator(I,I,_).
We need two predicates, as the first is a wrapper around the accumulator which passes the empty list to the accumulator predicate. The base case no longer has anything to do with the empty list - all it has to do is state that the final accumulator list is actually the final list that we're after (which has been threaded through the accumulator predicate just for this purpose). Also, in this case, the accumulator predicates need to be in this order otherwise there will be one choice point that evaluates as false right at the end.
Getting ones head around recursion in Prolog and when you need to use bottom-up recursion rather than top-down is a non-trivial feat. I didn't really have a solid grasp on it at all until I had a good read through The Art of Prolog. There should also be plenty of info about accumulators online.
Here is an alternate implementation which does'nt require calculating the length of the list. Here N is the length of list A. This solution gives all the answers without going out of stack.
members([X],L,1) :- member(X,L).
members([H|T],L,N) :- N>1 , member(H,L) , N1 is N-1, members(T,L,N1).
Example execution:
?- members(L,[1,2,3],5).
L = [1, 1, 1, 1, 1] ;
L = [1, 1, 1, 1, 2] ;
L = [1, 1, 1, 1, 3] ;
L = [1, 1, 1, 2, 1] ;
...
L = [3, 3, 3, 1, 2] ;
L = [3, 3, 3, 3, 1] ;
L = [3, 3, 3, 3, 2] ;
L = [3, 3, 3, 3, 3] ;
No
You do the check for the depth after the recursion. So the depth of the recursion is not limited, only the resulting lists are discarded as too long.
Use meta-predicate maplist/2,
lambdas, and membership predicate memberd/2 and simply write:
:- use_module(library(lambda)).
members(As,Bs,N) :-
length(Xs,N),
append(As,_,Xs),
maplist(Bs+\A^memberd(A,Bs), As).
Sample query with abbreviated answer sequence:
?- members(As,[1,2,3],5).
As = [ ] ;
As = [ 1] ; As = [ 2] ; As = [ 3] ;
As = [ 1,1] ; As = [ 1,2] ; /* ... */ As = [ 3,3] ;
As = [ 1,1,1] ; As = [ 1,1,2] ; /* ... */ As = [ 3,3,3] ;
As = [ 1,1,1,1] ; As = [ 1,1,1,2] ; /* ... */ As = [ 3,3,3,3] ;
As = [1,1,1,1,1] ; As = [1,1,1,1,2] ; /* ... */ As = [3,3,3,3,3] ;
false.
Above query universally terminates.
Let's look at the size of the solution set:
?- setof(As,members(As,[1,2,3],5),Ass), length(Ass,N_Solutions).
Ass = [[],[1],[1,1],[1,1,1],[1,1,1|...],[1,1|...],[1|...],[...|...]|...],
N_Solutions = 364.
?- 364 =:= 1 + 3 + 3^2 + 3^3 + 3^4 + 3^5.
true.

Resources