Getting a list of children for a node in Prolog
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
|
show 6 more comments
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
What do you thinknode_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 definechildren(node(_, Kids), Kids).
, then queries such aschildren(node(123, foo), foo).
succeed. Also, Prolog doesn't know that thenode/2
inside yourchildren/2
fact is the same as thenode/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 thatchildren(whatever)
, can only betrue
orfalse
(or raise an error, or get stuck in an infinite loop).
– Willem Van Onsem
Nov 14 '18 at 11:38
@CapelliCnode_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
|
show 6 more comments
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
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
search tree prolog
asked Nov 14 '18 at 9:10
Matthew TMatthew T
5010
5010
What do you thinknode_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 definechildren(node(_, Kids), Kids).
, then queries such aschildren(node(123, foo), foo).
succeed. Also, Prolog doesn't know that thenode/2
inside yourchildren/2
fact is the same as thenode/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 thatchildren(whatever)
, can only betrue
orfalse
(or raise an error, or get stuck in an infinite loop).
– Willem Van Onsem
Nov 14 '18 at 11:38
@CapelliCnode_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
|
show 6 more comments
What do you thinknode_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 definechildren(node(_, Kids), Kids).
, then queries such aschildren(node(123, foo), foo).
succeed. Also, Prolog doesn't know that thenode/2
inside yourchildren/2
fact is the same as thenode/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 thatchildren(whatever)
, can only betrue
orfalse
(or raise an error, or get stuck in an infinite loop).
– Willem Van Onsem
Nov 14 '18 at 11:38
@CapelliCnode_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
|
show 6 more comments
1 Answer
1
active
oldest
votes
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.
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%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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 14 '18 at 21:17
tastas
7,3922720
7,3922720
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%2f53296522%2fgetting-a-list-of-children-for-a-node-in-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
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 aschildren(node(123, foo), foo).
succeed. Also, Prolog doesn't know that thenode/2
inside yourchildren/2
fact is the same as thenode/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 betrue
orfalse
(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