⚠️ LEGACY — RESTORED SHIM (2026-05-13) #
Restored from commit e0876460^ after deletion at 0.230.913. Consumer migration
(Phase D per scratch/mcb_full_architecture.md) hadn't happened; Merge stack
files broke on clean build. Will be re-deleted when Phase D lands — its
canonical replacement is Linglib/Core/Combinatorics/RootedTree/PlanarCut.lean
(Cut/ChildCut/ChildCutList mutual inductive on Planar α).
Do not extend, do not add new consumers.
Admissible Cuts on Trees @cite{marcolli-chomsky-berwick-2025} #
Per @cite{marcolli-chomsky-berwick-2025} Definition 1.2.6, an admissible cut of a binary rooted tree T is a removal of a collection of edges of T such that no two lie on the same root-to-leaf path. Equivalently (Lemma 1.2.7), the data of an admissible cut on T is the same as a forest F_v = T_{v₁} ⊔ ⋯ ⊔ T_{vₙ} of disjoint accessible terms of T.
Trees with scalar trace labels #
This file defines CutShape on TraceTree α β (not on DecoratedTree α).
The TraceTree carrier has scalar trace labels (.trace (b : β))
rather than recursive subtree data. This is the carrier the bialgebra
of @cite{marcolli-chomsky-berwick-2025} Lemma 1.2.10 actually inhabits;
see Decorated.lean for the rationale: per @cite{marcolli-skigin-2025}
§10.1 (clarifying the brief discussion in M-C-B §1.3), trace labels
are elements of a disjoint marked copy ̄SO₀ of the leaf alphabet,
NOT recursive subtrees, for the bialgebra structure to be well-formed.
For the bialgebra layer, β = Unit (no informative trace label) — the
minimal instance, sufficient for coassoc but a strict simplification
of M-S. For the linguistic layer (CI interpretation, FormCopy), a
richer β plus a head-function-transparent extractor realizes
@cite{marcolli-skigin-2025} Definition 10.3 (head function projects
each contracted subtree to its head leaf's struck-through label).
This file is [UPSTREAM] — generic over α : Type* and β : Type*.
Crucial M-C-B reading: leaves ARE accessible terms #
Per @cite{marcolli-chomsky-berwick-2025} Definition 1.2.2, accessible
terms are subtrees T_v for v ∈ V_int(T) := V(T) \ {root of T}.
M-C-B's "internal" excludes the root vertex but includes leaves —
so leaves of T are accessible terms. (Verified against the worked
example on book p. 35, inline in §1.2 just before §1.2.1.)
Representation: 5-constructor enum #
A CutShape T for T : TraceTree α β records cut choices position-
by-position. Leaves admit only the trivial pass-through (no edges to
cut); nodes have four choices based on (cut left edge?) × (cut right
edge?). The antichain condition (M-C-B Def 1.2.6: no two cuts on the
same root-leaf path) is baked in by construction.
Layer status #
[UPSTREAM]. Future home is something like
Mathlib.Combinatorics.HopfAlgebra.ConnesKreimer.AdmissibleCut. This
file is part of the Stage 0.5 hoist out of Theories/Syntax/Minimalist/Hopf/
(per scratch/mcb_stage1_plan.md).
- No sorries, no
noncomputable, nodecide.
§1: Cut shape #
Universe-polymorphic in α : Type* and β : Type*. The inductive
takes both as parameters (not per-constructor indices), letting mathlib
upstream reuse this construction over arbitrary leaf-and-trace-label types.
An admissible cut on a tree T : TraceTree α β.
Trace-extraction restriction (substrate fix for coassoc). The cuts that
EXTRACT a child subtree (bothCut, onlyLeftCut, onlyRightCut) require
that child to NOT be a .trace marker (IsNotTrace). Without this
restriction, iterated cuts on the remainder of an outer cut would
accumulate .trace-of-.trace nesting, breaking the cuts-of-cuts bijection
(M-C-B Lemma 1.2.10 / Foissy 2002 §2). With scalar trace labels (β not
DecoratedTree), this nesting is what causes the basis cardinality to blow
up; the IsNotTrace constraint prevents it.
The bothRecurse constructor — which doesn't extract anything at this node —
has no restriction; it composes recursively into the children's CutShapes.
The atomic atLeaf / atTrace constructors are also unrestricted.
- atLeaf
{α : Type u_3}
{β : Type u_4}
{a : α}
: CutShape (TraceTree.leaf a)
An α-leaf admits only the empty cut (no edges to cut).
- atTrace
{α : Type u_3}
{β : Type u_4}
{b : β}
: CutShape (TraceTree.trace b)
A trace leaf admits only the empty cut.
- bothCut
{α : Type u_3}
{β : Type u_4}
{l r : TraceTree α β}
(hl : l.IsNotTrace)
(hr : r.IsNotTrace)
: CutShape (l.node r)
Cut both child edges of this node. Requires both children to be non-trace (cuts cannot extract
.tracemarkers). - onlyLeftCut
{α : Type u_3}
{β : Type u_4}
{l r : TraceTree α β}
(hl : l.IsNotTrace)
(cr : CutShape r)
: CutShape (l.node r)
Cut the left child edge, recurse into
rwith sub-cutcr. Requires the left child to be non-trace. - onlyRightCut
{α : Type u_3}
{β : Type u_4}
{l r : TraceTree α β}
(hr : r.IsNotTrace)
(cl : CutShape l)
: CutShape (l.node r)
Recurse into
lwith sub-cutcl, cut the right child edge. Requires the right child to be non-trace. - bothRecurse
{α : Type u_3}
{β : Type u_4}
{l r : TraceTree α β}
(cl : CutShape l)
(cr : CutShape r)
: CutShape (l.node r)
Don't cut at this node; recurse in both children. No restrictions since nothing is extracted at this level.
Instances For
§2: The empty (trivial) cut #
The empty cut on T: extract nothing, leave T unchanged.
Equations
- ConnesKreimer.CutShape.empty (ConnesKreimer.TraceTree.leaf a) = ConnesKreimer.CutShape.atLeaf
- ConnesKreimer.CutShape.empty (ConnesKreimer.TraceTree.trace b) = ConnesKreimer.CutShape.atTrace
- ConnesKreimer.CutShape.empty (l.node r) = (ConnesKreimer.CutShape.empty l).bothRecurse (ConnesKreimer.CutShape.empty r)
Instances For
§3: Decidable equality and finite enumeration #
The finite set of all cut shapes on T. The bothCut / onlyLeftCut /
onlyRightCut constructors are conditionally included based on whether the
relevant children pass IsNotTrace.
Equations
- One or more equations did not get rendered due to their size.
- ConnesKreimer.CutShape.all (ConnesKreimer.TraceTree.leaf a) = {ConnesKreimer.CutShape.atLeaf}
- ConnesKreimer.CutShape.all (ConnesKreimer.TraceTree.trace b) = {ConnesKreimer.CutShape.atTrace}
Instances For
Equations
- ConnesKreimer.CutShape.fintype T = { elems := ConnesKreimer.CutShape.all T, complete := ⋯ }
§4: Pruned forest F_v and remainder T/^c F_v #
For an admissible cut c : CutShape T:
cutForest c : TraceForest α βis the multiset of subtrees being extracted (M-C-B's F_v in Def 1.2.4 / Lemma 1.2.7)remainder c : TraceTree α βis the tree obtained by replacing each cut subtree with a.traceleaf labelled with what was cut (M-C-B's T/^c F_v in Def 1.2.4)
The trace label is a SCALAR β (not a recursive subtree). For β = Unit,
the trace marker carries no information; for β = α, it carries a head
label per @cite{marcolli-skigin-2025} Definition 10.3.
The pruned forest of a cut: the multiset of extracted subtrees. M-C-B Definition 1.2.4: F_v = T_{v_1} ⊔ ⋯ ⊔ T_{v_n}.
Equations
- ConnesKreimer.CutShape.atLeaf.cutForest = 0
- ConnesKreimer.CutShape.atTrace.cutForest = 0
- (ConnesKreimer.CutShape.bothCut hl hr).cutForest = {l, r}
- (ConnesKreimer.CutShape.onlyLeftCut hl cr).cutForest = {l} + cr.cutForest
- (ConnesKreimer.CutShape.onlyRightCut hr cl).cutForest = cl.cutForest + {r}
- (cl.bothRecurse cr).cutForest = cl.cutForest + cr.cutForest
Instances For
The remainder of a cut (contraction-with-trace, M-C-B Def 1.2.4):
T with each cut subtree replaced by a .trace default leaf.
The trace label is default : β from [Inhabited β]. Both
algebraic-side β = Unit (default = (), irrelevant) and
linguistic-side β = Nat (default = 0, sentinel binding index)
have Inhabited automatically. Callers wanting a specific label can
provide it via a custom Inhabited β instance at the call site
(rare; in practice the default suffices).
Note: by the IsNotTrace constraint on the extracting constructors, the
children getting wrapped with .trace here are guaranteed to NOT already
be .trace markers.
Equations
- ConnesKreimer.CutShape.atLeaf.remainder = ConnesKreimer.TraceTree.leaf a
- ConnesKreimer.CutShape.atTrace.remainder = ConnesKreimer.TraceTree.trace b
- (ConnesKreimer.CutShape.bothCut hl hr).remainder = (ConnesKreimer.TraceTree.trace default).node (ConnesKreimer.TraceTree.trace default)
- (ConnesKreimer.CutShape.onlyLeftCut hl cr).remainder = (ConnesKreimer.TraceTree.trace default).node cr.remainder
- (ConnesKreimer.CutShape.onlyRightCut hr cl).remainder = cl.remainder.node (ConnesKreimer.TraceTree.trace default)
- (cl.bothRecurse cr).remainder = cl.remainder.node cr.remainder
Instances For
The remainder of a cut (deletion-with-rebinarization, M-C-B Def 1.2.5): T with each cut subtree REMOVED (no trace), then edge-contracted to recover binarity. Used by Δ^d (the coproduct that linguistic Merge uses, per M-C-B Definition 1.3.4 p. 42: "consider the coproduct Δ = Δ^d of (1.2.8)").
Returns Option (TraceTree α β) because cutting both children of a
node leaves a vertex with no children — neither a leaf nor a binary
node. Such a vertex collapses (returns None); upstream binders absorb
the collapse via edge contraction:
- At a node, if BOTH children's deletion-remainder collapse, the node itself collapses.
- At a node, if ONE child collapses, the other becomes the remainder (the parent's edge to the survivor is "contracted", effectively absorbing the parent into the survivor).
This handling is faithful to M-C-B Def 1.2.5's "unique maximal binary rooted tree obtainable via contraction."
Equations
- One or more equations did not get rendered due to their size.
- ConnesKreimer.CutShape.atLeaf.remainderDeletion = some (ConnesKreimer.TraceTree.leaf a)
- ConnesKreimer.CutShape.atTrace.remainderDeletion = some (ConnesKreimer.TraceTree.trace b)
- (ConnesKreimer.CutShape.bothCut hl hr).remainderDeletion = none
- (ConnesKreimer.CutShape.onlyLeftCut hl cr).remainderDeletion = cr.remainderDeletion
- (ConnesKreimer.CutShape.onlyRightCut hr cl).remainderDeletion = cl.remainderDeletion
Instances For
Every subtree extracted by a cut on T is a proper subtree of T —
its size is strictly less than T.size. Used to prove T ∉ cutForest c,
which in turn drives the term-elimination in algebraic Merge bridge proofs
(Theories/Syntax/Minimalist/Merge/Action.lean).
Pair-cross elimination: for cuts c : CutShape S and c' : CutShape S',
the multiset sum cutForest c + cutForest c' cannot equal {S, S'}.
Used in the algebraic Merge bridge (Theories/Syntax/Minimalist/Merge/Action.lean)
to eliminate cross-terms in the expansion of Δ^d({S, S'}): any cut on one
side combined with any cut on the other side produces a cut-forest different
from {S, S'}, so δ_{S,S'} zeroes that term.
Proof: if the sum were {S, S'}, then S and S' are each in either
cutForest c or cutForest c'. Membership in cutForest c (resp. c')
forces a strict size decrease versus S (resp. S'), so S ∉ cutForest c
and S' ∉ cutForest c'. This forces S ∈ cutForest c' and S' ∈ cutForest c,
yielding S.size < S'.size and S'.size < S.size — contradiction.
Empty-cut characterization: cutForest c = 0 iff c = empty T.
Used in the algebraic Merge bridge's factor-out lemma to identify the unique
LEFT-empty contributor in comulTreeDel T.
§5.5: Cut depth (cost weighting for Minimal Search) #
@cite{marcolli-chomsky-berwick-2025} §1.5
Per @cite{marcolli-chomsky-berwick-2025} Definition in §1.5.2 (p. 59), each
extracted accessible term T_v ⊂ T carries a weight ε^{d_v} where
d_v = dist(v, v_T) is the depth of vertex v from the root of T.
cutTotalDepth c computes the sum Σ d_v over all subtrees extracted by
c. This is the load-bearing quantity for the Minimal Search cost
function: c(M(α, β)) = depth(α) + depth(β) per M-C-B rule 5 (p. 59), and
the cost of a single mergeOp call equals cutTotalDepth of the joint cut
producing (α, β).
The empty cut contributes 0 (no extractions). The non-empty cut on a node adds 1 (depth of immediate children) plus recursive contributions shifted by 1.
Phase 7d (Minimal Search) consumes this for the weighted Merge operator
M^ε and Proposition 1.5.1 (p. 60) — EM/IM are zero-cost; Sideward is
positive-cost.
Note: this captures only the EXTRACTION-side depth (positive contributions
per M-C-B rule 1). Quotient depth (rule 2, with ε^{-d} weights) cancels
the extraction depth in the IM composition; we don't track it separately
here because the cancellation-aware ℕ cost function we'll build computes
the final c(M) directly.
The total depth of a cut: the sum, over all subtrees extracted by c,
of the depth at which each subtree was extracted (= distance from
the root of the source tree to the vertex where the cut occurred).
For a cut on .node l r:
bothCut: extractslandreach at depth 1 → total = 2.onlyLeftCut hl cr: extractslat depth 1, pluscr's extractions from insider(each shifted +1) → 1 + (cutTotalDepth cr + |cutForest cr|).onlyRightCut hr cl: symmetric.bothRecurse cl cr: shifted contributions from both children.
Equations
- ConnesKreimer.CutShape.atLeaf.cutTotalDepth = 0
- ConnesKreimer.CutShape.atTrace.cutTotalDepth = 0
- (ConnesKreimer.CutShape.bothCut hl hr).cutTotalDepth = 2
- (ConnesKreimer.CutShape.onlyLeftCut hl cr).cutTotalDepth = 1 + (cr.cutTotalDepth + Multiset.card cr.cutForest)
- (ConnesKreimer.CutShape.onlyRightCut hr cl).cutTotalDepth = cl.cutTotalDepth + Multiset.card cl.cutForest + 1
- (cl.bothRecurse cr).cutTotalDepth = cl.cutTotalDepth + Multiset.card cl.cutForest + (cr.cutTotalDepth + Multiset.card cr.cutForest)
Instances For
§5.5.1: Sanity checks for cutTotalDepth #
The empty cut has depth 0 (no extractions).
A cut has depth 0 iff its cut-forest is empty (extracts nothing).
Combined with cutForest_eq_zero_iff, this gives cutTotalDepth c = 0 ↔ c = empty T. The cost-weighted Minimal Search formalism uses this
to characterize "no actual extraction" cases.
Converse: cutTotalDepth c = 0 forces c = empty T. The non-empty
cut constructors all contribute strictly positive depth (extracting
at least one subtree at depth ≥ 1).
The full characterization: cutTotalDepth c = 0 ↔ c = empty T.
§6: Sanity checks #
The empty cut's deletion-remainder is some T — the whole tree, unchanged.
Used by the algebraic Merge bridge's factor-out lemma to identify the
empty-cut term in comulTreeDel T as 1 ⊗ forestToHc {T}.
Cut both child edges of a node: extracts both children.
The unique cut on a leaf leaves the leaf unchanged.
The unique cut on a trace leaves the trace unchanged.
§6: Position vs. value: cutForest is NOT injective (and that's correct) #
A natural question: is cutForest : CutShape T → TraceForest α β injective
(per M-C-B Lemma 1.2.7's bijection)? The answer is no in general,
and that's actually consistent with M-C-B.
Counterexample: take T = .node X X (same subtree X on both sides).
Then bothRecurse cl cr and bothRecurse cr cl are syntactically
distinct CutShape T values but produce identical cutForest
multisets (multiset addition is commutative). More generally,
whenever subtrees on the left and right have shared substructure,
swapping cut choices gives the same value-level multiset but distinct
positional cut data.
This is consistent with M-C-B because Eq (1.2.8)'s Σ_{F_v} ranges
over positional subforests of disjoint accessible terms (per
M-C-B's "disjoint in T" qualifier in Lemma 1.2.7), not over value-
deduplicated multisets. Two positionally-distinct cuts that happen to
extract the same value-multiset CONTRIBUTE TWO TERMS to the sum.
Our Σ c : CutShape T correctly enumerates positionally — CutShape T
is the positional cut data. The map cutForest then projects
position to value; non-injectivity here corresponds to
multiplicities in the value-multiset projection of the sum, which is
exactly what M-C-B's sum is supposed to track.
Bottom line: don't try to prove cutForest injective; the sum
over CutShape is the right semantics, and value-level collisions are
genuine multiplicity contributions.
§7: IsNotTrace is preserved by remainder #
For cl : CutShape l, remainder cl has the same top-level constructor as l
(modulo .trace markers introduced for extracted children). In particular,
IsNotTrace l holds iff IsNotTrace (remainder cl) holds — the only .trace-
shaped tree's only CutShape is atTrace, whose remainder is the same .trace.
IsNotTrace is preserved by remainder in both directions.
Forward direction: if l is not a trace marker, neither is its remainder
after any cut.
Backward direction: if remainder cl is not a trace marker, neither is l.
§8: Δ^d leafCount conservation (M-C-B Def 1.6.2 + book p. 64 remark) #
For any admissible cut c on T, the deletion-coproduct's two channels
together account for all of T's leaves:
c.cutForest.degForest + (deletionLeafCount c) = T.leafCount
where deletionLeafCount c is (t.leafCount) if c.remainderDeletion = some t, else 0. This is M-C-B's degree-conservation observation
(book p. 64, paragraph after Def 1.6.2): "the overall deg(F) = #L(F) of
the workspace F ∈ 𝔉_{SO_0} is a conserved quantity throughout all the
forms of Merge described by (1.3.7)."
Load-bearing for the IM positive direction of Prop 1.6.10
(im_satisfiesNCL in Theories/Syntax/Minimalist/Merge/NoComplexityLoss.lean):
the IM workspace
transformation {T} → {.node Q β} preserves total leafCount because
β.leafCount + Q.leafCount = T.leafCount for Q = T/β via this lemma.
Total leafCount of the deletion-remainder, defined structurally on the cut. For each cut constructor, the remainder leaf count is computed directly: extracted leaves count as 1 (atLeaf/atTrace), edge contractions contribute 0 (bothCut), recursive cases pass through (only*Cut), and bothRecurse adds children's contributions.
Equivalent to Option.elim 0 leafCount ∘ remainderDeletion but
structurally tractable for proofs.
Equations
- ConnesKreimer.CutShape.atLeaf.deletionLeafCount = 1
- ConnesKreimer.CutShape.atTrace.deletionLeafCount = 1
- (ConnesKreimer.CutShape.bothCut hl hr).deletionLeafCount = 0
- (ConnesKreimer.CutShape.onlyLeftCut hl cr).deletionLeafCount = cr.deletionLeafCount
- (ConnesKreimer.CutShape.onlyRightCut hr cl).deletionLeafCount = cl.deletionLeafCount
- (cl.bothRecurse cr).deletionLeafCount = cl.deletionLeafCount + cr.deletionLeafCount
Instances For
Δ^d analog of M-C-B's degree-conservation remark, book p. 64: the
deletion-coproduct preserves total leafCount. For any cut c on T:
c.cutForest.degForest + deletionLeafCount c = T.leafCount.
M-C-B (book p. 64, paragraph after Def 1.6.2): "Observe that the overall degree deg(F) = #L(F) of the workspace … is a conserved quantity throughout all the forms of Merge described by (1.3.7), as none of the lexical items originally in the workspace is ever removed."
Note: this is the leafCount (= #L) slice only. M-C-B's Lemma 1.6.3
(book p. 65) and Proposition 1.6.4 (book p. 66) concern α (accessible
terms count) and σ (= b₀ + α), which are different counting functions and
are NOT formalized here. Those would be needed for the Sideward NCL
negative directions (per Remark 1.6.9, leafCount alone cannot distinguish
Sideward 2(b) from IM).
Structural induction on the cut: each constructor's contribution balances out so the total leafCount is conserved.
Master bridge: the structural deletionLeafCount agrees with the
Option.elim 0 leafCount of remainderDeletion. Both encode "leaves
surviving in the deletion-quotient", but deletionLeafCount is
structural (induction-friendly) while remainderDeletion is the actual
Δ^d output (Option-valued).
Corollary: when a cut has a non-trivial Δ^d remainder some t, the
structural deletionLeafCount agrees with t.leafCount. The IM-NCL
theorem in Theories/Syntax/Minimalist/Merge/NoComplexityLoss.lean uses
this to identify Q.leafCount = deletionLeafCount c0 for
c0.remainderDeletion = some Q.
§9: Δ^d size conservation (MCB Lemma 1.6.3 size analog) #
The size analog of cut_leafCount_conservation: for any admissible cut
c on T,
T.size = c.cutForest.sizeForest + deletionSize c + numContractions c
where:
cutForest.sizeForestis the total vertex count of extracted subtrees;deletionSize c = (c.remainderDeletion).elim 0 sizeis the vertex count of the binarized deletion-quotient (0 if it collapses entirely);numContractions ccounts the vertices LOST to edge-contraction during the deletion-quotient construction. A.bothCutalways contracts 1 parent vertex; anonly*Cutalways contracts 1 (its parent has only the trace child after the recursion); a.bothRecurse cl crcontracts 1 iff at least one child's remainder collapses (parent loses ≥ 1 child → contracts), 0 otherwise.
This generalizes the leafCount conservation (which is contraction-free
because contractions only affect non-leaf vertices). The single-edge
case (cutForest = {β_t}, remainderDeletion = some Q) yields
T.size = β_t.size + Q.size + 1 (exactly 1 contraction at the immediate
parent of the cut edge).
Number of vertices lost to edge contraction in the Δ^d quotient. See §9 docstring for the per-constructor recursion.
Equations
- ConnesKreimer.CutShape.atLeaf.numContractions = 0
- ConnesKreimer.CutShape.atTrace.numContractions = 0
- (ConnesKreimer.CutShape.bothCut hl hr).numContractions = 1
- (ConnesKreimer.CutShape.onlyLeftCut hl cr).numContractions = 1 + cr.numContractions
- (ConnesKreimer.CutShape.onlyRightCut hr cl).numContractions = 1 + cl.numContractions
- (cl.bothRecurse cr).numContractions = cl.numContractions + cr.numContractions + match cl.remainderDeletion, cr.remainderDeletion with | some val, some val_1 => 0 | x, x_1 => 1
Instances For
Δ^d size conservation (MCB Lemma 1.6.3 size analog, book p. 65).
For any cut c on T, the source tree's vertex count decomposes
as the sum of extracted-subtree vertices, deletion-remainder
vertices, and contracted vertices. Structural induction; each cut
constructor contributes a known number of contractions per the
numContractions recursion.
Δ^c size conservation #
Δ^c size conservation (MCB Lemma 1.6.3 size analog for the
contraction quotient, book p. 65). For any cut c on a trace-free
T, the source tree's vertex count decomposes cleanly into
extracted-subtree vertices plus the contraction-remainder's
NON-TRACE vertex count:
T.size = c.cutForest.sizeForest + (c.remainder).nonTraceSize
The trace-free hypothesis is encoded as T.nonTraceSize = T.size —
matching MCB's setup where syntactic objects in the workspace are
trace-free; trace markers appear only in quotient trees.
No "contraction count" appears here — Δ^c preserves all parent
vertices (they hold the trace markers). The trace markers in the
remainder don't count toward nonTraceSize, exactly recovering the
extracted subtrees' vertex bookkeeping.
Compare to cut_size_conservation for Δ^d which has an extra
numContractions c term.
Trace-freeness propagates: any subtree extracted by a cut on a
trace-free T is itself trace-free. Used by Δ^c counting to certify
that extracted accessible terms (β_t) have accCountC = accCount.
For a cut on a .node source tree, the contraction-remainder has
nonTraceSize ≥ 1 (the root parent vertex is preserved as a .node,
contributing 1 regardless of which child is replaced by .trace).
A cut with a singleton cutForest forces T to be a .node. (Leaf
and trace roots have only the trivial empty cut, with cutForest = 0.)
Useful for downstream proofs that need to use
nonTraceSize_remainder_pos_of_node on a T introduced as
TraceTree α β rather than .node l r syntactically.
Convenience wrapper: a cut with singleton cutForest has
remainder.nonTraceSize ≥ 1 regardless of how T is syntactically
introduced. Combines isNode_of_cutForest_singleton and
nonTraceSize_remainder_pos_of_node.
MCB Lemma 1.6.3 eq. 1.6.8 (book p. 65): for a single-edge cut on
T extracting accessible term β_t, the contraction-quotient's
accCountC satisfies α(T) = α(T_v) + α^c(T/^c T_v) + 1. The +1
accounts for the root vertex of T (counted in accCount T = T.size − 1
but not in the per-piece sum since the root is the new merged node
when re-merging).
Concretely: T.size − 1 = (β_t.size − 1) + ((T/^c β_t).nonTraceSize − 1) + 1
follows from cut_size_conservation_contraction with cutForest = {β_t}
and the size-pos witnesses.
MCB Lemma 1.6.3 eq. 1.6.10 (book p. 65): σ(T) = σ(T_v) + σ(T/^c T_v)
for a single-edge cut on T extracting β_t. (No +1 in this case — the
root vertex is already counted in σ_v + σ_q via the b₀ contribution.)
Concretely: 1 + (T.size − 1) = (1 + (β_t.size − 1)) + (1 + ((T/^c β_t).nonTraceSize − 1))
follows from cut_size_conservation_contraction.
Single-edge cut produces non-collapsing remainder: if a cut has
a singleton cutForest = {β_t}, then its remainderDeletion is
some _ (cannot be none). Contrapositive: a none remainder requires
a .bothCut at some node, which contributes ≥ 2 elements to cutForest.
Proved by structural recursion on the tree (and case-analysis on the
cut at each level), using eq_empty_of_cutForest_eq_zero to identify
the empty subordinate cuts and remainderDeletion_empty to discharge
them.
The empty cut contracts no vertices.
Vertex-accounting master equation (sharper bookkeeping at the
cardinality layer; companion to cut_size_conservation at the size
layer).
For any cut c : CutShape T,
c.cutForest.card = numContractions c + (1 if rd = none, else 0).
Geometric reading: each cut edge contributes one extracted subtree
to cutForest and one contracted parent vertex to numContractions.
The root of T contributes an extra contraction precisely when
the cut includes a .bothCut at the root (rd = none); when
rd = some, the root survives into the deletion remainder.
Subsumes the legacy single-edge / two-edge contraction-count lemmas
(numContractions_singleEdge, numContractions_twoEdge); both are
restated below as 1-line omega corollaries.
Specialization of cutForest_card_eq_numContractions_add for the
rd = some branch: numContractions c = c.cutForest.card.
Specialization of cutForest_card_eq_numContractions_add for the
rd = none branch: numContractions c + 1 = c.cutForest.card.
A single-edge cut has exactly 1 contracted vertex: the parent of the
cut edge. Corollary of numContractions_eq_card_of_remainderDeletion_some
with cutForest.card = 1 and the singleton-implies-rd-some witness
remainderDeletion_ne_none_of_cutForest_singleton.
Two-edge cut has exactly 2 contracted vertices (MCB Prop 1.6.8
case 3(a), book p. 70: "two edges are contracted, and hence the
counting of (non-root) vertices decreases by 2"). Corollary of
numContractions_eq_card_of_remainderDeletion_some with
cutForest.card = 2.
Single-edge-cut size relation (MCB Lemma 1.6.3 size analog of
eq. 1.6.7 / 1.6.9, book p. 65). For any cut c : CutShape T whose
cutForest is the singleton {β_t} and whose remainderDeletion is
some Q, the source tree T decomposes as
T.size = β_t.size + Q.size + 1.
Geometric reading: a single edge cut splits T into the extracted
accessible term β_t and the binarized deletion-quotient Q, plus
the contracted parent vertex of the cut edge (the +1).
Corollary of cut_size_conservation with numContractions = 1
(single-edge case, by numContractions_singleEdge).
Used by MinimalYield.im_pair_size_deltas_deltaD and
MinimalYield.sideward_2b_size_deltas_deltaD to discharge the
h_size hypothesis from cut data.