I'm trying to "reverse" an inorder traversal by turning the inorder list back into BSTs.
BSTs has the predicate form node(Value,Left,Right)
or leaf
, so the empty tree is just leaf
, a tree with one node is node(_,leaf,leaf)
.
Given the predicate enumerate_bst(Elems,Bst)
, the goal is to match Bst
to all possibilities of the inorder list Elems
. For example (note setof/3):
?- setof(Bst,enumerate_bst([],Bst),Enum).
Enum = [leaf].
?- setof(Bst,enumerate_bst([1,2],Bst),Enum).
Enum = [
node(1, leaf, node(2, leaf, leaf)),
node(2, node(1, leaf, leaf), leaf)
].
?- setof(Bst,enumerate_bst([1,2,3],Bst),Enum).
Enum = [
node(1, leaf, node(2, leaf, node(3, leaf, leaf))),
node(1, leaf, node(3, node(2, leaf, leaf), leaf)),
node(2, node(1, leaf, leaf), node(3, leaf, leaf)),
node(3, node(1, leaf, node(2, leaf, leaf)), leaf),
node(3, node(2, node(1, leaf, leaf), leaf), leaf)
].
What I tried to do:
I already have a predicate that matches a given BST to it's inorder list:
inorder(leaf,[]).
inorder(node(X,L,R),Elems) :-
inorder(L,Elems_L),
inorder(R,Elems_R),
append(Elems_L,[X],Tmp),
append(Tmp,Elems_R,Elems).
I tried to use it in reverse by putting in a list instead, but this only returned one result, I'm not exactly sure why.
What I'm currently trying to do
I'm trying to use the native predicate append/3 in reverse, but can't fully decide how this will be done.
Any ideas as to the best way to do this? Thanks!