Host-append decomposition for planar multi-tree insertion #
The planar substrate for Nonplanar.insertionMultiset_add_host:
multi-graft into a concatenated host list host_A ++ host_B
decomposes as a sum over boolean assignments of guests to either
host_A or host_B, with each side recursively multi-grafted
independently.
Architecture #
The proof introduces hostBucketSum, a Multiset aggregator analogous
to forestPairSum but splitting guests by a 2-bucket partition between
two arbitrary host forests (rather than between a head tree and its
tail). The bridge hostBucketSum_eq_insertionForest is proved by
induction on host_A.
This is the planar-level companion to the Nonplanar.insertionMultiset_add_host
combinatorial identity used in GrossmanLarsonAssoc.lean's
Oudom-Guin Prop 2.7.iii proof.
Status #
[UPSTREAM] candidate. Sorry-free.
§1: hostBucketSum aggregator #
Splits a list of guest trees into two buckets — those destined for
host_A and those destined for host_B — by accumulating boolean
choices for each remaining guest. At the leaf, the cartesian product of
each side's insertionForest is concatenated.
Two-host aggregator: at the leaf (no remaining guests), produce
the cartesian product of insertionForest host_A pre_A and
insertionForest host_B pre_B, joined by list concatenation.
At a cons, bind over [true, false] and extend either bucket.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Assignment rewrite: hostBucketSum accumulating into pre_A/pre_B
over remaining guests Ts equals the sum over [true, false]-
assignments of Ts of hostBucketSum on empty remaining with the
accumulators augmented by the partition. Mirrors
forestPairSum_assignment_rewrite in Insertion.lean.
hostBucketSum as a kBucketSum instance: 2 buckets indexed by Bool,
parallel cartesian-product leaf.
§2: Base case — hostBucketSum [] host_B [] [] guests = insertionForest host_B guests #
When host_A = [], only the "all-false" boolean assignment can
produce a non-zero insertionForest [] _ ≠ 0, since
insertionForest [] _ = 0 whenever the second argument is non-empty.
The all-false path gives ({[]} ×ˢ insertionForest host_B guests).map (++),
which collapses to insertionForest host_B guests.
§3: 3-bucket aggregator and the full bridge #
The headline planar identity. Combined with the Nonplanar lift below
(via Quotient.out + host-Perm invariance lifted through Nonplanar.mk),
this yields the substrate for Nonplanar.insertionMultiset_add_host.
The proof goes by induction on host_A. The base case (host_A = [])
is hostBucketSum_nil_A (above). The inductive case host_A = T :: F_A
proceeds via a 3-bucket aggregator hostTripleSum that explicitly
partitions guests into three buckets {T-bucket, F_A-bucket, host_B-bucket}.
We then prove:
hostBucketSum_eq_hostTripleSum: LHS (the 2-stephostBucketSum) equals the 3-bucket sum (reorganizing "A-vs-B then T-vs-F_A within A").insertionForest_cons_append_eq_hostTripleSum: RHS (theinsertionForestoverT :: (F_A ++ host_B)) equals the 3-bucket sum (using the outer IH onF_Ato convertinsertionForest (F_A ++ host_B) YintohostBucketSum F_A host_B, reorganizing "T-vs-rest then F_A-vs-host_B within rest").
Equations
- RootedTree.Planar.Pathed.instDecidableEqTripleIdx x✝ y✝ = if h : RootedTree.Planar.Pathed.TripleIdx.ctorIdx✝ x✝ = RootedTree.Planar.Pathed.TripleIdx.ctorIdx✝ y✝ then isTrue ⋯ else isFalse ⋯
Uniform decomposition of insertionForest (T :: F) X over [true, false]-assignments
of X's elements to the T-bucket or F-bucket. Works for empty X via singleton bind.
Lemma X (listChoices append-decomposition): enumerating length-(n+1)
bit vectors and applying g equals enumerating length-n bit vectors and
summing g (α ++ [true]) + g (α ++ [false]). Multiset-level, NOT list-level.
Length-additive splitting: a bind over length-(m+n) bit vectors equals a
nested bind: outer over length-m, inner over length-n, with the leaf
function applied to the concatenation.
Companion to listChoices_succ_append_bind (which splits off a single bit
from the end). Original consumer was the A3.3 basis-level proof in
InsertionAssoc.lean (deleted 2026-05-16); kept as a general utility.
Proof: induction on n. Base n = 0 reduces via List.append_nil; step
n + 1 peels off one bit via listChoices_succ_append_bind on both sides
and rebinds via List.append_assoc.
Polymorphic length-additive splitting: a bind over length-(m+n)
enumerations equals a nested bind, outer over length-m and inner over
length-n, with the leaf function applied to the concatenation.
Generalizes listChoices_append_bind (the Bool case) to arbitrary
xs : List β. The proof inducts on m, peeling one element off the
front via listChoices_succ (rather than the back, as in the Bool
version which uses listChoices_succ_append_bind).
Used by RHS_eq_canonical_msform to split a length-(pre_T_B.length + T_orig-count) choice into a pre_T_B.length prefix (choice_T) and
a T_orig-count suffix (choice_T_orig).
.map-variant of listChoices_split_bind. When the consumer is .map g
instead of .bind g, the same length-additive splitting holds, with the
inner .bind becoming a .map. Derived from listChoices_split_bind by
rewriting the outer .map as .bind over a singleton multiset and
converting back.
Length lemma: every element of listChoices xs n has length exactly n.
Used in the cons case of hostBucketSum_eq_hostTripleSum_aux to invoke
List.zip_append.
§4: Connecting hostTripleSum with insertion T ∘ hostBucketSum F_A host_B #
Lemma A reduces hostBucketSum (T :: F_A) host_B [] [] guests to
hostTripleSum T F_A host_B [] [] [] guests. To complete the bridge, we
need hostTripleSum T F_A host_B [] [] [] guests = insertionForest (T :: (F_A ++ host_B)) guests.
Approach: generalize to hostTripleSum_T_split:
hostTripleSum T F_A host_B pre_T pre_FA pre_B remaining =
bind α over remaining.length:
(insertion T (pre_T ++ filter_true remaining α)).bind T' =>
(hostBucketSum F_A host_B pre_FA pre_B (filter_false remaining α)).map (T' :: ·)
Then for pre_T = pre_FA = pre_B = [], combine with the IH hostBucketSum F_A host_B = insertionForest (F_A ++ host_B) to close the bridge.
Requires listChoices_succ_cons_bind (the cons-prepending analog of
listChoices_succ_append_bind).
Cons-prepending analog of listChoices_succ_append_bind. The bit
for the cons-front guest goes at the FRONT of α rather than the back.
§5: Host-Perm invariance at the multiset-of-multiset level #
insertionForest is invariant under permutation of host trees, but only at
the level where output lists are wrapped via Multiset.ofList ∘ List.map mk
(i.e., the level used by Nonplanar.insertionMultiset). The list structure
of inner outputs (which is host-position-correlated) is discarded by this
outer wrapper, allowing host trees to be permuted without changing the
multiset-of-multiset image.
The key combinatorial lemma is the swap symmetry of two adjacent host trees,
which we prove via hostTripleSum's 3-bucket structure: when the F_A bucket
is a singleton [T₂], swapping the T-bucket with the F_A-bucket gives a
configuration symmetric in (T₁, T₂) at the multiset level.
Host-Perm invariance at the multiset-of-multiset level: when host
trees are permuted, the (insertionForest host gs).map (Multiset.ofList ∘ List.map mk)
is unchanged.
This is the key invariance used by Nonplanar.insertionMultiset_add_host
(and similar Nonplanar-side lifts) to bridge (A + B).toList.map Q.out
with A.toList.map Q.out ++ B.toList.map Q.out.
§6: Bit-vector ↔ powerset bridge #
For a list l : List β, bit-vectors of length |l| enumerate sublists
of l (the elements where the bit is true). At the multiset level, the
collection of (filter_t, filter_f) pairs over all bit-vectors equals
the collection of (s, ↑l - s) over s ∈ (↑l).powerset. Used by
Nonplanar.insertionMultiset_add_host to bridge the
hostBucketSum_assignment_rewrite form (bind over bit-vectors) with
the C.powerset.bind form on the RHS.
The complementary filter_t / filter_f operations on a bit-vector
over a list l partition l (as multisets) when their lengths match:
↑(filter_t l assn) + ↑(filter_f l assn) = ↑l.
Corollary: ↑(filter_f l assn) = ↑l - ↑(filter_t l assn), given matching length.
Length lemma: every element of listChoices [b₁, b₂] n has length exactly n.
A re-export of the existing mem_listChoices_length for [true, false].
Bit-vector ↔ powerset bridge (paired form, first-component map only):
enumerating bit-vectors and mapping to ↑(filter_t) gives the powerset
of ↑l. (No second component yet — see paired version below.)
Bit-vector ↔ powerset bridge (paired form): enumerating bit-vectors
and pairing (filter_t, filter_f) gives the powerset paired with
complement (s, ↑l - s). Derived from the single-component version +
filterMap_f_eq_sub.
§7: Guest-multiset invariance at the msform level #
(insertionForest host gs).map msform depends only on the multiset image
of gs.map mk, not on the planar representatives or order. This combines
guest-Perm invariance + guest-PlanarEquiv invariance into a single lemma
matching the level used by Nonplanar.insertionMultiset.
Forest version of guest-PlanarEquiv invariance: Forall₂ PlanarEquiv
on guests preserves (insertionForest F Ts).map (List.map mk).
Mirrors insertionForest_planarEquiv_host (Insertion.lean §6) but for
the guest list.
Combined guest invariance at the multiset-of-multiset level.