Nonplanar n-ary rooted trees as a quotient of RoseTree α #
[MCB25] [foissy-introduction-hopf-algebras-trees]
A nonplanar rooted tree is a RoseTree α modulo the equivalence
relation generated by:
- swapping two adjacent children of any vertex
- replacing a child with a nonplanar-equivalent tree (recursive step)
The quotient Nonplanar α := Quotient RoseTree.instSetoid gives the carrier MCB §1.1.2 +
§1.10 actually wants for syntactic objects: trees with unordered
children at each node.
Strategy #
Define a primitive PermStep relation that captures a single elementary
move (a swap or a recursive substitution), then take the equivalence
closure via Relation.EqvGen. This way:
- The equivalence relation IS automatically an equivalence (via the
reflexive/symmetric/transitive constructors of
EqvGen). - Proving things about it reduces to handling the elementary
PermStepcases plus the equivalence-closure constructors.
Foissy connection #
With Nonplanar α as carrier, B+_a : Multiset (Nonplanar α) → Nonplanar α
becomes well-defined: graft the multiset of children under a new root
labeled a. (For RoseTree α with multiset forests, B+ wasn't well-defined
because the resulting tree's child-list ordering depended on choice of
multiset representative.) This unblocks Foissy's clean cocycle proof of
Δ^p coassoc on the nonplanar Hopf algebra (Phase A.7).
MCB anchor #
[MCB25] §1.1.3 (book p. 20) — explicit
caveat: {α, {β, γ}} = α △ β γ = α △ γ β = γ β △ α. This file's
Nonplanar α realizes that unordered-children semantics for general
arity.
Status #
[UPSTREAM] candidate. No sorries.
PermStep — elementary moves #
A PermStep t s says: s is obtained from t by either:
- swapping two adjacent children of some vertex, or
- replacing a single child with a tree related by
PermStep(recursion).
A single-step child-permutation move on a rooted tree.
- swapAtRoot
{α : Type u_1}
{a : α}
{l r : RoseTree α}
{pre post : List (RoseTree α)}
: (node a (pre ++ l :: r :: post)).PermStep (node a (pre ++ r :: l :: post))
Swap two adjacent children at the root vertex.
- recurse
{α : Type u_1}
{a : α}
{pre : List (RoseTree α)}
{old new : RoseTree α}
{post : List (RoseTree α)}
(h : old.PermStep new)
: (node a (pre ++ old :: post)).PermStep (node a (pre ++ new :: post))
Apply a step inside a child subtree, leaving siblings unchanged.
Instances For
PermEquiv — equivalence closure #
The nonplanar-equivalence relation on trees: the equivalence
closure of PermStep. Built using Relation.EqvGen, so it's
automatically reflexive / symmetric / transitive.
Nonplanar equivalence on trees: equivalence closure of PermStep.
Equations
- RoseTree.PermEquiv = Relation.EqvGen RoseTree.PermStep
Instances For
Lifting structural invariants from RoseTree to Nonplanar #
Functions RoseTree α → β that are invariant under PermStep lift
through the equivalence closure to functions Nonplanar α → β. Below
we lift numNodes (vertex count) and the other counts as worked examples.
The pattern: prove invariance under the elementary PermStep, then
extend to PermEquiv = EqvGen PermStep by an EqvGen induction. On
RoseTree the counts sum/foldr-max directly over cs.map …, so
permutation invariance is just List.Perm.sum_eq / List.Perm.foldr_eq
on the child list.
Node count invariance #
Leaf-count invariance #
Value invariance #
Lifting child-list operations to PermEquiv #
The smart constructor Nonplanar.node needs to know that the
parent-node equivalence respects the natural list-of-children
operations: cons (sibling-prepend), permutation, and componentwise
equivalence.
Arity / depth / isLeaf invariance #
Three more invariants of tree structure that are preserved by
PermEquiv. The pattern follows numNodes: prove *_permStep
by case on the step constructor, then lift to *_permEquiv via
EqvGen induction.
Setoid instance #
The setoid on RoseTree α whose quotient is Nonplanar α.
Equations
- RoseTree.instSetoid = { r := RoseTree.PermEquiv, iseqv := ⋯ }
Nonplanar — the quotient type #
A nonplanar n-ary rooted tree with α-labeled vertices: the quotient
of RoseTree α by PermEquiv.
Equations
- RootedTree.Nonplanar α = Quotient RoseTree.instSetoid
Instances For
The canonical projection from ordered to nonplanar trees.
Equations
- RootedTree.Nonplanar.mk t = ⟦t⟧
Instances For
Lift a function RoseTree α → β that's invariant under PermEquiv
to Nonplanar α → β.
Equations
- RootedTree.Nonplanar.lift f h = Quotient.lift f h
Instances For
Smart leaf constructor + lifted counts #
A leaf in Nonplanar α is mk (RoseTree.leaf a). numNodes is the
canonical first lifted invariant.
A nonplanar leaf labeled a.
Equations
Instances For
The node count (number of vertices) of a nonplanar tree, lifted
from RoseTree.numNodes via PermEquiv-invariance.
Instances For
The leaf count (number of childless vertices) of a nonplanar tree,
lifted from RoseTree.numLeaves via PermEquiv-invariance. MCB's
complexity grading #L (Def. 1.6.2) is built on this.
Instances For
The arity (root child count) of a nonplanar tree.
Instances For
The depth (longest root-to-leaf path in vertices) of a nonplanar tree.
Instances For
A nonplanar tree is a leaf if its root has no children. (Audit
item: queue migrate to Prop + [DecidablePred] once the matching
RoseTree.isLeaf is migrated.)
Instances For
Destructors and node injectivity #
The root value and the children (as a multiset of nonplanar trees) are
PermEquiv-invariant, so they descend to Nonplanar. congrArg on these destructors
inverts mk-equality at a node with no induction, giving the injectivity
characterization mk_node_eq_mk_node_iff.
The root value of a nonplanar tree.
Instances For
The children of a nonplanar tree, as a multiset of nonplanar trees.
Equations
- RootedTree.Nonplanar.children = RootedTree.Nonplanar.lift (fun (t : RoseTree α) => ↑(List.map RootedTree.Nonplanar.mk t.children)) ⋯
Instances For
Injectivity of the node constructor on the quotient: mk-images of two nodes are
equal iff the root values agree and the children agree as multisets of nonplanar
trees. The forward direction is congrArg on the value and children
destructors; the backward direction assembles a PermEquiv componentwise.
Smart node constructor #
The B+ operator (Phase A.7) and the Δ^c trace coproduct (Phase D) both
require building a Nonplanar α from a label and an unordered
collection of children. The smart constructor node a cs does this on
Multiset (Nonplanar α); well-definedness follows from
RoseTree.permEquiv_root_perm (children-list permutation invariance).
The characterization node_mk_tree_list then bridges back to the
underlying RoseTree node via Quotient.mk_out componentwise.
Build a Nonplanar α from a label and an unordered multiset of
children. Implementation: pick a list representative of the
multiset (Quotient.liftOn), then per-child tree representatives
via Quotient.out, and quotient back.
Equations
- RootedTree.Nonplanar.node a cs = Quotient.liftOn cs (fun (lst : List (RootedTree.Nonplanar α)) => RootedTree.Nonplanar.mk (RoseTree.node a (List.map Quotient.out lst))) ⋯
Instances For
Sanity tests #
Root value and children #
Root-level projections, lifted through the quotient: RoseTree.value is
PermEquiv-invariant on the nose (value_permEquiv), and the
mk-image of RoseTree.children is invariant as a multiset (root swaps
permute the list; recursive steps rewrite a child within its mk-class).
The root value of a nonplanar tree.
Instances For
The multiset of root children of a nonplanar tree.
Equations
- RootedTree.Nonplanar.rootChildren = RootedTree.Nonplanar.lift (fun (t : RoseTree α) => ↑(List.map RootedTree.Nonplanar.mk t.children)) ⋯
Instances For
Eta law: every tree is the node of its root value and root children.
Functoriality of map under PermEquiv #
Setup for Nonplanar.map: lift RoseTree.map through the quotient by
showing it preserves the equivalence relation. Done in two steps:
elementary PermStep preservation, then closure under EqvGen.
RoseTree.map preserves PermEquiv (the equivalence closure of
PermStep). Substrate for Nonplanar.map.
Functoriality #
Lift RoseTree.map through the quotient. Counterpart of List.map for
lists: a function f : α → β lifts to Nonplanar α → Nonplanar β by
relabeling every vertex.
Map a function over the vertex labels of a nonplanar rooted tree.
Lifted from RoseTree.map via Quotient.map.
Equations
- RootedTree.Nonplanar.map f = Quotient.map (RoseTree.map f) ⋯
Instances For
Quotient-unfolding for Nonplanar.map. Plain lemma (not @[simp])
since mathlib's generic Quotient.map_mk covers the same ground.