Prolog - Tree Traversal.
Breadth First Tree Traversal
This program performs breadth-first traversal of a tree, placing the results in a list in that order. It can be run in "reverse" (also see Append) to find those trees, if any, that would give a particular list when traversed:
-
append(nil, B, B). append(cons(A,As), B, cons(A, AsB)) <= append(As, B, AsB). bft(nil, nil). bft(cons(fork(empty, E, empty), Q), cons(E, BFL)) <= bft(Q, BFL). bft(cons(fork(empty, E, R), Q), cons(E, BFL)) <= append(Q, cons(R,nil), Q2) and bft(Q2, BFL). bft(cons(fork(L, E, empty), Q), cons(E, BFL)) <= append(Q, cons(L,nil), Q2) and bft(Q2, BFL). bft(cons(fork(L, E, R), Q), cons(E, BFL)) <= append(Q, cons(L,cons(R,nil)), Q2) and bft(Q2, BFL). {Query:} ? bft(cons(T,nil), cons(a, cons(b, cons(c, nil)))). {comment one query out: ? bft(cons(fork(fork(empty,1,empty), 2, fork(empty,3,empty)), nil), BFL). } {Loosely based on csc3030 Programming Paradigms exam Q5 1994} {have to make the rules exclusive and exhaustive for the toy} {interpreter - muprolog is cleverer } {see the muprolog examples directory for the real thing. }
- There are, in general, multiple trees that would give the same breadth-first order to a given list of nodes.
Infix Tree Traversal
A program can easily be written to perform infix traversal of a binary tree. However this will not easily run backwards in a Prolog system with only a simple top-down left-to-right evaluation strategy. Either a more complex evaluation strategy is needed or the program must be modified:
append(c(H,T), L, c(H,T2)) <= append(T, L, T2). append(nil, L, L). unground(someUniqueNonsense). {a hack! eg. unground(X) } ground(X) <= not unground(X). {a hack! eg. ground(c( , )) } {does not consider the possibility of} {being partially ground.} {-----------------} {only if the tree is ground, loops otherwise:} infix1(fork(L,E,R), INF) <= infix(L, LI) and infix(R, RI) and append(LI, c(E,RI), INF) . {only if the list is ground, loops otherwise:} infix2(fork(L,E,R), INF) <= append(LI, c(E,RI), INF) and infix(L, LI) and infix(R, RI) . infix(leaf(L), c(L,nil)). infix(T,L) <= ground(T) and infix1(T,L). infix(T,L) <= ground(L) and infix2(T,L). {Query:} ? infix(T, c(1,c(2,c(3,c(4,c(5,nil))))) ). {other query commented out: ? infix( fork(fork(leaf(1),2,leaf(3)), 4, fork(leaf(5),6,leaf(7))), L). } { Infix tree traversal, assumes strict top-down } { left-to-right search. Loosely based on CSC3030 } { Programming Paradigms exam, Q3; June 1993. } { Muprolog does not need the hack because it can } { dynamically reorder atoms within the query. } { The proper (Muprolog) example is in another directory. }