Getting a list of children for a node in Prolog












2















I'm trying to do a simple tree search in Prolog, and I need a function that would return a list of children for a given node.



My code is:



root(a).
node(a, [b, c]).
node(b, ).
node(c, [d, e, f]).
node(d, ).
node(e, ).
node(f, ).

children(node(_, Kids), Kids).

node_matches(_,_).
node_matches(Criteria, [Head|Tail]) :- node_matches(Criteria, Head), node_matches(Criteria, Tail).

search_node(Criteria, [Node]) :- node_matches(Criteria, Node), search_node(Criteria, children(Node)).


Currently I'm getting and error Undefined procedure: children/1, which makes sense, because I haven't implemented a function with 1 argument.
How can I implement such a function?










share|improve this question























  • What do you think node_matches(_,_). means ?

    – CapelliC
    Nov 14 '18 at 10:26











  • Prolog doesn't know what your logic needs to be for defining a rule. So when you define children(node(_, Kids), Kids)., then queries such as children(node(123, foo), foo). succeed. Also, Prolog doesn't know that the node/2 inside your children/2 fact is the same as the node/2 that you've defined as facts. Finally, you haven't said how you want your predicate to behave. An example would help.

    – lurker
    Nov 14 '18 at 11:35











  • These are not functions, but predicates, this is not just nomenclature, but it thus means that children(whatever), can only be true or false (or raise an error, or get stuck in an infinite loop).

    – Willem Van Onsem
    Nov 14 '18 at 11:38











  • @CapelliC node_matches(_,_). is just a temporary placeholder for a predicate that will later on hold more exact logic for matching. Currently, it just returns true if given 2 equal values.

    – Matthew T
    Nov 14 '18 at 12:52






  • 1





    You don't need to be "pro". You just need to get a few basics down.

    – lurker
    Nov 14 '18 at 14:34
















2















I'm trying to do a simple tree search in Prolog, and I need a function that would return a list of children for a given node.



My code is:



root(a).
node(a, [b, c]).
node(b, ).
node(c, [d, e, f]).
node(d, ).
node(e, ).
node(f, ).

children(node(_, Kids), Kids).

node_matches(_,_).
node_matches(Criteria, [Head|Tail]) :- node_matches(Criteria, Head), node_matches(Criteria, Tail).

search_node(Criteria, [Node]) :- node_matches(Criteria, Node), search_node(Criteria, children(Node)).


Currently I'm getting and error Undefined procedure: children/1, which makes sense, because I haven't implemented a function with 1 argument.
How can I implement such a function?










share|improve this question























  • What do you think node_matches(_,_). means ?

    – CapelliC
    Nov 14 '18 at 10:26











  • Prolog doesn't know what your logic needs to be for defining a rule. So when you define children(node(_, Kids), Kids)., then queries such as children(node(123, foo), foo). succeed. Also, Prolog doesn't know that the node/2 inside your children/2 fact is the same as the node/2 that you've defined as facts. Finally, you haven't said how you want your predicate to behave. An example would help.

    – lurker
    Nov 14 '18 at 11:35











  • These are not functions, but predicates, this is not just nomenclature, but it thus means that children(whatever), can only be true or false (or raise an error, or get stuck in an infinite loop).

    – Willem Van Onsem
    Nov 14 '18 at 11:38











  • @CapelliC node_matches(_,_). is just a temporary placeholder for a predicate that will later on hold more exact logic for matching. Currently, it just returns true if given 2 equal values.

    – Matthew T
    Nov 14 '18 at 12:52






  • 1





    You don't need to be "pro". You just need to get a few basics down.

    – lurker
    Nov 14 '18 at 14:34














2












2








2








I'm trying to do a simple tree search in Prolog, and I need a function that would return a list of children for a given node.



My code is:



root(a).
node(a, [b, c]).
node(b, ).
node(c, [d, e, f]).
node(d, ).
node(e, ).
node(f, ).

children(node(_, Kids), Kids).

node_matches(_,_).
node_matches(Criteria, [Head|Tail]) :- node_matches(Criteria, Head), node_matches(Criteria, Tail).

