1-- Even sets and even covers across a split, a vertex set crossed by no edge:2-- an even set of one side is even in the whole graph, covers of the two3-- sides join, and a cover found with the end functions restricted to a side4-- is a cover for the original ends.5-- Part of Cumulus, the Grace17 mathematics library.6-- Copyright (c) 2026 Grant Passmore.7-- Released under the Apache License 2.0. See LICENSE in the repository root.8-- Authors: Grant Passmore910module Grace.Cumulus.GraphTheory.Flows.Splits11import Lifting12import Multigraph.Subgraph1314-- An even set of one side of a split is even in the whole graph: no edge of15-- it has an end outside the side.16theorem EvenEdgeSet.of_side (V X leftEnd rightEnd F : Set)17requires even : EvenEdgeSet(X, leftEnd, rightEnd, F)18requires ends : ∀ e ∈ F, leftEnd(e) ∈ X ∧ rightEnd(e) ∈ X19shows EvenEdgeSet(V, leftEnd, rightEnd, F)20proof21obtain⟨finite, degrees⟩:= even22refine⟨finite, _⟩23intros v hv24 by_cases inX : v ∈ X25 . exact degrees with v, inX26 . -- No edge of F has an end at v.27have none : incidentEnds(leftEnd, rightEnd, F, v) =∅28ext p29constructor30 . intro hp31obtain⟨e, he, i, hi, rfl⟩:= incidentEnds.shape with hp32obtain⟨leftX, rightX⟩:= ends with e, he33have sides := (incidentEnds.pair.forward with hp).right34exfalso35rcases sides with⟨_, atLeft⟩|⟨_, atRight⟩36 . rw atLeft at leftX37exact inX with leftX38 . rw atRight at rightX39exact inX with rightX40 . intro hp41simpat hp42unfold degreeIn43rw [none, cardinality.empty]44exact Even.zero4546-- A vertex set left by no edge splits the graph; covers of the two sides join.47theorem EvenCover.join (V E leftEnd rightEnd X F G : Set)48requires graph : Graph(V, E, leftEnd, rightEnd)49requiressplit : X ⊆ V ∧ crossing(leftEnd, rightEnd, E, X) =∅50requires first : EvenCover(X, inside(leftEnd, rightEnd, E, X), leftEnd,51 rightEnd, F)52requires second : EvenCover(V ∖ X, inside(leftEnd, rightEnd, E, V ∖ X),53 leftEnd, rightEnd, G)54shows∃ H, EvenCover(V, E, leftEnd, rightEnd, H)55proof56obtain⟨subset, none⟩:=split57obtain⟨functionF, evenF, coversF⟩:= first58obtain⟨functionG, evenG, coversG⟩:= second59have endsE := Graph.ends with graph60-- The insides of the two sides are disjoint, and since no edge crosses61-- between the sides, together they hold every edge.62have apart : Disjoint(inside(leftEnd, rightEnd, E, X),63 inside(leftEnd, rightEnd, E, V ∖ X))64rw Disjoint.iff65intros e he inY66have outside := difference.membership.forward with inY.right.left67exact outside.right with he.right.left68have sides : ∀ e ∈ E, e ∈ inside(leftEnd, rightEnd, E, X) ∨69 e ∈ inside(leftEnd, rightEnd, E, V ∖ X)70intros e he71obtain⟨leftV, rightV⟩:= endsE with e, he72have notCross : ¬e ∈ crossing(leftEnd, rightEnd, E, X)73rw none74simp75 by_cases leftX : leftEnd(e) ∈ X76 . left77refine⟨he, leftX, _⟩78by_contra rightX79apply notCross80refine⟨he, _⟩81left82exact⟨leftX, rightX⟩83 . right84have rightX : ¬rightEnd(e) ∈ X85intro rightX86apply notCross87refine⟨he, _⟩88right89exact⟨rightX, leftX⟩90exact⟨he, (difference.membership.backward with leftV, leftX),91 (difference.membership.backward with rightV, rightX)⟩92-- Coordinate by coordinate, the union of the two sides' even sets is an93-- even set of the whole graph.94have union : ∀ i ∈3, F(i) ∪ G(i) ∈𝒫(E) ∧95 EvenEdgeSet(V, leftEnd, rightEnd, F(i) ∪ G(i))96intros i hi97have subF : F(i) ⊆ inside(leftEnd, rightEnd, E, X) :=98 powerset.membership_iff.forward99with (FunctionBetween.apply_closed with functionF, hi)100have subG : G(i) ⊆ inside(leftEnd, rightEnd, E, V ∖ X) :=101 powerset.membership_iff.forward102with (FunctionBetween.apply_closed with functionG, hi)103have evenFi := EvenEdgeSet.of_side at V, X, leftEnd, rightEnd, F(i)104with (evenF with i, hi),105 (ends_in.subset with (inside.ends at leftEnd, rightEnd, E, X), subF)106have evenGi := EvenEdgeSet.of_side at V, V ∖ X, leftEnd, rightEnd, G(i)107with (evenG with i, hi),108 (ends_in.subset with (inside.ends at leftEnd, rightEnd, E, V ∖ X),109 subG)110have apartI : Disjoint(F(i), G(i)) :=111 Disjoint.of_subset_right112with (Disjoint.of_subset_left with apart, subF), subG113refine⟨powerset.membership_iff.backward with (Subset.union2_iff.backward114with⟨(Subset.transitive with subF, inside.subset),115 (Subset.transitive with subG, inside.subset)⟩),116 (EvenEdgeSet.union_disjoint with evenFi, evenGi, apartI)⟩117have zero : 0∈3bysimp [membership.three]118have one : 1∈3bysimp [membership.three]119have two : 2∈3bysimp [membership.three]120obtain⟨mem0, even0⟩:= union with0, zero121obtain⟨mem1, even1⟩:= union with1, one122obtain⟨mem2, even2⟩:= union with2, two123have values := tripleMap.value with mem0, mem1, mem2124have valueAt : ∀ i ∈3,125 tripleMap(𝒫(E), F(0) ∪ G(0), F(1) ∪ G(1), F(2) ∪ G(2))(i) =126 F(i) ∪ G(i)127intros i hi128havecases:= membership.three.forward with hi129rcasescaseswithrfl|rfl|rfl130 . exact values.left131 . exact values.right.left132 . exact values.right.right133witness tripleMap(𝒫(E), F(0) ∪ G(0), F(1) ∪ G(1), F(2) ∪ G(2))134refine⟨(tripleMap.function with mem0, mem1, mem2), _, _⟩135 . intros i hi136have value := valueAt with i, hi137rw value138exact (union with i, hi).right139 . intros e he140havecases:= sides with e, he141rcasescaseswith inX | inY142 . obtain⟨i, hi, inF⟩:= coversF with e, inX143have value := valueAt with i, hi144refine⟨i, hi, _⟩145rw value146simp [inF]147 . obtain⟨i, hi, inG⟩:= coversG with e, inY148have value := valueAt with i, hi149refine⟨i, hi, _⟩150rw value151simp [inG]152153-- An even cover found with the restricted ends is one for the original154-- ends, since a degree reads only the ends of edges of the set.155theorem EvenCover.of_restricted (W V E leftEnd rightEnd D F : Set)156requires graph : Graph(W, E, leftEnd, rightEnd)157requires edges : D ⊆ E158requires cover : EvenCover(V, D, restrict(leftEnd, D), restrict(rightEnd, D),159 F)160shows EvenCover(V, D, leftEnd, rightEnd, F)161proof162obtain⟨function, even, covers⟩:= cover163refine⟨function, _, covers⟩164intros i hi165have subset : F(i) ⊆ D := powerset.membership_iff.forward166with (FunctionBetween.apply_closed with function, hi)167obtain⟨finite, degrees⟩:= even with i, hi168refine⟨finite, _⟩169intros v hv170have same := degreeIn.restricted at W, E, D, F(i), leftEnd, rightEnd, v171with graph, edges, subset172rw← same173exact degrees with v, hv174