counting the elements of a list of lists PROLOG












1















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.










share|improve this question

























  • A list of lists, or an lists that are nested arbitrary deep?

    – Willem Van Onsem
    Dec 18 '18 at 17:16
















1















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.










share|improve this question

























  • A list of lists, or an lists that are nested arbitrary deep?

    – Willem Van Onsem
    Dec 18 '18 at 17:16














1












1








1








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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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



















  • 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












2 Answers
2






active

oldest

votes


















1














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:




  1. an empty list , in which case the total number is of course zero; and

  2. a non-empty list [H|T], where H is a list, and T is the list of remaining lists. In that case we first calculate the length of H, we the calculate (through recursion) the sum of the lists in T 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).





share|improve this answer
























  • 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











  • 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



















0














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.






share|improve this answer

























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    1














    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:




    1. an empty list , in which case the total number is of course zero; and

    2. a non-empty list [H|T], where H is a list, and T is the list of remaining lists. In that case we first calculate the length of H, we the calculate (through recursion) the sum of the lists in T 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).





    share|improve this answer
























    • 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











    • 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
















    1














    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:




    1. an empty list , in which case the total number is of course zero; and

    2. a non-empty list [H|T], where H is a list, and T is the list of remaining lists. In that case we first calculate the length of H, we the calculate (through recursion) the sum of the lists in T 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).





    share|improve this answer
























    • 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











    • 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














    1












    1








    1







    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:




    1. an empty list , in which case the total number is of course zero; and

    2. a non-empty list [H|T], where H is a list, and T is the list of remaining lists. In that case we first calculate the length of H, we the calculate (through recursion) the sum of the lists in T 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).





    share|improve this answer













    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:




    1. an empty list , in which case the total number is of course zero; and

    2. a non-empty list [H|T], where H is a list, and T is the list of remaining lists. In that case we first calculate the length of H, we the calculate (through recursion) the sum of the lists in T 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).






    share|improve this answer












    share|improve this answer



    share|improve this answer










    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 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











    • @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



















    • 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











    • 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

















    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













    0














    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.






    share|improve this answer






























      0














      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.






      share|improve this answer




























        0












        0








        0







        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.






        share|improve this answer















        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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 2 at 8:59

























        answered Jan 1 at 16:56









        Will NessWill Ness

        46.2k468126




        46.2k468126






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

            How to fix TextFormField cause rebuild widget in Flutter