search_node(Criteria, [Node]) :- node_matches(Criteria, Node), search_node(Criteria, children(Node)).


Currently I'm getting and error Undefined procedure: children/1, which makes sense, because I haven't implemented a function with 1 argument.
How can I implement such a function?










share|improve this question














I'm trying to do a simple tree search in Prolog, and I need a function that would return a list of children for a given node.



My code is:



root(a).
node(a, [b, c]).
node(b, ).
node(c, [d, e, f]).
node(d, ).
node(e, ).
node(f, ).

children(node(_, Kids), Kids).

node_matches(_,_).
node_matches(Criteria, [Head|Tail]) :- node_matches(Criteria, Head), node_matches(Criteria, Tail).

search_node(Criteria, [Node]) :- node_matches(Criteria, Node), search_node(Criteria, children(Node)).


Currently I'm getting and error Undefined procedure: children/1, which makes sense, because I haven't implemented a function with 1 argument.
How can I implement such a function?







search tree prolog






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 14 '18 at 9:10









Matthew TMatthew T

5010




5010













  • What do you think node_matches(_,_). means ?

    – CapelliC
    Nov 14 '18 at 10:26











  • Prolog doesn't know what your logic needs to be for defining a rule. So when you define children(node(_, Kids), Kids)., then queries such as children(node(123, foo), foo). succeed. Also, Prolog doesn't know that the node/2 inside your children/2 fact is the same as the node/2 that you've defined as facts. Finally, you haven't said how you want your predicate to behave. An example would help.

    – lurker
    Nov 14 '18 at 11:35











  • These are not functions, but predicates, this is not just nomenclature, but it thus means that children(whatever), can only be true or false (or raise an error, or get stuck in an infinite loop).

    – Willem Van Onsem
    Nov 14 '18 at 11:38











  • @CapelliC node_matches(_,_). is just a temporary placeholder for a predicate that will later on hold more exact logic for matching. Currently, it just returns true if given 2 equal values.

    – Matthew T
    Nov 14 '18 at 12:52






  • 1





    You don't need to be "pro". You just need to get a few basics down.

    – lurker
    Nov 14 '18 at 14:34



















  • What do you think node_matches(_,_). means ?

    – CapelliC
    Nov 14 '18 at 10:26











  • Prolog doesn't know what your logic needs to be for defining a rule. So when you define children(node(_, Kids), Kids)., then queries such as children(node(123, foo), foo). succeed. Also, Prolog doesn't know that the node/2 inside your children/2 fact is the same as the node/2 that you've defined as facts. Finally, you haven't said how you want your predicate to behave. An example would help.

    – lurker
    Nov 14 '18 at 11:35











  • These are not functions, but predicates, this is not just nomenclature, but it thus means that children(whatever), can only be true or false (or raise an error, or get stuck in an infinite loop).

    – Willem Van Onsem
    Nov 14 '18 at 11:38











  • @CapelliC node_matches(_,_). is just a temporary placeholder for a predicate that will later on hold more exact logic for matching. Currently, it just returns true if given 2 equal values.

    – Matthew T
    Nov 14 '18 at 12:52






  • 1





    You don't need to be "pro". You just need to get a few basics down.

    – lurker
    Nov 14 '18 at 14:34

















What do you think node_matches(_,_). means ?

– CapelliC
Nov 14 '18 at 10:26





What do you think node_matches(_,_). means ?

– CapelliC
Nov 14 '18 at 10:26













Prolog doesn't know what your logic needs to be for defining a rule. So when you define children(node(_, Kids), Kids)., then queries such as children(node(123, foo), foo). succeed. Also, Prolog doesn't know that the node/2 inside your children/2 fact is the same as the node/2 that you've defined as facts. Finally, you haven't said how you want your predicate to behave. An example would help.

– lurker
Nov 14 '18 at 11:35





Prolog doesn't know what your logic needs to be for defining a rule. So when you define children(node(_, Kids), Kids)., then queries such as children(node(123, foo), foo). succeed. Also, Prolog doesn't know that the node/2 inside your children/2 fact is the same as the node/2 that you've defined as facts. Finally, you haven't said how you want your predicate to behave. An example would help.

