I am trying to write a Prolog predicate that gives a possible binary search tree for a given traversal. I chose to represent the tree like t(Root, Left Subtree, Right Subtree)
, leaves are simply t(Number)
and when a subtree does not exist its value is nil
.
This is what I have so far (only for postorder traversal in this case):
post(nil, []).
post(t(X), [X]).
post(t(N, L, R), T) :-
post(L, TL), post(R, TR),
append([TL, TR, [N]], T).
This works nicely in one way, but hangs in the other direction:
?- post(t(8, t(5, t(2), nil), t(12, t(9), t(16))), Trav).
Trav = [2, 5, 9, 16, 12, 8].
?- post(Tree, [2, 5, 9, 16, 12, 8]).
Tree = t(8, nil, t(12, nil, t(16, nil, t(9, nil, t(5, nil, t(2)))))) ;
Tree = t(8, nil, t(12, nil, t(16, nil, t(9, nil, t(5, nil, t(2, nil, nil)))))) ;
[execution hangs here]
I realized that post
does not require a binary search tree, ie there is no requirement for all nodes in the left subtree to be less than the root node and all nodes in the right subtree to be greater than the root node, so I also wrote this:
tree(t(_)).
tree(nil).
tree(t(N, L, R)) :-
tree(L), tree(R),
( L = t(NL, _, _) -> NL < N ; true ),
( R = t(NR, _, _) -> NR > N ; true ).
I thought I could just do ?- post(Tree, [...]), tree(Tree).
to make Prolog only return actual binary search trees. However, I seem to be stuck already at generating possible trees.
How could I improve my code? Is this even doable?
nil
ort(Value, Left, Right)
, and then a leaf node ist(Value, nil, nil)
. – TA_intern