counting the elements of a list of lists PROLOG
I am trying to count the elements of a list of
lists.
I implemented the code in this way:
len1(,0).
len1([_X|Xs],N) :- len1(Xs,N1), N is N1+1.
clist([,],0).
clist([Xs,Ys],N):- len1(Xs,N1),len1(Ys,N2),N is N1+N2.
i re-use count element (len1 predicates) in a list, and seems work.
Anyone can say me if is nice work, very bad or can do this but it s preferable other (without len1).
I dont think is good implementation, and otherwhise seems not generic.
Ad example this work only with list, that contain two list inside. If i want make generic? i think need to use _Xs, but i try to change my code and not working.
in particular i try to change this:
clist([Xs,Ys],N):- len1(Xs,N1),len1(Ys,N2),N is N1+N2.
in
clist([_Xs],N):- len1(_Xs,N1),N is N1.
and obviously don't work.
prolog
add a comment |
I am trying to count the elements of a list of
lists.
I implemented the code in this way:
len1(,0).
len1([_X|Xs],N) :- len1(Xs,N1), N is N1+1.
clist([,],0).
clist([Xs,Ys],N):- len1(Xs,N1),len1(Ys,N2),N is N1+N2.
i re-use count element (len1 predicates) in a list, and seems work.
Anyone can say me if is nice work, very bad or can do this but it s preferable other (without len1).
I dont think is good implementation, and otherwhise seems not generic.
Ad example this work only with list, that contain two list inside. If i want make generic? i think need to use _Xs, but i try to change my code and not working.
in particular i try to change this:
clist([Xs,Ys],N):- len1(Xs,N1),len1(Ys,N2),N is N1+N2.
in
clist([_Xs],N):- len1(_Xs,N1),N is N1.
and obviously don't work.
prolog
A list of lists, or an lists that are nested arbitrary deep?
– Willem Van Onsem
Dec 18 '18 at 17:16
add a comment |
I am trying to count the elements of a list of
lists.
I implemented the code in this way:
len1(,0).
len1([_X|Xs],N) :- len1(Xs,N1), N is N1+1.
clist([,],0).
clist([Xs,Ys],N):- len1(Xs,N1),len1(Ys,N2),N is N1+N2.
i re-use count element (len1 predicates) in a list, and seems work.
Anyone can say me if is nice work, very bad or can do this but it s preferable other (without len1).
I dont think is good implementation, and otherwhise seems not generic.
Ad example this work only with list, that contain two list inside. If i want make generic? i think need to use _Xs, but i try to change my code and not working.
in particular i try to change this:
clist([Xs,Ys],N):- len1(Xs,N1),len1(Ys,N2),N is N1+N2.
in
clist([_Xs],N):- len1(_Xs,N1),N is N1.
and obviously don't work.
prolog
I am trying to count the elements of a list of
lists.
I implemented the code in this way:
len1(,0).
len1([_X|Xs],N) :- len1(Xs,N1), N is N1+1.
clist([,],0).
clist([Xs,Ys],N):- len1(Xs,N1),len1(Ys,N2),N is N1+N2.
i re-use count element (len1 predicates) in a list, and seems work.
Anyone can say me if is nice work, very bad or can do this but it s preferable other (without len1).
I dont think is good implementation, and otherwhise seems not generic.
Ad example this work only with list, that contain two list inside. If i want make generic? i think need to use _Xs, but i try to change my code and not working.
in particular i try to change this:
clist([Xs,Ys],N):- len1(Xs,N1),len1(Ys,N2),N is N1+N2.
in
clist([_Xs],N):- len1(_Xs,N1),N is N1.
and obviously don't work.
prolog
prolog
edited Dec 18 '18 at 18:57


false
11.1k772149
11.1k772149
asked Dec 18 '18 at 17:06


