1-- The tree-packing theorem of Tutte and Nash-Williams by Kaiser's argument:2-- under the packing condition, a maximal decomposition into k trees and a3-- rest has a connected rest, since an edge of least level in an even set of4-- the rest would admit an improving exchange, and k + 1 disjoint spanning5-- trees follow by induction.6-- Part of Cumulus, the Grace17 mathematics library.7-- Copyright (c) 2026 Grant Passmore.8-- Released under the Apache License 2.0. See LICENSE in the repository root.9-- Authors: Grant Passmore1011module Grace.Cumulus.GraphTheory.TreePacking.Kaiser12import ExchangeOrder1314-- A connected finite edge set holds a spanning tree: a maximal forest15-- inside it joins whatever it joins.16theorem SpanningTree.within (V leftEnd rightEnd F : Set)17requires finiteVertices : Finite(V)18requires nonempty : V ≠∅19requires finite : Finite(F)20requires ends : ∀ e ∈ F, leftEnd(e) ∈ V ∧ rightEnd(e) ∈ V21requires connected : Connects(V, leftEnd, rightEnd, F)22shows∃ G ⊆ F, SpanningTree(V, leftEnd, rightEnd, G)23proof24have finiteFamily := forestsIn.finite at V, leftEnd, rightEnd, F with finite25have emptyForest := forestsIn.contains_empty at V, leftEnd, rightEnd, F26obtain⟨G, inFamily, _, maximal⟩:=27 Finite.maximal_extension with finiteFamily, emptyForest28obtain⟨inPowerset, forest⟩:= inFamily29have subsetF := powerset.membership_iff.forward with inPowerset30have endsG := ends_in.subset with ends, subsetF31have connectedG : Connects(V, leftEnd, rightEnd, G)32intros u hu v hv33exact Forest.maximal_joined with finiteVertices, ends, inFamily, maximal,34 hu, (connected with u, hu, v, hv)35refine⟨G, subsetF, ?_⟩36exact SpanningTree.of_connected_forest with37 finiteVertices, nonempty, endsG, forest, connectedG3839-- The function on succ(k) agreeing with T below k and taking G at k: it40-- adjoins the edges in no tree as a last colour, and later replaces the41-- last colour by a spanning tree inside it.42def replaceLast (E T G : Set, k : Nat) : Set:=43 { p ∈ succ(k) ×𝒫(E) |∃ i ∈ succ(k),44 (i ∈ k ∧ p = (i, T(i))) ∨ (i = k ∧ p = (i, G)) }4546theorem replaceLast.shape (E T G x y : Set, k : Nat)47requires member : (x, y) ∈ replaceLast(E, T, G, k)48shows (x ∈ k ∧ y = T(x)) ∨ (x = k ∧ y = G)49proof50obtain⟨_, i, _, cases⟩:= member51rcasescaseswith⟨below, shape⟩|⟨same, shape⟩52 . obtain⟨xi, yT⟩:= orderedPair.injective with shape53left54rw xi55exact⟨below, yT⟩56 . obtain⟨xi, yG⟩:= orderedPair.injective with shape57right58rw xi59exact⟨same, yG⟩6061theorem replaceLast.function (E T G : Set, k : Nat)62requires classes : ∀ i ∈ k, T(i) ∈𝒫(E)63requires last : G ∈𝒫(E)64shows replaceLast(E, T, G, k) : succ(k) →𝒫(E)65proof66have notSelf := membership.irreflexive at k67constructor68 . intros p member69exact member.left70constructor71 . intros x y relatedY z relatedZ72have shapeY := replaceLast.shape with relatedY73have shapeZ := replaceLast.shape with relatedZ74rcases shapeY with⟨xBelow, yT⟩|⟨xLast, yG⟩75 . rcases shapeZ with⟨_, zT⟩|⟨zLast, _⟩76 . cc77 . exfalso78rw zLast at xBelow79exact notSelf with xBelow80 . rcases shapeZ with⟨zBelow, _⟩|⟨_, zG⟩81 . exfalso82rw xLast at zBelow83exact notSelf with zBelow84 . cc85 . intros x input86havecases:= membership.successor_forward{n := k} with input87rcasescaseswith below | same88 . haveclass:= classes with x, below89refine⟨T(x), class, ?_⟩90unfold relates91refine⟨(product.pair with input, class), x, input, ?_⟩92left93exact⟨below, rfl⟩94 . refine⟨G, last, ?_⟩95unfold relates96refine⟨(product.pair with input, last), x, input, ?_⟩97right98exact⟨same, rfl⟩99100theorem replaceLast.value_below (E T G : Set, k i : Nat)101requires classes : ∀ i ∈ k, T(i) ∈𝒫(E)102requires last : G ∈𝒫(E)103requires index : i ∈ k104shows replaceLast(E, T, G, k)(i) = T(i)105proof106have inSucc : i ∈ succ(k) bysimp [index]107haveclass:= classes with i, index108have related : relates(replaceLast(E, T, G, k), i, T(i))109unfold relates110refine⟨(product.pair with inSucc, class), i, inSucc, ?_⟩111left112exact⟨index, rfl⟩113exact FunctionBetween.apply_value with114 (replaceLast.function with classes, last), inSucc, related115116theorem replaceLast.value_last (E T G : Set, k : Nat)117requires classes : ∀ i ∈ k, T(i) ∈𝒫(E)118requires last : G ∈𝒫(E)119shows replaceLast(E, T, G, k)(k) = G120proof121have kIn : k ∈ succ(k) bysimp122have related : relates(replaceLast(E, T, G, k), k, G)123unfold relates124refine⟨(product.pair with kIn, last), k, kIn, ?_⟩125right126exact⟨rfl, rfl⟩127exact FunctionBetween.apply_value with128 (replaceLast.function with classes, last), kIn, related129130-- The packing condition for succ(k) colours gives it for k.131theorem PackingCondition.below (V E leftEnd rightEnd : Set, k : Nat)132requires finiteVertices : Finite(V)133requires finiteEdges : Finite(E)134requires condition : PackingCondition(V, E, leftEnd, rightEnd, succ(k))135shows PackingCondition(V, E, leftEnd, rightEnd, k)136proof137intros P partition138have packed := condition with P, partition139have finiteClasses := Partition.finite with finiteVertices, partition140have finiteCrossing : Finite(crossingClasses(P, leftEnd, rightEnd, E)) :=141 Finite.subset with finiteEdges,142 (crossingClasses.subset at P, leftEnd, rightEnd, E)143have step := mul.succ_left at k, cardinality(P) - 1144rw step at packed145arith146147-- A packing of k trees extends to a decomposition into succ(k) colours,148-- the edges in no tree forming the last colour.149theorem TreePacking.decomposition (V E leftEnd rightEnd T : Set, k : Nat)150requires function : FunctionBetween(T, k, 𝒫(E))151requires apart : ∀ i ∈ k, ∀ j ∈ k, i ≠ j → Disjoint(T(i), T(j))152requires trees : ∀ i ∈ k, SpanningTree(V, leftEnd, rightEnd, T(i))153shows Decomposition(E, replaceLast(E, T, E ∖ coloursBelow(T, k), k),154 succ(k)) ∧155 (∀ i ∈ k, SpanningTree(V, leftEnd, rightEnd,156 replaceLast(E, T, E ∖ coloursBelow(T, k), k)(i)))157proof158have last : E ∖ coloursBelow(T, k) ∈𝒫(E) :=159 powerset.membership_iff.backward with difference.subset_left160have classes : ∀ i ∈ k, T(i) ∈𝒫(E)161intros i index162exact FunctionBetween.apply_closed with function, index163constructor164 . refine⟨(replaceLast.function with classes, last), ?_, ?_⟩165 . -- Every edge has a colour: its tree, or the last colour.166intros g inE167 by_cases inBelow : g ∈ coloursBelow(T, k)168 . obtain⟨i, index, inT⟩:= coloursBelow.colour with inBelow169have iNat := natural.member at k with i, index170have inSucc : i ∈ succ(k) bysimp [index]171refine⟨i, inSucc, ?_⟩172rw replaceLast.value_below with classes, last, index173exact inT174 . have kIn : k ∈ succ(k) bysimp175refine⟨k, kIn, ?_⟩176rw replaceLast.value_last with classes, last177simp [inE, inBelow]178 . -- The trees are disjoint, and the last colour misses them all.179intros i indexI j indexJ different180have iNat := natural.member at succ(k) with i, indexI181have jNat := natural.member at succ(k) with j, indexJ182have casesI := membership.successor_forward{n := k} with indexI183have casesJ := membership.successor_forward{n := k} with indexJ184rcases casesI with belowI | lastI185 . rw replaceLast.value_below with classes, last, belowI186rcases casesJ with belowJ | lastJ187 . rw replaceLast.value_below with classes, last, belowJ188exact apart with i, belowI, j, belowJ, different189 . rw [lastJ, (replaceLast.value_last with classes, last)]190apply Disjoint.iff.backward191intros g inT inRest192have inBelow := coloursBelow.contains with belowI, inT193exact (difference.membership.forward with inRest).right with inBelow194 . rw [lastI, (replaceLast.value_last with classes, last)]195rcases casesJ with belowJ | lastJ196 . rw replaceLast.value_below with classes, last, belowJ197apply Disjoint.iff.backward198intros g inRest inT199have inBelow := coloursBelow.contains with belowJ, inT200exact (difference.membership.forward with inRest).right with inBelow201 . exfalso202rw [lastI, lastJ] at different203exact different withrfl204 . intros i index205have iNat := natural.member at k with i, index206rw replaceLast.value_below with classes, last, index207exact trees with i, index208209-- The even set closed by e in the colour c refined at the level m of e has210-- an edge other than e of level below m: otherwise every edge of the set211-- would keep its ends within the class X of e at stage m, so the set would212-- join the ends of e inside X by edges of T(c), against the level of e.213theorem fundamental.lower_level (V E leftEnd rightEnd T e C : Set, c k m : Nat)214requires graph : Graph(V, E, leftEnd, rightEnd)215requires finiteVertices : Finite(V)216requires nonempty : V ≠∅217requires decomposition : Decomposition(E, T, succ(k))218requires edge : e ∈ E219requires level : FiniteLevel(V, leftEnd, rightEnd, T, e, succ(k), m)220requires colour : c = leastNatural(disconnectedColour(leftEnd, rightEnd, T,221 partitionSequence(V, leftEnd, rightEnd, T, succ(k), m), succ(k)))222requires closes :223 C ⊆ T(c) ∪ {e} ∧ e ∈ C ∧ EvenEdgeSet(V, leftEnd, rightEnd, C)224shows∃ g ∈ C, g ≠ e ∧225 (∃ n ∈ ℕ, n < m ∧226 FiniteLevel(V, leftEnd, rightEnd, T, g, succ(k), n))227proof228obtain⟨subsetC, eInC, even⟩:= closes229obtain⟨together, parted⟩:= level230obtain⟨X, class, leftIn, rightIn⟩:= together231have partition : Partition(V,232 partitionSequence(V, leftEnd, rightEnd, T, succ(k), m)) :=233 partitionSequence.partition with graph, nonempty, decomposition234obtain⟨some, _⟩:= FiniteLevel.refining_colour with235 graph, nonempty, decomposition, level236obtain⟨colourIn, _⟩:= disconnectedColour.least with some237rw← colour at colourIn238have ends := Decomposition.ends with graph, decomposition, colourIn239have endsC : ∀ g ∈ C, leftEnd(g) ∈ V ∧ rightEnd(g) ∈ V240intros g inC241have inUnion := subsetC with g, inC242simpat inUnion243rcases inUnion with inT | same244 . exact ends with g, inT245 . rw same246exact Graph.ends with graph, e, edge247by_contra none248-- Every edge of C keeps its ends together at stage m, so X is closed.249have togetherAll : ∀ g ∈ C,250∃ Y ∈ partitionSequence(V, leftEnd, rightEnd, T, succ(k), m),251 leftEnd(g) ∈ Y ∧ rightEnd(g) ∈ Y252intros g inC253by_contra apart254have start := partitionSequence.together_zero255at V, leftEnd, rightEnd, T, g, succ(k) with (endsC with g, inC)256obtain⟨n, natural, less, levelG⟩:=257 FiniteLevel.of_parted with start, apart258have notE : g ≠ e259intro same260rwunder same at apart261exact apart with⟨X, class, leftIn, rightIn⟩262exact none with⟨g, inC, notE, n, natural, less, levelG⟩263-- So C ∖ {e} joins the ends of e inside X by edges of T(c), and they264-- share a component of T(c) within X, a class of stage m + 1.265have joinedInside := EvenEdgeSet.joined_inside with finiteVertices,266 partition, class, endsC, even, eInC, ⟨leftIn, rightIn⟩, togetherAll267have restSubset : inside(leftEnd, rightEnd, C ∖ {e}, X) ⊆268 inside(leftEnd, rightEnd, T(c), X)269intros g inInside270obtain⟨inRest, leftG, rightG⟩:= inInside271obtain⟨inC, notE⟩:=272 difference.singleton_membership.forward with inRest273have inUnion := subsetC with g, inC274simp [notE] at inUnion275exact⟨inUnion, leftG, rightG⟩276have joined := Joined.monotone with restSubset, joinedInside277rwunder colour at ends278apply parted279rwunder partitionSequence.succ280rwunder partitionStep.refined with partition, ends, some281rwunder← colour282exact refineBy.together withclass, ⟨leftIn, rightIn⟩, joined283284-- The finite levels of the edges of the last colour lying in its even285-- sets, and the finite levels of the edges other than e of an even set.286def cycleLevels (V leftEnd rightEnd T : Set, k : Nat) : Set:=287 { n ∈ ℕ |∃ g ∈ T(k),288 FiniteLevel(V, leftEnd, rightEnd, T, g, succ(k), n) ∧289 (∃ C, C ⊆ T(k) ∧ g ∈ C ∧ EvenEdgeSet(V, leftEnd, rightEnd, C)) }290291def closedLevels (V leftEnd rightEnd T C e : Set, k : Nat) : Set:=292 { n ∈ ℕ |∃ g ∈ C, g ≠ e ∧293 FiniteLevel(V, leftEnd, rightEnd, T, g, succ(k), n) }294295-- No edge of the last colour in an even set of it has a least finite296-- level under a maximal decomposition: the colour refined at that level297-- closes an even set through it, whose edge f of least level is below, and298-- exchanging the two edges gives a decomposition preceding the maximal one.299theorem Kaiser.no_least_edge (V E leftEnd rightEnd T e : Set, c k m : Nat)300requires graph : Graph(V, E, leftEnd, rightEnd)301requires finiteVertices : Finite(V)302requires finiteEdges : Finite(E)303requires nonempty : V ≠∅304requires decomposition : Decomposition(E, T, succ(k))305requires trees : ∀ i ∈ k, SpanningTree(V, leftEnd, rightEnd, T(i))306requires maximal : ¬(∃ U, Decomposition(E, U, succ(k)) ∧307 (∀ i ∈ k, SpanningTree(V, leftEnd, rightEnd, U(i))) ∧308 Precedes(V, leftEnd, rightEnd, T, U, succ(k)))309requires level : FiniteLevel(V, leftEnd, rightEnd, T, e, succ(k), m)310requires least : ∀ g ∈ T(k), ∀ n ∈ ℕ,311 FiniteLevel(V, leftEnd, rightEnd, T, g, succ(k), n) →312 (∃ C, C ⊆ T(k) ∧ g ∈ C ∧ EvenEdgeSet(V, leftEnd, rightEnd, C)) →313 m ≤ n314requires cycle :315∃ C, C ⊆ T(k) ∧ e ∈ C ∧ EvenEdgeSet(V, leftEnd, rightEnd, C)316requires colour : c = leastNatural(disconnectedColour(leftEnd, rightEnd, T,317 partitionSequence(V, leftEnd, rightEnd, T, succ(k), m), succ(k)))318shows⊥319proof320-- c is a colour below k not holding e, so e closes an even set in T(c).321obtain⟨C₀, subsetC₀, eInC₀, _⟩:= cycle322have first : e ∈ T(k) := subsetC₀ with e, eInC₀323obtain⟨colourC, outside, _⟩:= FiniteLevel.colour_below with324 graph, nonempty, decomposition, level, first, colour325have colourIn : c ∈ succ(k) bysimp [colourC]326have kIn : k ∈ succ(k) bysimp327have endsC := Decomposition.ends with graph, decomposition, colourIn328have endsK := Decomposition.ends with graph, decomposition, kIn329have classK := Decomposition.class_subset with decomposition, kIn330have edge : e ∈ E := classK with e, first331obtain⟨C, subsetC, eInC, even⟩:= SpanningTree.fundamental with332 finiteVertices, ⟨endsC, (endsK with e, first)⟩, (trees with c, colourC),333 outside334-- Its edges other than e have finite levels, one of them below m; f is335-- an edge of least such level.336obtain⟨g, gInC, gNotE, n, nNatural, nLess, gLevel⟩:=337 fundamental.lower_level with graph, finiteVertices, nonempty,338 decomposition, edge, level, colour, ⟨subsetC, eInC, even⟩339have subsetLevels : closedLevels(V, leftEnd, rightEnd, T, C, e, k) ⊆ ℕ340intros p member341exact member.left342have inLevels : n ∈ closedLevels(V, leftEnd, rightEnd, T, C, e, k) :=343⟨nNatural, g, gInC, gNotE, gLevel⟩344have inhabited : Nonempty(closedLevels(V, leftEnd, rightEnd, T, C, e, k)) :=345⟨n, inLevels⟩346obtain⟨pNatural, f, fInC, fNotE, fLevel⟩:=347 leastNatural.member with inhabited, subsetLevels348have pLeast := leastNatural.least with inhabited, subsetLevels, inLevels349have pNat := nat.omega.backward with pNatural350have nNat := nat.omega.backward with nNatural351have closes : ∃ C, C ⊆ T(c) ∪ {e} ∧ e ∈ C ∧ f ∈ C ∧352 f ≠ e ∧ EvenEdgeSet(V, leftEnd, rightEnd, C) ∧353 (∀ g ∈ C, ∀ n ∈ ℕ,354 FiniteLevel(V, leftEnd, rightEnd, T, g, succ(k), n) →355 (∃ p ∈ ℕ,356 FiniteLevel(V, leftEnd, rightEnd, T, f, succ(k), p) ∧ p ≤ n))357refine⟨C, subsetC, eInC, fInC, fNotE, even, ?_⟩358intros h hInC q qNatural hLevel359refine⟨leastNatural(closedLevels(V, leftEnd, rightEnd, T, C, e, k)),360 pNatural, fLevel, ?_⟩361 by_cases same : h = e362 . -- The level of e is m, above the level of g and so of f.363rw same at hLevel364have unique := FiniteLevel.unique with graph, decomposition, level, hLevel365rw← unique366arith367 . exact leastNatural.least with inhabited, subsetLevels,368⟨qNatural, h, hInC, same, hLevel⟩369obtain⟨precedes, treesU⟩:= exchange.precedes with graph, finiteVertices,370 finiteEdges, nonempty, decomposition, trees, level, least, cycle, colour,371 closes372have second : f ∈ T(c)373have inUnion := subsetC with f, fInC374simp [fNotE] at inUnion375exact inUnion376have decompositionU := exchange.decomposition377at V, E, leftEnd, rightEnd, T, e, f, c, k378with decomposition, colourC, first, second379exact maximal with380⟨exchange(E, T, e, f, c, k), decompositionU, treesU, precedes⟩381382-- The last colour of a maximal decomposition connects V: otherwise383-- Kaiser.cycle_edge gives edges of finite level in even sets of the last384-- colour, and one of least level is excluded by Kaiser.no_least_edge.385theorem Kaiser.last_connected (V E leftEnd rightEnd T : Set, k : Nat)386requires graph : Graph(V, E, leftEnd, rightEnd)387requires finiteVertices : Finite(V)388requires finiteEdges : Finite(E)389requires nonempty : V ≠∅390requires decomposition : Decomposition(E, T, succ(k))391requires trees : ∀ i ∈ k, SpanningTree(V, leftEnd, rightEnd, T(i))392requires condition : PackingCondition(V, E, leftEnd, rightEnd, succ(k))393requires maximal : ¬(∃ U, Decomposition(E, U, succ(k)) ∧394 (∀ i ∈ k, SpanningTree(V, leftEnd, rightEnd, U(i))) ∧395 Precedes(V, leftEnd, rightEnd, T, U, succ(k)))396shows Connects(V, leftEnd, rightEnd, T(k))397proof398by_contra disconnected399obtain⟨C₀, subsetC₀, even₀, e₀, inC₀, n₀, natural₀, level₀⟩:=400 Kaiser.cycle_edge with graph, finiteVertices, finiteEdges, nonempty,401 decomposition, trees, condition, disconnected402have subsetLevels : cycleLevels(V, leftEnd, rightEnd, T, k) ⊆ ℕ403intros n member404exact member.left405have inLevels : n₀ ∈ cycleLevels(V, leftEnd, rightEnd, T, k) :=406⟨natural₀, e₀, (subsetC₀ with e₀, inC₀), level₀,407 C₀, subsetC₀, inC₀, even₀⟩408have inhabited : Nonempty(cycleLevels(V, leftEnd, rightEnd, T, k)) :=409⟨n₀, inLevels⟩410obtain⟨mNatural, e, first, level, cycle⟩:=411 leastNatural.member with inhabited, subsetLevels412have mNat := nat.omega.backward with mNatural413have least : ∀ g ∈ T(k), ∀ n ∈ ℕ,414 FiniteLevel(V, leftEnd, rightEnd, T, g, succ(k), n) →415 (∃ C, C ⊆ T(k) ∧ g ∈ C ∧ EvenEdgeSet(V, leftEnd, rightEnd, C)) →416 leastNatural(cycleLevels(V, leftEnd, rightEnd, T, k)) ≤ n417intros g inT n natural levelG cycleG418exact leastNatural.least with inhabited, subsetLevels,419⟨natural, g, inT, levelG, cycleG⟩420obtain⟨c, colour⟩:= exists_eq at leastNatural(disconnectedColour(421 leftEnd, rightEnd, T, partitionSequence(V, leftEnd, rightEnd, T, succ(k),422 leastNatural(cycleLevels(V, leftEnd, rightEnd, T, k))), succ(k)))423have cNat : Nat(c)424rw colour425exact leastNatural.natural with (disconnectedColour.subset at leftEnd,426 rightEnd, T, partitionSequence(V, leftEnd, rightEnd, T, succ(k),427 leastNatural(cycleLevels(V, leftEnd, rightEnd, T, k))), succ(k))428exact Kaiser.no_least_edge with graph, finiteVertices, finiteEdges,429 nonempty, decomposition, trees, maximal, level, least, cycle, colour430431-- Tutte and Nash-Williams: the packing condition suffices. By induction432-- on k: the condition for succ(k) gives k trees, which extend to a433-- decomposition into succ(k) colours; a maximal one has a connected last434-- colour, which holds the last tree.435theorem treePacking (V E leftEnd rightEnd : Set, k : Nat)436requires graph : Graph(V, E, leftEnd, rightEnd)437requires finiteVertices : Finite(V)438requires finiteEdges : Finite(E)439requires nonempty : V ≠∅440requires condition : PackingCondition(V, E, leftEnd, rightEnd, k)441shows TreePacking(V, E, leftEnd, rightEnd, k)442proof443induction k444| zero =>445intro _446witness∅447refine⟨?_, ?_, ?_⟩448 . constructor449 . exact empty.subset450constructor451 . intros x y relatedY z relatedZ452exfalso453exactset.empty with relatedY454 . intros x input455exfalso456rw nat.zero at input457exactset.empty with input458 . intros i index459exfalso460rw nat.zero at index461exactset.empty with index462 . intros i index463exfalso464rw nat.zero at index465exactset.empty with index466| succ(n) using ih =>467intro condition468have below := PackingCondition.below with469 finiteVertices, finiteEdges, condition470obtain⟨T₀, function₀, apart₀, trees₀⟩:= ih with below471obtain⟨decomposition₀, trees₁⟩:=472 TreePacking.decomposition with function₀, apart₀, trees₀473have some : ∃ T, Decomposition(E, T, succ(n)) ∧474 (∀ i ∈ n, SpanningTree(V, leftEnd, rightEnd, T(i))) :=475⟨replaceLast(E, T₀, E ∖ coloursBelow(T₀, n), n),476 decomposition₀, trees₁⟩477obtain⟨T, decomposition, trees, maximal⟩:= Precedes.maximal with478 graph, finiteVertices, finiteEdges, nonempty, some479have connected := Kaiser.last_connected with graph, finiteVertices,480 finiteEdges, nonempty, decomposition, trees, condition, maximal481-- The last tree: a spanning tree inside the connected last colour.482have kIn : n ∈ succ(n) bysimp483have classK := Decomposition.class_subset with decomposition, kIn484have endsK := ends_in.subset with (Graph.ends with graph), classK485have finiteK := Finite.subset with finiteEdges, classK486obtain⟨G, subsetG, tree⟩:= SpanningTree.within with487 finiteVertices, nonempty, finiteK, endsK, connected488have classes : ∀ i ∈ n, T(i) ∈𝒫(E)489intros i index490have inSucc : i ∈ succ(n) bysimp [index]491exact FunctionBetween.apply_closed with decomposition.left, inSucc492have last : G ∈𝒫(E) := powerset.membership_iff.backward with493 (Subset.transitive with subsetG, classK)494witness replaceLast(E, T, G, n)495refine⟨(replaceLast.function with classes, last), ?_, ?_⟩496 . -- The colours stay disjoint, the last tree lying in the last colour.497intros i indexI j indexJ different498have iNat := natural.member at succ(n) with i, indexI499have jNat := natural.member at succ(n) with j, indexJ500have casesI := membership.successor_forward{n := n} with indexI501have casesJ := membership.successor_forward{n := n} with indexJ502rcases casesI with belowI | lastI503 . rw replaceLast.value_below with classes, last, belowI504rcases casesJ with belowJ | lastJ505 . rw replaceLast.value_below with classes, last, belowJ506exact decomposition.right.right with507 i, indexI, j, indexJ, different508 . rw [lastJ, (replaceLast.value_last with classes, last)]509rw lastJ at different510exact Disjoint.of_subset_right with511 (decomposition.right.right with i, indexI, n, kIn, different),512 subsetG513 . rw [lastI, (replaceLast.value_last with classes, last)]514rcases casesJ with belowJ | lastJ515 . rw replaceLast.value_below with classes, last, belowJ516rw lastI at different517exact Disjoint.of_subset_left with518 (decomposition.right.right with n, kIn, j, indexJ, different),519 subsetG520 . exfalso521rw [lastI, lastJ] at different522exact different withrfl523 . intros i index524have iNat := natural.member at succ(n) with i, index525havecases:= membership.successor_forward{n := n} with index526rcasescaseswith below | same527 . rw replaceLast.value_below with classes, last, below528exact trees with i, below529 . rw [same, (replaceLast.value_last with classes, last)]530exact tree531