1-- The exchange step: an edge e of least finite level in an even set of the2-- last colour is traded for an edge of lower level on the even set it closes3-- in the colour refined at that level, and the first k colours stay trees.4-- Part of Cumulus, the Grace17 mathematics library.5-- Copyright (c) 2026 Grant Passmore.6-- Released under the Apache License 2.0. See LICENSE in the repository root.7-- Authors: Grant Passmore89module Grace.Cumulus.GraphTheory.TreePacking.Exchange10import Order1112-- The exchange: e of least finite level m in an even set of T_k, P its class13-- at level m, c_m the colour refined there, e' an edge of least level on the14-- even set closed by e in T_{c_m}. Exchanging e and e' between the two15-- colours keeps the first k colours trees.16def exchange (E T e f : Set, c k : Nat) : Set:=17 { p ∈ succ(k) ×𝒫(E) |∃ i ∈ succ(k),18 (i = c ∧ p = (i, (T(c) ∪ {e}) ∖ {f})) ∨19 (i = k ∧ p = (i, (T(k) ∪ {f}) ∖ {e})) ∨20 (i ≠ c ∧ i ≠ k ∧ p = (i, T(i))) }2122-- An edge has one colour.23theorem Decomposition.colour_unique (E T g : Set, k i j : Nat)24requires decomposition : Decomposition(E, T, k)25requires indexI : i ∈ k26requires indexJ : j ∈ k27requires inI : g ∈ T(i)28requires inJ : g ∈ T(j)29shows i = j30proof31by_contra different32exact decomposition.right.right with33 i, indexI, j, indexJ, different, g, inI, inJ3435-- The facts the exchange rests on: c and k are distinct colours, e and f36-- are distinct edges of E, and the two swapped classes lie in E.37theorem exchange.setting (E T e f : Set, c k : Nat)38requires decomposition : Decomposition(E, T, succ(k))39requires colour : c ∈ k40requires first : e ∈ T(k)41requires second : f ∈ T(c)42shows c ≠ k ∧ e ≠ f ∧43 (T(c) ∪ {e}) ∖ {f} ∈𝒫(E) ∧ (T(k) ∪ {f}) ∖ {e} ∈𝒫(E)44proof45have less := Less.of_membership at c, k with colour46have distinct : c ≠ k byarith47have cIn : c ∈ succ(k) bysimp [colour]48have kIn : k ∈ succ(k) bysimp49have classC := Decomposition.class_subset with decomposition, cIn50have classK := Decomposition.class_subset with decomposition, kIn51have eInE := classK with e, first52have fInE := classC with f, second53have unionC : T(c) ∪ {e} ⊆ E :=54 Subset.union2_iff.backward with55⟨classC, (singleton.subset_iff.backward with eInE)⟩56have unionK : T(k) ∪ {f} ⊆ E :=57 Subset.union2_iff.backward with58⟨classK, (singleton.subset_iff.backward with fInE)⟩59refine⟨distinct, ?_, ?_, ?_⟩60 . intro same61rw same at first62exact decomposition.right.right with63 c, cIn, k, kIn, distinct, f, second, first64 . exact powerset.membership_iff.backward with65 (Subset.transitive with difference.subset_left, unionC)66 . exact powerset.membership_iff.backward with67 (Subset.transitive with difference.subset_left, unionK)6869-- An entry of the exchange is one of the three kinds of class.70theorem exchange.shape (E T e f x y : Set, c k : Nat)71requires member : (x, y) ∈ exchange(E, T, e, f, c, k)72shows (x = c ∧ y = (T(c) ∪ {e}) ∖ {f}) ∨73 (x = k ∧ y = (T(k) ∪ {f}) ∖ {e}) ∨74 (x ≠ c ∧ x ≠ k ∧ y = T(x))75proof76obtain⟨_, i, _, cases⟩:= member77rcasescaseswith78⟨same, shape⟩|⟨same, shape⟩|⟨notC, notK, shape⟩79 . obtain⟨xi, yA⟩:= orderedPair.injective with shape80left81rw xi82exact⟨same, yA⟩83 . obtain⟨xi, yB⟩:= orderedPair.injective with shape84right85left86rw xi87exact⟨same, yB⟩88 . obtain⟨xi, yC⟩:= orderedPair.injective with shape89right90right91rw xi92exact⟨notC, notK, yC⟩9394theorem exchange.function (E T e f : Set, c k : Nat)95requires decomposition : Decomposition(E, T, succ(k))96requires colour : c ∈ k97requires first : e ∈ T(k)98requires second : f ∈ T(c)99shows exchange(E, T, e, f, c, k) : succ(k) →𝒫(E)100proof101obtain⟨distinct, _, swappedC, swappedK⟩:=102 exchange.setting with decomposition, colour, first, second103constructor104 . intros p member105exact member.left106constructor107 . intros x y relatedY z relatedZ108have shapeY := exchange.shape with relatedY109have shapeZ := exchange.shape with relatedZ110-- In each of the nine cases the two values agree or the indices clash.111rcases shapeY with⟨xc, yA⟩|⟨xk, yB⟩|⟨xnc, xnk, yC⟩112 . rcases shapeZ with⟨zc, zA⟩|⟨zk, zB⟩|⟨znc, znk, zC⟩; . cc; . cc; . cc113 . rcases shapeZ with⟨zc, zA⟩|⟨zk, zB⟩|⟨znc, znk, zC⟩; . cc; . cc; . cc114 . rcases shapeZ with⟨zc, zA⟩|⟨zk, zB⟩|⟨znc, znk, zC⟩; . cc; . cc; . cc115 . intros x input116 by_cases xc : x = c117 . refine⟨(T(c) ∪ {e}) ∖ {f}, swappedC, ?_⟩118unfold relates119refine⟨(product.pair with input, swappedC), x, input, ?_⟩120left121exact⟨xc, rfl⟩122 by_cases xk : x = k123 . refine⟨(T(k) ∪ {f}) ∖ {e}, swappedK, ?_⟩124unfold relates125refine⟨(product.pair with input, swappedK), x, input, ?_⟩126right127left128exact⟨xk, rfl⟩129haveclass:= FunctionBetween.apply_closed with decomposition.left, input130refine⟨T(x), class, ?_⟩131unfold relates132refine⟨(product.pair with input, class), x, input, ?_⟩133right134right135exact⟨xc, xk, rfl⟩136137theorem exchange.value_colour (E T e f : Set, c k : Nat)138requires decomposition : Decomposition(E, T, succ(k))139requires colour : c ∈ k140requires first : e ∈ T(k)141requires second : f ∈ T(c)142shows exchange(E, T, e, f, c, k)(c) = (T(c) ∪ {e}) ∖ {f}143proof144obtain⟨_, _, swappedC, _⟩:=145 exchange.setting with decomposition, colour, first, second146have cIn : c ∈ succ(k) bysimp [colour]147have function := exchange.function with decomposition, colour, first, second148have related : relates(exchange(E, T, e, f, c, k), c, (T(c) ∪ {e}) ∖ {f})149unfold relates150refine⟨(product.pair with cIn, swappedC), c, cIn, ?_⟩151left152exact⟨rfl, rfl⟩153exact FunctionBetween.apply_value with function, cIn, related154155theorem exchange.value_last (E T e f : Set, c k : Nat)156requires decomposition : Decomposition(E, T, succ(k))157requires colour : c ∈ k158requires first : e ∈ T(k)159requires second : f ∈ T(c)160shows exchange(E, T, e, f, c, k)(k) = (T(k) ∪ {f}) ∖ {e}161proof162obtain⟨_, _, _, swappedK⟩:=163 exchange.setting with decomposition, colour, first, second164have kIn : k ∈ succ(k) bysimp165have function := exchange.function with decomposition, colour, first, second166have related : relates(exchange(E, T, e, f, c, k), k, (T(k) ∪ {f}) ∖ {e})167unfold relates168refine⟨(product.pair with kIn, swappedK), k, kIn, ?_⟩169right170left171exact⟨rfl, rfl⟩172exact FunctionBetween.apply_value with function, kIn, related173174theorem exchange.value_other (E T e f : Set, c k i : Nat)175requires decomposition : Decomposition(E, T, succ(k))176requires colour : c ∈ k177requires first : e ∈ T(k)178requires second : f ∈ T(c)179requires index : i ∈ succ(k)180requires notC : i ≠ c181requires notK : i ≠ k182shows exchange(E, T, e, f, c, k)(i) = T(i)183proof184have function := exchange.function with decomposition, colour, first, second185haveclass:= FunctionBetween.apply_closed with decomposition.left, index186have related : relates(exchange(E, T, e, f, c, k), i, T(i))187unfold relates188refine⟨(product.pair with index, class), i, index, ?_⟩189right190right191exact⟨notC, notK, rfl⟩192exact FunctionBetween.apply_value with function, index, related193194-- An edge lies in the exchanged class of a colour when it is e and the195-- colour is c, f and the colour is k, or neither edge and of that colour.196theorem exchange.class_membership (E T e f g : Set, c k i : Nat)197requires decomposition : Decomposition(E, T, succ(k))198requires colour : c ∈ k199requires first : e ∈ T(k)200requires second : f ∈ T(c)201requires index : i ∈ succ(k)202shows g ∈ exchange(E, T, e, f, c, k)(i) ↔203 (g = e ∧ i = c) ∨ (g = f ∧ i = k) ∨204 (g ≠ e ∧ g ≠ f ∧ g ∈ T(i))205proof206obtain⟨distinct, edges, _, _⟩:=207 exchange.setting with decomposition, colour, first, second208have cIn : c ∈ succ(k) bysimp [colour]209have kIn : k ∈ succ(k) bysimp210have eNotC : ¬e ∈ T(c)211intro inC212exact distinct with213 (Decomposition.colour_unique with decomposition, cIn, kIn, inC, first)214have fNotK : ¬f ∈ T(k)215intro inK216exact distinct with217 (Decomposition.colour_unique with decomposition, cIn, kIn, second, inK)218 by_cases ic : i = c219 . rw [ic, (exchange.value_colour with decomposition, colour, first, second)]220constructor221 . intro member222simp [union2.membership, singleton.membership] at member223rcases member with⟨inC | same, notF⟩224 . right225right226refine⟨?_, notF, inC⟩227intro same228rw same at inC229exact eNotC with inC230 . left231exact⟨same, rfl⟩232 . introcases233rcasescaseswith⟨same, _⟩|⟨_, ck⟩|⟨_, notF, inC⟩234 . rw same235simp [edges]236 . exfalso237exact distinct with ck238 . simp [inC, notF]239 by_cases ik : i = k240 . rw [ik, (exchange.value_last with decomposition, colour, first, second)]241constructor242 . intro member243simp [union2.membership, singleton.membership] at member244rcases member with⟨inK | same, notE⟩245 . right246right247refine⟨notE, ?_, inK⟩248intro same249rw same at inK250exact fNotK with inK251 . right252left253exact⟨same, rfl⟩254 . introcases255rcasescaseswith⟨_, kc⟩|⟨same, _⟩|⟨notE, _, inK⟩256 . exfalso257cc258 . rw same259have different : f ≠ e bycc260simp [different]261 . simp [inK, notE]262rw (exchange.value_other with263 decomposition, colour, first, second, index, ic, ik)264constructor265 . intro inT266right267right268refine⟨?_, ?_, inT⟩269 . intro same270rw same at inT271exact ik with (Decomposition.colour_unique with272 decomposition, index, kIn, inT, first)273 . intro same274rw same at inT275exact ic with (Decomposition.colour_unique with276 decomposition, index, cIn, inT, second)277 . introcases278rcasescaseswith⟨_, same⟩|⟨_, same⟩|⟨_, _, inT⟩279 . exfalso280exact ic with same281 . exfalso282exact ik with same283 . exact inT284285theorem exchange.decomposition (V E leftEnd rightEnd T e f : Set, c k : Nat)286requires decomposition : Decomposition(E, T, succ(k))287requires colour : c ∈ k288requires first : e ∈ T(k)289requires second : f ∈ T(c)290shows Decomposition(E, exchange(E, T, e, f, c, k), succ(k))291proof292obtain⟨_, edges, _, _⟩:=293 exchange.setting with decomposition, colour, first, second294have cIn : c ∈ succ(k) bysimp [colour]295have kIn : k ∈ succ(k) bysimp296refine⟨(exchange.function with decomposition, colour, first, second),297 ?_, ?_⟩298-- Every edge keeps a colour: e moves to c, f to k, the rest stay.299 . intros g inE300 by_cases ge : g = e301 . refine⟨c, cIn, ?_⟩302rw exchange.class_membership with303 decomposition, colour, first, second, cIn304left305exact⟨ge, rfl⟩306 by_cases gf : g = f307 . refine⟨k, kIn, ?_⟩308rw exchange.class_membership with309 decomposition, colour, first, second, kIn310right311left312exact⟨gf, rfl⟩313obtain⟨i, index, inT⟩:= decomposition.right.left with g, inE314have natural := natural.member at succ(k) with i, index315refine⟨i, index, ?_⟩316rw exchange.class_membership with317 decomposition, colour, first, second, index318right319right320exact⟨ge, gf, inT⟩321-- And only one colour, as under T.322 . intros i indexI j indexJ different323have naturalI := natural.member at succ(k) with i, indexI324have naturalJ := natural.member at succ(k) with j, indexJ325apply Disjoint.iff.backward326intros g inI inJ327rw exchange.class_membership with328 decomposition, colour, first, second, indexI at inI329rw exchange.class_membership with330 decomposition, colour, first, second, indexJ at inJ331rcases inI with⟨ge, ic⟩|⟨gf, ik⟩|⟨notE, notF, inTi⟩332 . rcases inJ with⟨_, jc⟩|⟨gf, _⟩|⟨notE, _, _⟩333 . cc334 . cc335 . exact notE with ge336 . rcases inJ with⟨ge, _⟩|⟨_, jk⟩|⟨_, notF, _⟩337 . cc338 . cc339 . exact notF with gf340 . rcases inJ with⟨ge, _⟩|⟨gf, _⟩|⟨_, _, inTj⟩341 . exact notE with ge342 . exact notF with gf343 . exact different with344 (Decomposition.colour_unique with345 decomposition, indexI, indexJ, inTi, inTj)346