theantomctheantomc
1158
1158
A list of lists, or an lists that are nested arbitrary deep?
– Willem Van Onsem
Dec 18 '18 at 17:16
add a comment |
A list of lists, or an lists that are nested arbitrary deep?
– Willem Van Onsem
Dec 18 '18 at 17:16
A list of lists, or an lists that are nested arbitrary deep?
– Willem Van Onsem
Dec 18 '18 at 17:16
A list of lists, or an lists that are nested arbitrary deep?
– Willem Van Onsem
Dec 18 '18 at 17:16
add a comment |
2 Answers
2
active
oldest
votes
Well you can apply the same trick for your clist/2
predicate: instead of solving the problem for lists with two elements, you can consider two cases:
- an empty list
, in which case the total number is of course zero; and
- a non-empty list
[H|T]
, whereH
is a list, andT
is the list of remaining lists. In that case we first calculate the length ofH
, we the calculate (through recursion) the sum of the lists inT
and then sum these together.
So we can implement this as:
clist(, 0).
clist([H|T], N) :-
length(H, HN),
clist(T, TN),
N is HN + TN.
The above can be improved by using an accumulator: we can define a predicate clist/3
that has a variable that stores the total number of elements in the list this far, in case we reach the end of the list, we unify the answer with that variable, like:
clist(L, N) :-
clist(L, 0, N).
clist(, N, N).
clist([H|T], N1, N) :-
length(H, HN),
N2 is N1 + HN,
clist(T, N2, N).
lenght is predefinite predicate?because for exercise i would implement alone(just for understand how work). In the "optimization" i understand that you use a sort of cycle like in programming language ..so when i ask to compile a query i need to specify the list of list and the number of elements (number of list inside the list)...right? sorry for more question, but i try to understand well
– theantomc
Dec 18 '18 at 18:10
@theantomc: well you imlemented alen1/2
yourself, so you can use it. As for the optimization, we use an accumulator, so no, this will generate the total number of elements.
– Willem Van Onsem
Dec 18 '18 at 18:12
can i use my len1 like in my example? or is wrong way? For optimization i think must study more on accumulator, i will do and after i try new example with this new element for me. thanks so much for clarify!
– theantomc
Dec 18 '18 at 18:19
@theantomc: yes, if you replace thelength(H, HN)
call withlen1(H, HN)
it will still work.
– Willem Van Onsem
Dec 18 '18 at 18:21
add a comment |
Yes, you were correct in wanting to generalize your definition. Instead of
clist([,],0).
(well, first, it should be
clist( , 0).
Continuing...) and
clist([Xs,Ys], N):- len1(Xs,N1), len1(Ys,N2), N is N1+N2.
which handles two lists in a list, change it to
clist([Xs|YSs], N):- len1(Xs,N1), len1(YSs,N2), N is N1+N2.
to handle any number of lists in a list. But now the second len1
is misapplied. It receives a list of lists, not just a list as before. Faced with having to handle a list of lists (YSs
) to be able to handle a list of lists ([Xs|YSs]
), we're back where we started. Are we, really?
Not quite. We already have the predicate to handle the list of lists -- it's clist
that we're defining! Wait, what? Do we have it defined yet? We haven't finished writing it down, yes, but we will; and when we've finished writing it down we will have it defined. Recursion is a leap of faith:
clist([Xs|YSs], N):- len1(Xs,N1), clist(YSs,N2), N is N1+N2.
Moreover, this second list of lists YSs
is shorter than [Xs|YSs]
. An that is the key.
And if the lists were arbitrarily deeply nested, the recursion would be
clist([XSs|YSs], N):- clist(XSs,N1), clist(YSs,N2), N is N1+N2.
with the appropriately mended base case(s).
Recursion is a leap of faith: assume we have the solution already, use it to handle smaller sub-cases of the problem at hand, simply combine the results - there you have it! The solution we assumed to have, coming into existence because we used it as if it existed already.
recursion( Whole, Solution ) :-
problem( Whole, Shell, NestedCases),
maplist( recursion, NestedCases, SolvedParts),
problem( Solution, Shell, SolvedParts).
A Russian matryoshka doll of problems all the way down, turned into solutions all the way back up from the deepest level. But the point is, we rely on recursion to handle the inner matryoshka, however many levels it may have nested inside her. We only take apart and reassemble the one -- the top-most.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53837915%2fcounting-the-elements-of-a-list-of-lists-prolog%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Well you can apply the same trick for your clist/2
predicate: instead of solving the problem for lists with two elements, you can consider two cases:
- an empty list
, in which case the total number is of course zero; and
- a non-empty list
[H|T]
, whereH
is a list, andT
is the list of remaining lists. In that case we first calculate the length ofH
, we the calculate (through recursion) the sum of the lists inT
and then sum these together.
So we can implement this as:
clist(, 0).
clist([H|T], N) :-
length(H, HN),
clist(T, TN),
N is HN + TN.
The above can be improved by using an accumulator: we can define a predicate clist/3
that has a variable that stores the total number of elements in the list this far, in case we reach the end of the list, we unify the answer with that variable, like:
clist(L, N) :-
clist(L, 0, N).
clist(, N, N).
clist([H|T], N1, N) :-
length(H, HN),
N2 is N1 + HN,
clist(T, N2, N).
lenght is predefinite predicate?because for exercise i would implement alone(just for understand how work). In the "optimization" i understand that you use a sort of cycle like in programming language ..so when i ask to compile a query i need to specify the list of list and the number of elements (number of list inside the list)...right? sorry for more question, but i try to understand well
– theantomc
Dec 18 '18 at 18:10
@theantomc: well you imlemented alen1/2
yourself, so you can use it. As for the optimization, we use an accumulator, so no, this will generate the total number of elements.
– Willem Van Onsem
Dec 18 '18 at 18:12
can i use my len1 like in my example? or is wrong way? For optimization i think must study more on accumulator, i will do and after i try new example with this new element for me. thanks so much for clarify!
– theantomc
Dec 18 '18 at 18:19
@theantomc: yes, if you replace thelength(H, HN)
call withlen1(H, HN)
it will still work.
– Willem Van Onsem
Dec 18 '18 at 18:21
add a comment |
Well you can apply the same trick for your clist/2
predicate: instead of solving the problem for lists with two elements, you can consider two cases:
- an empty list
, in which case the total number is of course zero; and
- a non-empty list
[H|T]
, whereH
is a list, andT
is the list of remaining lists. In that case we first calculate the length ofH
, we the calculate (through recursion) the sum of the lists inT
and then sum these together.
So we can implement this as:
clist(, 0).
clist([H|T], N) :-
length(H, HN),
clist(T, TN),
N is HN + TN.
The above can be improved by using an accumulator: we can define a predicate clist/3
that has a variable that stores the total number of elements in the list this far, in case we reach the end of the list, we unify the answer with that variable, like:
clist(L, N) :-
clist(L, 0, N).
clist(, N, N).
clist([H|T], N1, N) :-
length(H, HN),
N2 is N1 + HN,
clist(T, N2, N).
lenght is predefinite predicate?because for exercise i would implement alone(just for understand how work). In the "optimization" i understand that you use a sort of cycle like in programming language ..so when i ask to compile a query i need to specify the list of list and the number of elements (number of list inside the list)...right? sorry for more question, but i try to understand well
– theantomc
Dec 18 '18 at 18:10
@theantomc: well you imlemented alen1/2
yourself, so you can use it. As for the optimization, we use an accumulator, so no, this will generate the total number of elements.
– Willem Van Onsem
Dec 18 '18 at 18:12
can i use my len1 like in my example? or is wrong way? For optimization i think must study more on accumulator, i will do and after i try new example with this new element for me. thanks so much for clarify!
– theantomc
Dec 18 '18 at 18:19
@theantomc: yes, if you replace thelength(H, HN)
call withlen1(H, HN)
it will still work.
– Willem Van Onsem
Dec 18 '18 at 18:21
add a comment |
Well you can apply the same trick for your clist/2
predicate: instead of solving the problem for lists with two elements, you can consider two cases:
- an empty list
, in which case the total number is of course zero; and
- a non-empty list
[H|T]
, whereH
is a list, andT
is the list of remaining lists. In that case we first calculate the length ofH
, we the calculate (through recursion) the sum of the lists inT
and then sum these together.
So we can implement this as:
clist(, 0).
clist([H|T], N) :-
length(H, HN),
clist(T, TN),
N is HN + TN.
The above can be improved by using an accumulator: we can define a predicate clist/3
that has a variable that stores the total number of elements in the list this far, in case we reach the end of the list, we unify the answer with that variable, like:
clist(L, N) :-
clist(L, 0, N).
clist(, N, N).
clist([H|T], N1, N) :-
length(H, HN),
N2 is N1 + HN,
clist(T, N2, N).
Well you can apply the same trick for your clist/2
predicate: instead of solving the problem for lists with two elements, you can consider two cases:
- an empty list
, in which case the total number is of course zero; and
- a non-empty list
[H|T]
, whereH
is a list, andT
is the list of remaining lists. In that case we first calculate the length ofH
, we the calculate (through recursion) the sum of the lists inT
and then sum these together.
So we can implement this as:
clist(, 0).
clist([H|T], N) :-
length(H, HN),
clist(T, TN),
N is HN + TN.
The above can be improved by using an accumulator: we can define a predicate clist/3
that has a variable that stores the total number of elements in the list this far, in case we reach the end of the list, we unify the answer with that variable, like:
clist(L, N) :-
clist(L, 0, N).
clist(, N, N).
clist([H|T], N1, N) :-
length(H, HN),
N2 is N1 + HN,
clist(T, N2, N).
answered Dec 18 '18 at 17:23


