Hello Juan,
This is because you are not providing all the context to the questions you ask :-(
I am guessing, having answered your previous email, that this is something you are doing in a course, and that the facts are something you were given, not something you came up with. You are probably going through the different ways to represent a tree data structure: before you had a tree as a compound term.
(BTW, still not sure what is the benefit of using nested lists instead of nested terms: why was your tree like this:
[[[], a, []], b, [[], c, []]]
instead of like this:
t(b, t(a, [], []), t(c, [], []))
But I digress.)
Now you are representing any number of binary trees as a "flattened" list of nodes (aka "Adjacency list"). I guess if you have a relational database, you would have a single table with four columns, one for the ID of the node, one for the value, and two columns for the IDs of the left and right child.
@Barbara: the ID is necessary if you have more than one tree or if the tree might have the same value in different nodes.
In the query you show, you are asking: "What is the value of the parent node of a node with a value 3, in the tree with root a4?"
You could google something like "relational database binary tree" or "binary tree adjacency list" and so on and read a bit on the subject, if your course material does not provide enough detail or good references.
The point is, again, there is not enough context, and both Barbara and me have to guess what exactly you are doing. Her solution is correct, if you knew that you have only one tree, and the values are unique.
Even in the case of "many trees in one table, node values not unique within a tree or in the table" you can start as she showed you, then go up the tree to check if you find the root you were given in the query. Or you could instead go down the tree starting at the given root, looking for the node with the ID you found.
You only have to add definitions for the edges where the first two arguments are the nodes, as expected by the path meta-predicate. I will call them up/2 and down/2, depending which way you want to do it. So I saved the code from the link above in a file
path.pl, and I now have this:
==
?- listing(tree).
tree(a4, 6, b3, b4).
tree(b3, 7, c1, c2).
tree(c1, 5, d1, nil).
tree(d1, 1, nil, nil).
tree(c2, 3, nil, d2).
tree(d2, 4, nil, nil).
tree(b4, 8, c3, c4).
tree(c3, 10, nil, nil).
tree(c4, 11, d3, d4).
tree(d3, 9, nil, nil).
tree(d4, 2, nil, nil).
true.
?- listing(up).
up(B, A) :-
tree(A, _, B, _).
up(B, A) :-
tree(A, _, _, B).
true.
?- listing(down).
down(A, B) :-
tree(A, _, B, _).
down(A, B) :-
tree(A, _, _, B).
true.
?- [path].
true.
?- tree(X, 3, _, _),
( tree(X0, R, X, _) % as in Barbara's solution
; tree(X0, R, _, X)
),
path(up, Path, X, a4). % a path up the tree to the root
X = c2,
X0 = b3,
R = 7,
Path = [c2, b3, a4] ;
false.
?- tree(X, 3, _, _),
( tree(X0, R, X, _) % as in Barbara's solution
; tree(X0, R, _, X)
),
path(down, Path, a4, X). % a path down from the root
X = c2,
X0 = b3,
R = 7,
Path = [a4, b3, c2] ;
false.==
The last two queries show you how you could search either up or down the tree.
Since you know that a binary tree is a directed, acyclic graph, you can get rid of some of the code in the definition of path. I will let you figure out what you can safely leave out.
Cheers,
Boris