Unordered rooted trees #
An unordered rooted tree with vertices labelled in α is a RoseTree α modulo the permutation
of children at every vertex: the quotient UnorderedTree α := Quotient RoseTree.isSetoid. In the
Connes–Kreimer literature, as in Foissy's introduction, these are the rooted trees and the
ordered ones the planar rooted trees. The identity criterion is RoseTree.Perm
(Core/Data/RoseTree/Perm.lean); this file owns the quotient: the projection mk, the lifting
API, the lifted invariants, and the constructor node on Multiset children, under which the
grafting B⁺ of a multiset of trees is well defined.
Main definitions #
UnorderedTree,UnorderedTree.mk: the quotient and its projection; operations descend throughQuotient.liftand proofs throughQuotient.inductionOn, as forMultiset.UnorderedTree.cons: adjoin a tree as a further child of the root, the transport of the list cons on children; it is left-commutative, soMultiset.foldrbuilds the constructorUnorderedTree.nodeon a multiset of children computably.UnorderedTree.induction_on,UnorderedTree.fold: induction and recursion on a tree as a label over a multiset of trees.UnorderedTree.para: recursion in which each step also sees the children themselves, so that subtree-sensitive functions are defined on the quotient with no invariance proof.
References #
The quotient type #
An unordered rooted tree with α-labelled vertices, the quotient of RoseTree α by the
permutation of children at every vertex (RoseTree.Perm).
Equations
- UnorderedTree α = Quotient RoseTree.isSetoid
Instances For
The canonical projection from ordered to nonplanar trees.
Equations
- UnorderedTree.mk t = ⟦t⟧
Instances For
Leaves and lifted counts #
A nonplanar leaf labeled a.
Equations
Instances For
The number of vertices of a nonplanar tree.
Equations
- UnorderedTree.numNodes = Quotient.lift RoseTree.numNodes ⋯
Instances For
The number of childless vertices of a nonplanar tree.
Equations
- UnorderedTree.numLeaves = Quotient.lift RoseTree.numLeaves ⋯
Instances For
The number of children of the root.
Equations
- UnorderedTree.arity = Quotient.lift RoseTree.arity ⋯
Instances For
The number of vertices on a longest root-to-leaf path.
Equations
- UnorderedTree.height = Quotient.lift RoseTree.height ⋯
Instances For
Destructors and node injectivity #
The root value and the children (as a multiset of nonplanar trees) are
RoseTree.Perm-invariant, so they descend to UnorderedTree. Node injectivity,
mk_node_eq_mk_node_iff, is RoseTree.perm_node_iff read through mk.
The root value of a nonplanar tree.
Equations
- UnorderedTree.value = Quotient.lift RoseTree.value ⋯
Instances For
The children of a nonplanar tree, as a multiset of nonplanar trees.
Equations
- UnorderedTree.children = Quotient.lift (fun (t : RoseTree α) => ↑(List.map UnorderedTree.mk t.children)) ⋯
Instances For
Adjoining a child, and the node constructor #
cons c t adjoins c as a further child of the root of t; it is the transport of the list
cons on children lists and is left-commutative, so node a F is its Multiset.foldr over the
children F starting from the leaf a. Both are computable, and node_mk_tree_list reads
node back on a list of planar children.
Adjoin a tree as a further child of the root.
Equations
- c.cons t = Quotient.liftOn₂ c t (fun (c t : RoseTree α) => UnorderedTree.mk (RoseTree.node t.value (c :: t.children))) ⋯
Instances For
Build an unordered tree from a label and a multiset of children, by adjoining the children one at a time to the leaf.
Equations
- UnorderedTree.node a F = Multiset.foldr UnorderedTree.cons (UnorderedTree.leaf a) F
Instances For
Structural induction and recursion #
An unordered tree is a label over a multiset of unordered trees. induction_on, fold and
para are the induction, recursion and paramorphism principles of that description; a function
defined through them needs no proof of invariance under RoseTree.Perm.
Induction on an unordered tree proves motive t for all t from motive (node a F) given
motive c for every child c ∈ F.
The catamorphism replaces each node a F by f a of the multiset of folded children.
Equations
- UnorderedTree.fold f = Quotient.lift (RoseTree.fold fun (a : α) (bs : List β) => f a ↑bs) ⋯
Instances For
The paramorphism passes f a each child together with its value. It is the fold into
pairs whose first component rebuilds the subtree.
Equations
- UnorderedTree.para f t = (UnorderedTree.fold (fun (a : α) (ps : Multiset (UnorderedTree α × β)) => (UnorderedTree.node a (Multiset.map Prod.fst ps), f a ps)) t).2
Instances For
Functoriality #
Relabel every vertex of a nonplanar tree.
Equations
- UnorderedTree.map f = Quotient.map (RoseTree.map f) ⋯