Simultaneous grafting on rose trees #
This file defines multiGraft T pairs, which grafts several trees onto T at once. Each pair
(p, S) names a vertex of T by its address p and a tree S to become a new child of that
vertex; every address is read in the original T, as in Foissy's multiple grafting. Trees
grafted at the same vertex are prepended in the order of the pair list, so multiGraft depends on
that order, and Insertion.lean recovers independence of it once children are unordered.
Main definitions #
multiGraft,multiGraftChildren: simultaneous grafting into a tree and into a forest.rootPrependFilter,headChildFilter,tailChildFilter: the pairs aimed at the root, at the first child, and at the later children, with the addresses shortened accordingly.
Main results #
filterMap_rootPrependFilter,filterMap_headChildFilter,filterMap_tailChildFilter: each filter is aList.filteron the address followed by a projection.multiGraft_nil: grafting nothing leaves the tree unchanged.
Implementation notes #
The three filters are top-level definitions rather than inline match expressions so that every
caller elaborates the same matcher, which lets their filterMap equations rewrite across files.
References #
Routing the pairs #
A pair aimed at the root yields its tree.
Equations
- RoseTree.rootPrependFilter pair = match pair.1 with | [] => some pair.2 | head :: tail => none
Instances For
A pair aimed inside the first child yields the pair with the leading index removed.
Equations
- RoseTree.headChildFilter pair = match pair.1 with | 0 :: rest => some (rest, pair.2) | x => none
Instances For
A pair aimed inside a later child yields the pair with the leading index decremented.
Equations
- RoseTree.tailChildFilter pair = match pair.1 with | k.succ :: rest => some (k :: rest, pair.2) | x => none
Instances For
Simultaneous grafting #
multiGraft T pairs grafts the tree of each pair at the vertex its address names. The trees
aimed at the root are prepended to its children in pair-list order; the other pairs descend into
the child their first index names.
Equations
- (RoseTree.node a cs).multiGraft x✝ = RoseTree.node a (List.filterMap RoseTree.rootPrependFilter x✝ ++ RoseTree.multiGraftChildren cs x✝)
Instances For
multiGraftChildren cs pairs grafts into the forest cs, where the first index of each
address names a tree of cs.
Equations
- RoseTree.multiGraftChildren [] x✝ = []
- RoseTree.multiGraftChildren (c :: cs) x✝ = c.multiGraft (List.filterMap RoseTree.headChildFilter x✝) :: RoseTree.multiGraftChildren cs (List.filterMap RoseTree.tailChildFilter x✝)
Instances For
Filter characterizations #
Each pair filter is a List.filter on the address followed by a projection, so Insertion.lean
can split the pair lists by a predicate on addresses.
Grafting keeps the root value.
multiGraftChildren depends on its pair list only through the two child filters.
Root pairs never reach the children.
multiGraftChildren cs pairs has the same length as cs.
Grafting nothing leaves a tree unchanged.
Grafting nothing leaves a forest unchanged.