Willem Van OnsemWillem Van Onsem
150k16145235
150k16145235
lenght is predefinite predicate?because for exercise i would implement alone(just for understand how work). In the "optimization" i understand that you use a sort of cycle like in programming language ..so when i ask to compile a query i need to specify the list of list and the number of elements (number of list inside the list)...right? sorry for more question, but i try to understand well
– theantomc
Dec 18 '18 at 18:10
@theantomc: well you imlemented alen1/2
yourself, so you can use it. As for the optimization, we use an accumulator, so no, this will generate the total number of elements.
– Willem Van Onsem
Dec 18 '18 at 18:12
can i use my len1 like in my example? or is wrong way? For optimization i think must study more on accumulator, i will do and after i try new example with this new element for me. thanks so much for clarify!
– theantomc
Dec 18 '18 at 18:19
@theantomc: yes, if you replace thelength(H, HN)
call withlen1(H, HN)
it will still work.
– Willem Van Onsem
Dec 18 '18 at 18:21
add a comment |
lenght is predefinite predicate?because for exercise i would implement alone(just for understand how work). In the "optimization" i understand that you use a sort of cycle like in programming language ..so when i ask to compile a query i need to specify the list of list and the number of elements (number of list inside the list)...right? sorry for more question, but i try to understand well
– theantomc
Dec 18 '18 at 18:10
@theantomc: well you imlemented alen1/2
yourself, so you can use it. As for the optimization, we use an accumulator, so no, this will generate the total number of elements.
– Willem Van Onsem
Dec 18 '18 at 18:12
can i use my len1 like in my example? or is wrong way? For optimization i think must study more on accumulator, i will do and after i try new example with this new element for me. thanks so much for clarify!
– theantomc
Dec 18 '18 at 18:19
@theantomc: yes, if you replace thelength(H, HN)
call withlen1(H, HN)
it will still work.
– Willem Van Onsem
Dec 18 '18 at 18:21
lenght is predefinite predicate?because for exercise i would implement alone(just for understand how work). In the "optimization" i understand that you use a sort of cycle like in programming language ..so when i ask to compile a query i need to specify the list of list and the number of elements (number of list inside the list)...right? sorry for more question, but i try to understand well
– theantomc
Dec 18 '18 at 18:10
lenght is predefinite predicate?because for exercise i would implement alone(just for understand how work). In the "optimization" i understand that you use a sort of cycle like in programming language ..so when i ask to compile a query i need to specify the list of list and the number of elements (number of list inside the list)...right? sorry for more question, but i try to understand well
– theantomc
Dec 18 '18 at 18:10
@theantomc: well you imlemented a
len1/2
yourself, so you can use it. As for the optimization, we use an accumulator, so no, this will generate the total number of elements.– Willem Van Onsem
Dec 18 '18 at 18:12
@theantomc: well you imlemented a
len1/2
yourself, so you can use it. As for the optimization, we use an accumulator, so no, this will generate the total number of elements.– Willem Van Onsem
Dec 18 '18 at 18:12
can i use my len1 like in my example? or is wrong way? For optimization i think must study more on accumulator, i will do and after i try new example with this new element for me. thanks so much for clarify!
– theantomc
Dec 18 '18 at 18:19
can i use my len1 like in my example? or is wrong way? For optimization i think must study more on accumulator, i will do and after i try new example with this new element for me. thanks so much for clarify!
– theantomc
Dec 18 '18 at 18:19
@theantomc: yes, if you replace the
length(H, HN)
call with len1(H, HN)
it will still work.– Willem Van Onsem
Dec 18 '18 at 18:21
@theantomc: yes, if you replace the
length(H, HN)
call with len1(H, HN)
it will still work.– Willem Van Onsem
Dec 18 '18 at 18:21
add a comment |
Yes, you were correct in wanting to generalize your definition. Instead of
clist([,],0).
(well, first, it should be
clist( , 0).
Continuing...) and
clist([Xs,Ys], N):- len1(Xs,N1), len1(Ys,N2), N is N1+N2.
which handles two lists in a list, change it to
clist([Xs|YSs], N):- len1(Xs,N1), len1(YSs,N2), N is N1+N2.
to handle any number of lists in a list. But now the second len1
is misapplied. It receives a list of lists, not just a list as before. Faced with having to handle a list of lists (YSs
) to be able to handle a list of lists ([Xs|YSs]
), we're back where we started. Are we, really?
Not quite. We already have the predicate to handle the list of lists -- it's clist
that we're defining! Wait, what? Do we have it defined yet? We haven't finished writing it down, yes, but we will; and when we've finished writing it down we will have it defined. Recursion is a leap of faith:
clist([Xs|YSs], N):- len1(Xs,N1), clist(YSs,N2), N is N1+N2.
Moreover, this second list of lists YSs
is shorter than [Xs|YSs]
. An that is the key.
And if the lists were arbitrarily deeply nested, the recursion would be
clist([XSs|YSs], N):- clist(XSs,N1), clist(YSs,N2), N is N1+N2.
with the appropriately mended base case(s).
Recursion is a leap of faith: assume we have the solution already, use it to handle smaller sub-cases of the problem at hand, simply combine the results - there you have it! The solution we assumed to have, coming into existence because we used it as if it existed already.
recursion( Whole, Solution ) :-
problem( Whole, Shell, NestedCases),
maplist( recursion, NestedCases, SolvedParts),
problem( Solution, Shell, SolvedParts).
A Russian matryoshka doll of problems all the way down, turned into solutions all the way back up from the deepest level. But the point is, we rely on recursion to handle the inner matryoshka, however many levels it may have nested inside her. We only take apart and reassemble the one -- the top-most.
add a comment |
Yes, you were correct in wanting to generalize your definition. Instead of
clist([,],0).
(well, first, it should be
clist( , 0).
Continuing...) and
clist([Xs,Ys], N):- len1(Xs,N1), len1(Ys,N2), N is N1+N2.
which handles two lists in a list, change it to
clist([Xs|YSs], N):- len1(Xs,N1), len1(YSs,N2), N is N1+N2.
to handle any number of lists in a list. But now the second len1
is misapplied. It receives a list of lists, not just a list as before. Faced with having to handle a list of lists (YSs
) to be able to handle a list of lists ([Xs|YSs]
), we're back where we started. Are we, really?
Not quite. We already have the predicate to handle the list of lists -- it's clist
that we're defining! Wait, what? Do we have it defined yet? We haven't finished writing it down, yes, but we will; and when we've finished writing it down we will have it defined. Recursion is a leap of faith:
clist([Xs|YSs], N):- len1(Xs,N1), clist(YSs,N2), N is N1+N2.
Moreover, this second list of lists YSs
is shorter than [Xs|YSs]
. An that is the key.
And if the lists were arbitrarily deeply nested, the recursion would be
clist([XSs|YSs], N):- clist(XSs,N1), clist(YSs,N2), N is N1+N2.
with the appropriately mended base case(s).
Recursion is a leap of faith: assume we have the solution already, use it to handle smaller sub-cases of the problem at hand, simply combine the results - there you have it! The solution we assumed to have, coming into existence because we used it as if it existed already.
recursion( Whole, Solution ) :-
problem( Whole, Shell, NestedCases),
maplist( recursion, NestedCases, SolvedParts),
problem( Solution, Shell, SolvedParts).
A Russian matryoshka doll of problems all the way down, turned into solutions all the way back up from the deepest level. But the point is, we rely on recursion to handle the inner matryoshka, however many levels it may have nested inside her. We only take apart and reassemble the one -- the top-most.
add a comment |
Yes, you were correct in wanting to generalize your definition. Instead of
clist([,],0).
(well, first, it should be
clist( , 0).
Continuing...) and
clist([Xs,Ys], N):- len1(Xs,N1), len1(Ys,N2), N is N1+N2.
which handles two lists in a list, change it to
clist([Xs|YSs], N):- len1(Xs,N1), len1(YSs,N2), N is N1+N2.
to handle any number of lists in a list. But now the second len1
is misapplied. It receives a list of lists, not just a list as before. Faced with having to handle a list of lists (YSs
) to be able to handle a list of lists ([Xs|YSs]
), we're back where we started. Are we, really?
Not quite. We already have the predicate to handle the list of lists -- it's clist
that we're defining! Wait, what? Do we have it defined yet? We haven't finished writing it down, yes, but we will; and when we've finished writing it down we will have it defined. Recursion is a leap of faith:
clist([Xs|YSs], N):- len1(Xs,N1), clist(YSs,N2), N is N1+N2.
Moreover, this second list of lists YSs
is shorter than [Xs|YSs]
. An that is the key.
And if the lists were arbitrarily deeply nested, the recursion would be
clist([XSs|YSs], N):- clist(XSs,N1), clist(YSs,N2), N is N1+N2.
with the appropriately mended base case(s).
Recursion is a leap of faith: assume we have the solution already, use it to handle smaller sub-cases of the problem at hand, simply combine the results - there you have it! The solution we assumed to have, coming into existence because we used it as if it existed already.
recursion( Whole, Solution ) :-
problem( Whole, Shell, NestedCases),
maplist( recursion, NestedCases, SolvedParts),
problem( Solution, Shell, SolvedParts).
A Russian matryoshka doll of problems all the way down, turned into solutions all the way back up from the deepest level. But the point is, we rely on recursion to handle the inner matryoshka, however many levels it may have nested inside her. We only take apart and reassemble the one -- the top-most.
Yes, you were correct in wanting to generalize your definition. Instead of
clist([,],0).
(well, first, it should be
clist( , 0).
Continuing...) and
clist([Xs,Ys], N):- len1(Xs,N1), len1(Ys,N2), N is N1+N2.
which handles two lists in a list, change it to
clist([Xs|YSs], N):- len1(Xs,N1), len1(YSs,N2), N is N1+N2.
to handle any number of lists in a list. But now the second len1
is misapplied. It receives a list of lists, not just a list as before. Faced with having to handle a list of lists (YSs
) to be able to handle a list of lists ([Xs|YSs]
), we're back where we started. Are we, really?
Not quite. We already have the predicate to handle the list of lists -- it's clist
that we're defining! Wait, what? Do we have it defined yet? We haven't finished writing it down, yes, but we will; and when we've finished writing it down we will have it defined. Recursion is a leap of faith:
clist([Xs|YSs], N):- len1(Xs,N1), clist(YSs,N2), N is N1+N2.
Moreover, this second list of lists YSs
is shorter than [Xs|YSs]
. An that is the key.
And if the lists were arbitrarily deeply nested, the recursion would be
clist([XSs|YSs], N):- clist(XSs,N1), clist(YSs,N2), N is N1+N2.
with the appropriately mended base case(s).
Recursion is a leap of faith: assume we have the solution already, use it to handle smaller sub-cases of the problem at hand, simply combine the results - there you have it! The solution we assumed to have, coming into existence because we used it as if it existed already.
recursion( Whole, Solution ) :-
problem( Whole, Shell, NestedCases),
maplist( recursion, NestedCases, SolvedParts),
problem( Solution, Shell, SolvedParts).
A Russian matryoshka doll of problems all the way down, turned into solutions all the way back up from the deepest level. But the point is, we rely on recursion to handle the inner matryoshka, however many levels it may have nested inside her. We only take apart and reassemble the one -- the top-most.
edited Jan 2 at 8:59
answered Jan 1 at 16:56


Will NessWill Ness
46.2k468126
46.2k468126
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53837915%2fcounting-the-elements-of-a-list-of-lists-prolog%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
A list of lists, or an lists that are nested arbitrary deep?
– Willem Van Onsem
Dec 18 '18 at 17:16