– lurker
Nov 14 '18 at 11:35













These are not functions, but predicates, this is not just nomenclature, but it thus means that children(whatever), can only be true or false (or raise an error, or get stuck in an infinite loop).

– Willem Van Onsem
Nov 14 '18 at 11:38





These are not functions, but predicates, this is not just nomenclature, but it thus means that children(whatever), can only be true or false (or raise an error, or get stuck in an infinite loop).

– Willem Van Onsem
Nov 14 '18 at 11:38













@CapelliC node_matches(_,_). is just a temporary placeholder for a predicate that will later on hold more exact logic for matching. Currently, it just returns true if given 2 equal values.

– Matthew T
Nov 14 '18 at 12:52





@CapelliC node_matches(_,_). is just a temporary placeholder for a predicate that will later on hold more exact logic for matching. Currently, it just returns true if given 2 equal values.

– Matthew T
Nov 14 '18 at 12:52




1




1





You don't need to be "pro". You just need to get a few basics down.

– lurker
Nov 14 '18 at 14:34





You don't need to be "pro". You just need to get a few basics down.

– lurker
Nov 14 '18 at 14:34












1 Answer
1






active

oldest

votes


















3














Since you are interested in a list, why not considering the use of DCGs for the task? After all, DCGs describe lists and they yield easily readable code. Conveniently, your given facts node/2 provide the direct successors of a node in a list, so it is opportune to use a list of nodes to be visited as the DCGs single argument. The DCG itself could be named after what it describes, for example children//1. You can define a calling predicate, let's also give it a nice descriptive name, say node_children/2, that uses phrase/2 to call the DCG:



node_children(N,C) :-
node(N,Succs), % Succs are the direct successors of node N
phrase(children(Succs),C). % based on them the DCG children//1 describes the list C


The DGC children//1 has to describe a list that consists of all the nodes in its argument-list and their respective children, that is, their respective successors, their successors' successors, and so on (that wording already bears the scent of recursion :-). So children//1 might look something like this:



children() -->       % if there are no nodes
. % there are no children
children([N|Ns]) --> % N, the first node in the list...
{node(N,Succs)}, % ...has the direct successors Succs...
[N], % ...and is in the list of children...
children(Succs), % ...as well as its successors and their children...
children(Ns). % ...as well as the other nodes in the list


In the first goal of the recursive rule of children//1, {node(N,Succs)}, you can observe how predicates can be called in a DCG, namely enclosed by braces. Now let's see node_children/2 in action:



   ?- node_children(a,C).
C = [b,c,d,e,f]
?- node_children(b,C).
C =
?- node_children(c,C).
C = [d,e,f]


You can also ask more general queries like What nodes and respective children are there?:



   ?- node_children(N,C).
C = [b,c,d,e,f],
N = a ? ;
C = ,
N = b ? ;
C = [d,e,f],
N = c ? ;
C = ,
N = d ? ;
C = ,
N = e ? ;
C = ,
N = f


Or Which nodes have three children?:



   ?- C=[_,_,_], node_children(N,C).
C = [d,e,f],
N = c ? ;
no


