Function Repository Resource:

AncestralTreeScan

Source Notebook

Perform a depth-first scan of a tree with access to computations made on the current vertex's ancestors

Contributed by: Daniel McDonald

ResourceFunction["AncestralTreeScan"][function,outputFunction,tree]

performs a depth-first scan of function over tree, where function is passed the history of computations performed at ancestral vertices.

Details

Scanning a tree is also known as tree traversal or tree search. ResourceFunction["AncestralTreeScan"] always visits vertices according to a depth-first traversal.
Scanning a tree is typically used to carry out an operation on subtrees where the operation has a "side effect", such as making an assignment.
ResourceFunction["AncestralTreeScan"][f,g,t] performs a depth-first scan of the tree t, where the following arguments are passed to the function f at the current vertex v: the list of computations made on the vertices of the tree on the path from the root to the parent of v (which will always be the empty list if v is the root), and the datum extracted from t at v. At v, this output of f is appended to the list of computations, before this updated list is passed as the lone argument to the output function g. In this way a sequence of values computed at the vertices of the tree can be output, where the value to be computed at a given vertex depends on the values computed at its ancestors, without repeating computations or storing more computed values than just those belonging to the ancestors of the given vertex.

Examples

Basic Examples (2) 

Create a tree:

In[1]:=
tree = RandomTree[10]
Out[1]=

Scan the tree:

In[2]:=
ResourceFunction["AncestralTreeScan"][
 f,
 Print@*g,
 tree
 ]

Create a tree whose vertices are numbers:

In[3]:=
addTree = RandomTree[10]
Out[3]=

Find each sequence of incremental sums from the root to a vertex, without having to repeat the computation of any partial sums:

In[4]:=
ResourceFunction["AncestralTreeScan"][
 Function[{sumList, addend},
  If[sumList == {}, addend, Last@sumList + addend]
  ],
 Print,
 addTree
 ]

Applications (3) 

Store all permutations of {a,b,c,d} as paths from the root id to leaves:

In[5]:=
permTree = ResourceFunction["AncestralNestTree"][
  Complement[{"a", "b", "c", "d"}, #] &, Tree["id", None], Infinity]
Out[5]=

Associate each of a,b,c,d with square matrices, and id with the identity matrix:

In[6]:=
matrixAssociation = Append[AssociationMap[
   RandomInteger[{-5, 5}, {2, 2}] &, {"a", "b", "c", "d"}], "id" -> IdentityMatrix[2]]
Out[6]=

Find all matrix products involving each matrix at most once without having to repeat subcomputations or store more than five matrix products at a time:

In[7]:=
ResourceFunction["AncestralTreeScan"][
 Function[{productList, matKey},
  {matKey, If[productList == {}, matrixAssociation[matKey], productList[[-1, 2]] . matrixAssociation[matKey]]}
  ],
 Function[{productList},
  Print[If[Length@productList == 1, productList[[1, 1]], Dot @@ Rest@productList[[All, 1]]] == productList[[-1, 2]]]
  ],
 permTree
 ]

Publisher

Daniel McDonald

Requirements

Wolfram Language 13.0 (December 2021) or above

Version History

  • 1.0.0 – 03 September 2025

Related Resources

License Information