1-- Parity of a sum of weights at most two: it is the parity of the number2-- of points of weight one3-- Part of Cumulus, the Grace17 mathematics library.4-- Copyright (c) 2026 Grant Passmore.5-- Released under the Apache License 2.0. See LICENSE in the repository root.6-- Authors: Grant Passmore78module Grace.Cumulus.Cardinal.SumParity9import NaturalSum10import Nat.Parity1112def ones (V w : Set) : Set:= { v ∈ V | w(v) =1 }1314theorem ones.subset (V w : Set)15shows ones(V, w) ⊆ V16proof17intros v hv18have parts := ones.membership.forward with hv19exact parts.left2021theorem ones.insert_other (V w a : Set)22requires other : w(a) ≠123shows ones(insert(a, V), w) = ones(V, w)24proof25ext v26constructor27 . intro hv28have parts := ones.membership.forward with hv29havesplit:= insert.membership.forward with parts.left30casessplitwith same | inV31 . exfalso32rw same at parts33exact other with parts.right34 . exact ones.membership.backward with⟨inV, parts.right⟩35 . intro hv36have parts := ones.membership.forward with hv37have inserted : v ∈ insert(a, V)38apply insert.membership.backward39right40exact parts.left41exact ones.membership.backward with⟨inserted, parts.right⟩4243theorem ones.insert_one (V w a : Set)44requires one : w(a) =145shows ones(insert(a, V), w) = insert(a, ones(V, w))46proof47ext v48constructor49 . intro hv50have parts := ones.membership.forward with hv51havesplit:= insert.membership.forward with parts.left52apply insert.membership.backward53casessplitwith same | inV54 . left55exact same56 . right57exact ones.membership.backward with⟨inV, parts.right⟩58 . intro hv59havesplit:= insert.membership.forward with hv60casessplitwith same | inOnes61 . rw same62apply ones.membership.backward63have inserted : a ∈ insert(a, V)64apply insert.membership.backward65left66rfl67exact⟨inserted, one⟩68 . have parts := ones.membership.forward with inOnes69have inserted : v ∈ insert(a, V)70apply insert.membership.backward71right72exact parts.left73exact ones.membership.backward with⟨inserted, parts.right⟩7475theorem Even.two76shows Even(2)77proof78have double := Even.double at179have same : add(1, 1) =2bycompute80 rwa same at double8182theorem Even.add_two_iff (s : Nat)83shows Even(s +2) ↔ Even(s)84proof85constructor86 . intro even87havesplit:= parity.exhaustive at s88casessplitwith evenS | oddS89 . exact evenS90 . exfalso91have odd := Odd.add_even with oddS, Even.two92exact Odd.not_even with odd, even93 . intro even94exact Even.add with even, Even.two9596theorem Even.add_one_iff (s : Nat)97shows Even(s +1) ↔ Odd(s)98proof99rw add.right_one100exact Even.succ_iff101102-- The sum of weights in {0, 1, 2} has the parity of the number of ones.103theorem natSum.parity_of_size (V w : Set, n : Nat)104requires finite : Finite(V)105requires size : cardinality(V) = n106requires weights : ∀ v ∈ V, w(v) =0∨ w(v) =1∨ w(v) =2107shows Even(natSum(V, w)) ↔ Even(cardinality(ones(V, w)))108proof109induction n generalizing V110| zero =>111intros V finite size weights112have has := cardinality.correct with finite113rw size at has114have empty := HasCardinality.empty_of_zero at V with has115have onesEmpty : ones(∅, w) =∅116apply Subset.antisymmetric117 . exact ones.subset at∅, w118 . exact empty.subset at ones(∅, w)119rw [empty, natSum.empty, onesEmpty]120rw← nat.zero121rw cardinality.natural122constructor123 . intro h124exact h125 . intro h126exact h127| succ(k) using ih =>128intros V finite size weights129have has := cardinality.correct with finite130rw size at has131obtain⟨a, ha⟩:= HasCardinality.exists_member with has132have removed := cardinality.remove with finite, ha133rw size at removed134have smaller := Naturals.injective.succ with removed135have restSize : cardinality(V ∖ {a}) = k136 symm137exact smaller138have restFinite := Finite.subset with finite, (difference.subset_left at V, {a})139have restWeights : ∀ v ∈ V ∖ {a}, w(v) =0∨ w(v) =1∨ w(v) =2140intros v hv141have parts := difference.singleton_membership.forward with hv142exact weights with v, parts.left143have rest := ih with V ∖ {a}, restFinite, restSize, restWeights144have naturals : ∀ v ∈ V ∖ {a}, w(v) ∈ ℕ145intros v hv146havesplit:= restWeights with v, hv147casessplitwith zero | more148 . rw zero149typecheck150 . cases more with one | two151 . rw one152typecheck153 . rw two154typecheck155have fresh : ¬a ∈ V ∖ {a}156intro inside157have parts := difference.singleton_membership.forward with inside158apply parts.right159rfl160have restore := insert.restore with ha161have onesFinite := Finite.subset with restFinite, (ones.subset at V ∖ {a}, w)162have onesFresh : ¬a ∈ ones(V ∖ {a}, w)163intro inside164exact fresh with (ones.subset at V ∖ {a}, w with a, inside)165havesplit:= weights with a, ha166have sumNat := natSum.natural with restFinite, naturals167have onesCorrect := cardinality.correct with onesFinite168have onesNat := onesCorrect.left169rw← restore170casessplitwith zero | more171 . have weightA : w(a) ∈ ℕ172rw zero173typecheck174have inserted := natSum.insert with restFinite, naturals, weightA, fresh175have other : w(a) ≠1176rw zero177exact zero.ne_one178have onesSame := ones.insert_other at V ∖ {a}, w, a with other179rw [inserted, onesSame, zero, add.right_unit]180exact rest181 . cases more with one | two182 . have weightA : w(a) ∈ ℕ183rw one184typecheck185have inserted := natSum.insert with restFinite, naturals, weightA, fresh186have onesIns := ones.insert_one at V ∖ {a}, w, a with one187have onesCard := cardinality.insert with onesFinite, onesFresh188rw [inserted, onesIns, one, onesCard]189haveleft:= Even.add_one_iff at natSum(V ∖ {a}, w)190haveright:= Even.succ_iff at cardinality(ones(V ∖ {a}, w))191have oddSum := Odd.iff_not_even at natSum(V ∖ {a}, w)192have oddOnes := Odd.iff_not_even at cardinality(ones(V ∖ {a}, w))193constructor194 . intro h195have oddS :=left.forward with h196have notEvenS := oddSum.forward with oddS197have notEvenC : ¬Even(cardinality(ones(V ∖ {a}, w)))198intro evenC199exact notEvenS with (rest.backward with evenC)200exactright.backward with (oddOnes.backward with notEvenC)201 . intro h202have oddC :=right.forward with h203have notEvenC := oddOnes.forward with oddC204have notEvenS : ¬Even(natSum(V ∖ {a}, w))205intro evenS206exact notEvenC with (rest.forward with evenS)207exactleft.backward with (oddSum.backward with notEvenS)208 . have weightA : w(a) ∈ ℕ209rw two210typecheck211have inserted := natSum.insert with restFinite, naturals, weightA, fresh212have other : w(a) ≠1213rw two214decide215have onesSame := ones.insert_other at V ∖ {a}, w, a with other216rw [inserted, onesSame, two]217have shift := Even.add_two_iff at natSum(V ∖ {a}, w)218constructor219 . intro h220exact rest.forward with (shift.forward with h)221 . intro h222exact shift.backward with (rest.backward with h)223224225-- The same for a finite set, with no size parameter.226theorem natSum.parity (V w : Set)227requires finite : Finite(V)228requires weights : ∀ v ∈ V, w(v) =0∨ w(v) =1∨ w(v) =2229shows Even(natSum(V, w)) ↔ Even(cardinality(ones(V, w)))230proof231have correct := cardinality.correct with finite232have natural := correct.left233have size : cardinality(V) = cardinality(V) byrfl234exact natSum.parity_of_size at V, w, cardinality(V)235with natural, finite, size, weights236237