Two closing remarks: You can see how the DCG children//1 is translated into a predicate by querying ?- listing(children).. To learn more about DCGs I can wholeheartedly recommend this DCG Primer.






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%2f53296522%2fgetting-a-list-of-children-for-a-node-in-prolog%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    Since you are interested in a list, why not considering the use of DCGs for the task? After all, DCGs describe lists and they yield easily readable code. Conveniently, your given facts node/2 provide the direct successors of a node in a list, so it is opportune to use a list of nodes to be visited as the DCGs single argument. The DCG itself could be named after what it describes, for example children//1. You can define a calling predicate, let's also give it a nice descriptive name, say node_children/2, that uses phrase/2 to call the DCG:



    node_children(N,C) :-
    node(N,Succs), % Succs are the direct successors of node N
    phrase(children(Succs),C). % based on them the DCG children//1 describes the list C


    The DGC children//1 has to describe a list that consists of all the nodes in its argument-list and their respective children, that is, their respective successors, their successors' successors, and so on (that wording already bears the scent of recursion :-). So children//1 might look something like this:



    children() -->       % if there are no nodes
    . % there are no children
    children([N|Ns]) --> % N, the first node in the list...
    {node(N,Succs)}, % ...has the direct successors Succs...
    [N], % ...and is in the list of children...
    children(Succs), % ...as well as its successors and their children...
    children(Ns). % ...as well as the other nodes in the list


    In the first goal of the recursive rule of children//1, {node(N,Succs)}, you can observe how predicates can be called in a DCG, namely enclosed by braces. Now let's see node_children/2 in action:



       ?- node_children(a,C).
    C = [b,c,d,e,f]
    ?- node_children(b,C).
    C =
    ?- node_children(c,C).
    C = [d,e,f]


    You can also ask more general queries like What nodes and respective children are there?:



       ?- node_children(N,C).
    C = [b,c,d,e,f],
    N = a ? ;
    C = ,
    N = b ? ;
    C = [d,e,f],
    N = c ? ;
    C = ,
    N = d ? ;
    C = ,
    N = e ? ;
    C = ,
    N = f


    Or Which nodes have three children?:



       ?- C=[_,_,_], node_children(N,C).
    C = [d,e,f],
    N = c ? ;
    no


    Two closing remarks: You can see how the DCG children//1 is translated into a predicate by querying ?- listing(children).. To learn more about DCGs I can wholeheartedly recommend this DCG Primer.






    share|improve this answer




























      3














      Since you are interested in a list, why not considering the use of DCGs for the task? After all, DCGs describe lists and they yield easily readable code. Conveniently, your given facts node/2 provide the direct successors of a node in a list, so it is opportune to use a list of nodes to be visited as the DCGs single argument. The DCG itself could be named after what it describes, for example children//1. You can define a calling predicate, let's also give it a nice descriptive name, say node_children/2, that uses phrase/2 to call the DCG:



      node_children(N,C) :-
      node(N,Succs), % Succs are the direct successors of node N
      phrase(children(Succs),C). % based on them the DCG children//1 describes the list C


      The DGC children//1 has to describe a list that consists of all the nodes in its argument-list and their respective children, that is, their respective successors, their successors' successors, and so on (that wording already bears the scent of recursion :-). So children//1 might look something like this:



      children() -->       % if there are no nodes
      . % there are no children
      children([N|Ns]) --> % N, the first node in the list...
      {node(N,Succs)}, % ...has the direct successors Succs...
      [N], % ...and is in the list of children...
      children(Succs), % ...as well as its successors and their children...
      children(Ns). % ...as well as the other nodes in the list


      In the first goal of the recursive rule of children//1, {node(N,Succs)}, you can observe how predicates can be called in a DCG, namely enclosed by braces. Now let's see node_children/2 in action:



         ?- node_children(a,C).
      C = [b,c,d,e,f]
      ?- node_children(b,C).
      C =
      ?- node_children(c,C).
      C = [d,e,f]


      You can also ask more general queries like What nodes and respective children are there?:



         ?- node_children(N,C).
      C = [b,c,d,e,f],
      N = a ? ;
      C = ,
      N = b ? ;
      C = [d,e,f],
      N = c ? ;
      C = ,
      N = d ? ;
      C = ,
      N = e ? ;
      C = ,
      N = f


      Or Which nodes have three children?:



         ?- C=[_,_,_], node_children(N,C).
      C = [d,e,f],
      N = c ? ;
      no


      Two closing remarks: You can see how the DCG children//1 is translated into a predicate by querying ?- listing(children).. To learn more about DCGs I can wholeheartedly recommend this DCG Primer.






      share|improve this answer


























        3












        3








        3







        Since you are interested in a list, why not considering the use of DCGs for the task? After all, DCGs describe lists and they yield easily readable code. Conveniently, your given facts node/2 provide the direct successors of a node in a list, so it is opportune to use a list of nodes to be visited as the DCGs single argument. The DCG itself could be named after what it describes, for example children//1. You can define a calling predicate, let's also give it a nice descriptive name, say node_children/2, that uses phrase/2 to call the DCG:



        node_children(N,C) :-
        node(N,Succs), % Succs are the direct successors of node N
        phrase(children(Succs),C). % based on them the DCG children//1 describes the list C


        The DGC children//1 has to describe a list that consists of all the nodes in its argument-list and their respective children, that is, their respective successors, their successors' successors, and so on (that wording already bears the scent of recursion :-). So children//1 might look something like this:



        children() -->       % if there are no nodes
        . % there are no children
        children([N|Ns]) --> % N, the first node in the list...
        {node(N,Succs)}, % ...has the direct successors Succs...
        [N], % ...and is in the list of children...
        children(Succs), % ...as well as its successors and their children...
        children(Ns). % ...as well as the other nodes in the list


        In the first goal of the recursive rule of children//1, {node(N,Succs)}, you can observe how predicates can be called in a DCG, namely enclosed by braces. Now let's see node_children/2 in action:



           ?- node_children(a,C).
        C = [b,c,d,e,f]
        ?- node_children(b,C).
        C =
        ?- node_children(c,C).
        C = [d,e,f]


        You can also ask more general queries like What nodes and respective children are there?:



           ?- node_children(N,C).
        C = [b,c,d,e,f],
        N = a ? ;
        C = ,
        N = b ? ;
        C = [d,e,f],
        N = c ? ;
        C = ,
        N = d ? ;
        C = ,
        N = e ? ;
        C = ,
        N = f


        Or Which nodes have three children?:



           ?- C=[_,_,_], node_children(N,C).
        C = [d,e,f],
        N = c ? ;
        no


        Two closing remarks: You can see how the DCG children//1 is translated into a predicate by querying ?- listing(children).. To learn more about DCGs I can wholeheartedly recommend this DCG Primer.






        share|improve this answer













        Since you are interested in a list, why not considering the use of DCGs for the task? After all, DCGs describe lists and they yield easily readable code. Conveniently, your given facts node/2 provide the direct successors of a node in a list, so it is opportune to use a list of nodes to be visited as the DCGs single argument. The DCG itself could be named after what it describes, for example children//1. You can define a calling predicate, let's also give it a nice descriptive name, say node_children/2, that uses phrase/2 to call the DCG:



        node_children(N,C) :-
        node(N,Succs), % Succs are the direct successors of node N
        phrase(children(Succs),C). % based on them the DCG children//1 describes the list C


        The DGC children//1 has to describe a list that consists of all the nodes in its argument-list and their respective children, that is, their respective successors, their successors' successors, and so on (that wording already bears the scent of recursion :-). So children//1 might look something like this:



        children() -->       % if there are no nodes
        . % there are no children
        children([N|Ns]) --> % N, the first node in the list...
        {node(N,Succs)}, % ...has the direct successors Succs...
        [N], % ...and is in the list of children...
        children(Succs), % ...as well as its successors and their children...
        children(Ns). % ...as well as the other nodes in the list


        In the first goal of the recursive rule of children//1, {node(N,Succs)}, you can observe how predicates can be called in a DCG, namely enclosed by braces. Now let's see node_children/2 in action:



           ?- node_children(a,C).
        C = [b,c,d,e,f]
        ?- node_children(b,C).
        C =
        ?- node_children(c,C).
        C = [d,e,f]


        You can also ask more general queries like What nodes and respective children are there?:



           ?- node_children(N,C).
        C = [b,c,d,e,f],
        N = a ? ;
        C = ,
        N = b ? ;
        C = [d,e,f],
        N = c ? ;
        C = ,
        N = d ? ;
        C = ,
        N = e ? ;
        C = ,
        N = f


        Or Which nodes have three children?:



           ?- C=[_,_,_], node_children(N,C).
        C = [d,e,f],
        N = c ? ;
        no


        Two closing remarks: You can see how the DCG children//1 is translated into a predicate by querying ?- listing(children).. To learn more about DCGs I can wholeheartedly recommend this DCG Primer.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 14 '18 at 21:17









        tastas

        7,3922720




        7,3922720






























            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%2f53296522%2fgetting-a-list-of-children-for-a-node-in-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

            Bressuire

            Vorschmack

            Quarantine