1-- The alternative for parity systems: a system is solvable exactly when no2-- left-kernel vector sees an odd right-hand side, proved by eliminating one3-- column at a time at a pivot row, which preserves obstructions and lifts4-- solutions.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.Combinatorics.ParityAlternative11import ParitySystems1213-- Section: Elimination.1415-- Elimination of the column c at a pivot row p meeting it: the pivot row is16-- added to every other row meeting c, and then the row p and the column c17-- are deleted. The right-hand side follows the rows.18def pivoted (A R C p c : Set) : Set:=19 ((R ∖ {p}) × (C ∖ {c})) ∩ (A △ (cofiber(A, R, c) × fiber(A, C, p)))2021def pivotRows (A R b p c : Set) : Set:= { r ∈ cofiber(A, R, c) | p ∈ b }2223def pivotedSide (A R b p c : Set) : Set:=24 (R ∖ {p}) ∩ (b △ pivotRows(A, R, b, p, c))2526theorem pivoted.subset (A R C p c : Set)27shows pivoted(A, R, C, p, c) ⊆ R × (C ∖ {c})28proof29intros q hq30unfold pivoted at hq31have parts := intersection.membership.forward with hq32obtain⟨_, r, hr, x, hx, rfl⟩:= product.membership.forward with parts.left33have row : r ∈ R := (difference.singleton_membership.forward with hr).left34exact product.pair with row, hx3536theorem pivotedSide.subset (A R b p c : Set)37shows pivotedSide(A, R, b, p, c) ⊆ R38proof39intros r hr40unfold pivotedSide at hr41have parts := intersection.membership.forward with hr42exact (difference.singleton_membership.forward with parts.left).left4344-- The rows of the pivoted matrix, met by a set t of the remaining columns:45-- a row missing c is unchanged, a row meeting c has the pivot row added.46theorem pivoted.row_unchanged (A R C p c r t : Set)47requires row : r ∈ R48requires other : r ≠ p49requires missing : ¬(r, c) ∈ A50requires inside : t ⊆ C ∖ {c}51shows fiber(pivoted(A, R, C, p, c), C ∖ {c}, r) ∩ t = fiber(A, C, r) ∩ t52proof53ext x54simp [pivoted, fiber.membership, cofiber.membership, intersection.membership,55 difference.singleton_membership, product.pair_membership,56 symmetricDifference.membership]5758theorem pivoted.row_added (A R C p c r t : Set)59requires row : r ∈ R60requires other : r ≠ p61requires meets : (r, c) ∈ A62requires inside : t ⊆ C ∖ {c}63shows fiber(pivoted(A, R, C, p, c), C ∖ {c}, r) ∩ t =64 (fiber(A, C, r) ∩ t) △ (fiber(A, C, p) ∩ t)65proof66ext x67simp [pivoted, fiber.membership, cofiber.membership, intersection.membership,68 difference.singleton_membership, product.pair_membership,69 symmetricDifference.membership]7071-- The columns, met by a set y of rows: a column missing the pivot row is72-- unchanged off p, a column meeting it has the column c added.73theorem pivoted.column_unchanged (A R C p c x y : Set)74requires column : x ∈ C ∖ {c}75requires missing : ¬(p, x) ∈ A76requires rows : y ⊆ R77shows cofiber(pivoted(A, R, C, p, c), R, x) ∩ y =78 cofiber(A, R, x) ∩ (y ∖ {p})79proof80ext r81simp [pivoted, fiber.membership, cofiber.membership, intersection.membership,82 difference.singleton_membership, product.pair_membership,83 symmetricDifference.membership]8485theorem pivoted.column_added (A R C p c x y : Set)86requires column : x ∈ C ∖ {c}87requires meets : (p, x) ∈ A88requires rows : y ⊆ R89shows cofiber(pivoted(A, R, C, p, c), R, x) ∩ y =90 (cofiber(A, R, x) ∩ (y ∖ {p})) △ (cofiber(A, R, c) ∩ (y ∖ {p}))91proof92ext r93simp [pivoted, fiber.membership, cofiber.membership, intersection.membership,94 difference.singleton_membership, product.pair_membership,95 symmetricDifference.membership]9697-- The pivoted right-hand side: a row r ≠ p is set when b and the correction98-- by the pivot row disagree.99theorem pivotedSide.member (A R b p c r : Set)100requires row : r ∈ R101requires other : r ≠ p102shows r ∈ pivotedSide(A, R, b, p, c) ↔¬(r ∈ b ↔ ((r, c) ∈ A ∧ p ∈ b))103proof104simp [pivotedSide, pivotRows, cofiber.membership, intersection.membership,105 difference.singleton_membership, symmetricDifference.membership]106107theorem pivotedSide.rows_unset (A R b p c y : Set)108requires rows : y ⊆ R109requires unset : ¬p ∈ b110shows y ∩ pivotedSide(A, R, b, p, c) = b ∩ (y ∖ {p})111proof112ext r113simp [pivotedSide, pivotRows, cofiber.membership, intersection.membership,114 difference.singleton_membership, symmetricDifference.membership]115116theorem pivotedSide.rows_set (A R b p c y : Set)117requires rows : y ⊆ R118requires pivotSet : p ∈ b119shows y ∩ pivotedSide(A, R, b, p, c) =120 (b ∩ (y ∖ {p})) △ (cofiber(A, R, c) ∩ (y ∖ {p}))121proof122ext r123simp [pivotedSide, pivotRows, cofiber.membership, intersection.membership,124 difference.singleton_membership, symmetricDifference.membership]125126-- A solution t of the pivoted system extends to one of the original: the127-- rows other than p are satisfied by t as they were, and c is added to t128-- exactly when the pivot row asks for it.129theorem pivoted.extend (A R C b p c t : Set)130requires finiteColumns : Finite(C)131requires column : c ∈ C132requires pivotRow : p ∈ R133requires pivot : (p, c) ∈ A134requires solution :135 Solves(pivoted(A, R, C, p, c), R, C ∖ {c}, pivotedSide(A, R, b, p, c), t)136shows∃ s, Solves(A, R, C, b, s)137proof138have inside := solution.left139have finiteT : Finite(t) :=140 Finite.subset with (Finite.difference with finiteColumns), inside141have fresh : ¬c ∈ t142intro hc143have bad := inside with c, hc144simpat bad145have inPivot : c ∈ fiber(A, C, p) :=⟨column, pivot⟩146have extend : ∀ X ⊆ {c},147 (EvenSet(fiber(A, C, p) ∩ t) ↔ (c ∈ X ↔ p ∈ b)) →148 Solves(A, R, C, b, t ∪ X)149intros X part fixed150constructor151 . simp152 . intros r hr153rw EvenSet.intersection_union_part with finiteT, part, fresh154have inRow : c ∈ fiber(A, C, r) ↔ (r, c) ∈ A bysimp [column]155 by_cases same : r = p156 . rw same157tauto158 . have reduced := solution.right with r, hr159rw pivotedSide.member with hr, same at reduced160 by_cases meets : (r, c) ∈ A161 . have finiteRow : Finite(fiber(A, C, r) ∩ t) :=162 Finite.subset with finiteT, intersection.subset_right163have finitePivot : Finite(fiber(A, C, p) ∩ t) :=164 Finite.subset with finiteT, intersection.subset_right165rw [(pivoted.row_added with hr, same, meets, inside),166 (EvenSet.symmetricDifference with finiteRow, finitePivot)]167at reduced168tauto169 . rw pivoted.row_unchanged with hr, same, meets, inside at reduced170tauto171 by_cases fixed : EvenSet(fiber(A, C, p) ∩ t) ↔¬p ∈ b172 . witness t ∪∅173have choice : EvenSet(fiber(A, C, p) ∩ t) ↔ (c ∈∅↔ p ∈ b) bysimp174exact extend with∅, empty.subset, choice175 . witness t ∪ {c}176have choice : EvenSet(fiber(A, C, p) ∩ t) ↔ (c ∈ {c} ↔ p ∈ b) bysimp177exact extend with {c}, Subset.reflexive, choice178179-- An obstruction y of the pivoted system lifts to one of the original: the180-- columns other than c are even over y ∖ {p} as they were, and p is added181-- exactly when the column c is odd there.182theorem pivoted.lift (A R C b p c y : Set)183requires finiteRows : Finite(R)184requires pivotRow : p ∈ R185requires pivot : (p, c) ∈ A186requires obstruction : Obstructs(pivoted(A, R, C, p, c), R, C ∖ {c},187 pivotedSide(A, R, b, p, c), y)188shows∃ z, Obstructs(A, R, C, b, z)189proof190have rows := obstruction.left191have finiteRest : Finite(y ∖ {p}) :=192 Finite.difference with (Finite.subset with finiteRows, rows)193have fresh : ¬p ∈ y ∖ {p} bysimp194have finitePivot : Finite(cofiber(A, R, c) ∩ (y ∖ {p})) :=195 Finite.subset with finiteRest, intersection.subset_right196have inPivot : p ∈ cofiber(A, R, c) :=⟨pivotRow, pivot⟩197have lift : ∀ Y ⊆ {p},198 (EvenSet(cofiber(A, R, c) ∩ (y ∖ {p})) ↔¬p ∈ Y) →199 Obstructs(A, R, C, b, (y ∖ {p}) ∪ Y)200intros Y part pivotColumn201refine⟨?_, ?_, ?_⟩202 . simp203 . intros x hx204rw EvenSet.intersection_union_part with finiteRest, part, fresh205have inColumn : p ∈ cofiber(A, R, x) ↔ (p, x) ∈ A bysimp [pivotRow]206 by_cases same : x = c207 . rw same208tauto209 . have column : x ∈ C ∖ {c} bysimp [hx, same]210have reduced := obstruction.right.left with x, column211 by_cases meets : (p, x) ∈ A212 . have finiteColumn : Finite(cofiber(A, R, x) ∩ (y ∖ {p})) :=213 Finite.subset with finiteRest, intersection.subset_right214rw [(pivoted.column_added with column, meets, rows),215 (EvenSet.symmetricDifference with finiteColumn, finitePivot)]216at reduced217tauto218 . rw pivoted.column_unchanged with column, meets, rows at reduced219tauto220 . have reduced := obstruction.right.right221have finiteSide : Finite(b ∩ (y ∖ {p})) :=222 Finite.subset with finiteRest, intersection.subset_right223rw [intersection.commutative,224 (EvenSet.intersection_union_part with finiteRest, part, fresh)]225 by_cases pivotSet : p ∈ b226 . rw [(pivotedSide.rows_set with rows, pivotSet),227 (EvenSet.symmetricDifference with finiteSide, finitePivot)]228at reduced229tauto230 . rw pivotedSide.rows_unset with rows, pivotSet at reduced231tauto232 by_cases evenColumn : EvenSet(cofiber(A, R, c) ∩ (y ∖ {p}))233 . witness (y ∖ {p}) ∪∅234have choice : EvenSet(cofiber(A, R, c) ∩ (y ∖ {p})) ↔¬p ∈∅bysimp235exact lift with∅, empty.subset, choice236 . witness (y ∖ {p}) ∪ {p}237have choice : EvenSet(cofiber(A, R, c) ∩ (y ∖ {p})) ↔¬p ∈ {p} bysimp238exact lift with {p}, Subset.reflexive, choice239240-- Elimination of a column c: the rows of A meeting c are added to a pivot241-- row, and a solution of the reduced system extends by choosing c. A column242-- no row meets is simply dropped.243theorem paritySystem.eliminate (A R C b c : Set)244requires finiteRows : Finite(R)245requires finiteColumns : Finite(C)246requires matrix : A ⊆ R × C247requires column : c ∈ C248requires unobstructed : ¬(∃ y, Obstructs(A, R, C, b, y))249shows∃ B, ∃ d, B ⊆ R × (C ∖ {c}) ∧ d ⊆ R ∧250¬(∃ y, Obstructs(B, R, C ∖ {c}, d, y)) ∧251 (∀ t, Solves(B, R, C ∖ {c}, d, t) →∃ s, Solves(A, R, C, b, s))252proof253 by_cases pivot : ∃ p ∈ R, (p, c) ∈ A254 . obtain⟨p, pivotRow, meets⟩:= pivot255refine⟨pivoted(A, R, C, p, c), pivotedSide(A, R, b, p, c),256 pivoted.subset, pivotedSide.subset, ?_, ?_⟩257 . intro obstructed258obtain⟨y, obstruction⟩:= obstructed259exact unobstructed260with (pivoted.lift with finiteRows, pivotRow, meets, obstruction)261 . intros t solution262exact pivoted.extend263with finiteColumns, column, pivotRow, meets, solution264 . have noPivot : ∀ r ∈ R, ¬(r, c) ∈ A265intros r hr hrc266exact pivot with⟨r, hr, hrc⟩267refine⟨A, b ∩ R, ?_, intersection.subset_right, ?_, ?_⟩268 . -- The column c of A is empty.269intros q hq270obtain⟨_, r, hr, x, hx, rfl⟩:=271 product.membership.forward with (matrix with q, hq)272have other : x ≠ c273intro same274rw same at hq275exact noPivot with r, hr, hq276exact product.pair with hr, (difference.singleton_membership.backward277with⟨hx, other⟩)278 . -- An obstruction of the reduced system obstructs A, c being even.279intro obstructed280obtain⟨y, obstruction⟩:= obstructed281have rows := obstruction.left282apply unobstructed283witness y284refine⟨rows, ?_, ?_⟩285 . intros x hx286 by_cases same : x = c287 . have none : cofiber(A, R, c) ∩ y =∅byext r; simp [noPivot]288rw [same, none]289exact EvenSet.empty290 . have remaining : x ∈ C ∖ {c} bysimp [hx, same]291exact obstruction.right.left with x, remaining292 . have same : y ∩ (b ∩ R) = y ∩ b byext r; simp293rw← same294exact obstruction.right.right295 . -- A solution of the reduced system solves A.296intros t solution297witness t298have inside := solution.left299constructor300 . intros x hx301exact (inside with x, hx).left302 . intros r hr303have reduced := solution.right with r, hr304have same : fiber(A, C ∖ {c}, r) ∩ t = fiber(A, C, r) ∩ t byext x; simp305rw same at reduced306rw reduced307simp [hr]308309-- Section: The alternative.310311-- Eliminating the columns one at a time: an unobstructed system over no312-- columns has the empty solution, since a row r ∈ b would obstruct by313-- itself.314theorem paritySystem.solvable (R C : Set)315requires finiteRows : Finite(R)316requires finiteColumns : Finite(C)317shows∀ A, ∀ b, A ⊆ R × C →¬(∃ y, Obstructs(A, R, C, b, y)) →318∃ t, Solves(A, R, C, b, t)319proof320induction finiteColumns with G c321| empty =>322intros A b matrix unobstructed323witness∅324constructor325 . simp326 . intros r hr327have none : fiber(A, ∅, r) ∩∅=∅byext x; simp328have absent : ¬r ∈ b329intro hrb330apply unobstructed331witness {r}332refine⟨singleton.subset_iff.backward with hr, ?_, ?_⟩333 . intros x hx334simpat hx335 . rw EvenSet.singleton_intersection336tauto337rw none338simp [EvenSet.empty, absent]339| insert using ih =>340intros A b matrix unobstructed341have column : c ∈ G ∪ {c} bysimp342have finiteStep : Finite(G ∪ {c}) :=343 Finite.union with GFinite, Finite.singleton344obtain⟨B, d, reducedMatrix, _, reducedUnobstructed, extension⟩:=345 paritySystem.eliminate346with finiteRows, finiteStep, matrix, column, unobstructed347have same : (G ∪ {c}) ∖ {c} = G byext x; simp [cFresh]348rw same at reducedMatrix349rwunder same at reducedUnobstructed, extension350obtain⟨t, solution⟩:= ih with B, d, reducedMatrix, reducedUnobstructed351exact extension with t, solution352353theorem paritySystem.alternative (A R C b : Set)354requires finiteRows : Finite(R)355requires finiteColumns : Finite(C)356requires matrix : A ⊆ R × C357requires side : b ⊆ R358shows (∃ t, Solves(A, R, C, b, t)) ↔¬(∃ y, Obstructs(A, R, C, b, y))359proof360constructor361 . intros solvable obstructed362obtain⟨t, solution⟩:= solvable363obtain⟨y, obstruction⟩:= obstructed364exact Solves.not_obstructed365with finiteRows, finiteColumns, matrix, solution, obstruction366 . intro unobstructed367have solvable := paritySystem.solvable with finiteRows, finiteColumns368exact solvable with A, b, matrix, unobstructed369