1-- Absolute values of the existing quotient integers2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Int.AbsoluteValue8import Arithmetic910theorem integerClass.positive_difference (a b d : Nat)11requires difference : b + d = a12shows integerClass(a, b) = integerOfNat(d)13proof14unfold integerOfNat15apply integerClass.eq with*{4}16ring1718theorem integerClass.negative_difference (a b d : Nat)19requires difference : a + d = b20shows integerClass(a, b) = integerNegativeOfNat(d)21proof22unfold integerNegativeOfNat23apply integerClass.eq with*{4}24ring2526theorem Integer.signed_natural (z : Integer)27shows∃ n, Nat(n) ∧ (z = integerOfNat(n) ∨ z = integerNegativeOfNat(n))28proof29obtain⟨a, aNat, b, bNat, shape⟩:= Integer.representatives at z with*30rwunder shape31have total := LessEqual.total at a, b with*32cases total with negative | positive33 . obtain⟨d, dNat, difference⟩:= negative34have value := integerClass.negative_difference with*35witness d36right37exact value38 . obtain⟨e, eNat, equation⟩:= positive39have value := integerClass.positive_difference with*40witness e41left42exact value4344theorem integerOfNat.neg (n : Nat)45shows -(integerOfNat(n)) = integerNegativeOfNat(n)46proof47simp [integerOfNat, integerNegativeOfNat, integerNegValue.classes, integerClassNeg]4849theorem integerNegativeOfNat.neg (n : Nat)50shows -(integerNegativeOfNat(n)) = integerOfNat(n)51proof52simp [integerOfNat, integerNegativeOfNat, integerNegValue.classes, integerClassNeg]5354theorem integerNegativeOfNat.injective (m n : Nat)55requires same : integerNegativeOfNat(m) = integerNegativeOfNat(n)56shows m = n57proof58simp [integerNegativeOfNat] at same59have sums := integerClass.equivalent_of_eq with*60simp [add] at sums61 symm62exact sums6364theorem integerOfNat.eq_negative (m n : Nat)65requires same : integerOfNat(m) = integerNegativeOfNat(n)66shows m =0∧ n =067proof68simp [integerOfNat, integerNegativeOfNat] at same69have sums := integerClass.equivalent_of_eq with*70simp [add] at sums71exact add.eq_zero with*, sums7273theorem integerMagnitude.unique_of_sign (z : Integer, m n : Nat)74requires first : z = integerOfNat(m) ∨ z = integerNegativeOfNat(m)75requires second : z = integerOfNat(n) ∨ z = integerNegativeOfNat(n)76shows m = n77proof78cases first with positiveM | negativeM79 . cases second with positiveN | negativeN80 . have same : integerOfNat(m) = integerOfNat(n)81 . cc82exact integerOfNat.injective with*83 . have same : integerOfNat(m) = integerNegativeOfNat(n)84 . cc85have zeros := integerOfNat.eq_negative with*86cc87 . cases second with positiveN | negativeN88 . have same : integerOfNat(n) = integerNegativeOfNat(m)89 . cc90have zeros := integerOfNat.eq_negative with*91cc92 . have same : integerNegativeOfNat(m) = integerNegativeOfNat(n)93 . cc94exact integerNegativeOfNat.injective with*9596-- Extract the unique natural magnitude in ZF, without Choice.97defunique integerMagnitude (z : Set) (n ∈ ℕ) :=98 z = integerOfNat(n) ∨ z = integerNegativeOfNat(n)99requires integer : Integer(z)100proof101obtain⟨n, nNat, sign⟩:= Integer.signed_natural at z with*102have member := nat.omega.forward with nNat103refine⟨n, member, sign⟩104105uniqueness106intros m mMember first n nMember second107have mNat := nat.omega.backward with mMember108have nNat := nat.omega.backward with nMember109exact integerMagnitude.unique_of_sign with*110111def integerNatAbs (z : Integer) : Nat:= integerMagnitude(z)112def integerAbs (z : Integer) : Integer := integerOfNat(integerNatAbs(z))113114theorem integerNatAbs.natural (z : Integer)115showsNat(integerNatAbs(z))116proof117have selected := integerMagnitude.selected at z with*118rcases selected with⟨member, sign⟩119unfold integerNatAbs120exact nat.omega.backward with member121122theorem integerNatAbs.cases (z : Integer)123shows z = integerOfNat(integerNatAbs(z)) ∨ z = integerNegativeOfNat(integerNatAbs(z))124proof125have selected := integerMagnitude.selected at z with*126rcases selected with⟨member, sign⟩127 simpa [integerNatAbs] using sign128129theorem integerNatAbs.eq_of_sign (z : Integer, n : Nat)130requires sign : z = integerOfNat(n) ∨ z = integerNegativeOfNat(n)131shows integerNatAbs(z) = n132proof133have selected := integerNatAbs.cases with*134exact integerMagnitude.unique_of_sign with*135136theorem integerNatAbs.ofNat (n : Nat)137shows integerNatAbs(integerOfNat(n)) = n138proof139apply integerNatAbs.eq_of_sign with*{2}140left141rfl142143theorem integerNatAbs.ofNegativeNat (n : Nat)144shows integerNatAbs(integerNegativeOfNat(n)) = n145proof146apply integerNatAbs.eq_of_sign with*{2}147right148rfl149150theorem integerNatAbs.neg (z : Integer)151shows integerNatAbs(-z) = integerNatAbs(z)152proof153have sign := integerNatAbs.cases with*154apply integerNatAbs.eq_of_sign with*{2}155cases sign with positive | negative156 . right157have negated := integerOfNat.neg at integerNatAbs(z) with*158 rwa ← positive at negated159 . left160have negated := integerNegativeOfNat.neg at integerNatAbs(z) with*161 rwa ← negative at negated162163theorem integerAbs.integer (z : Integer)164shows Integer(integerAbs(z))165proof166unfold integerAbs167exact integerOfNat.integer with*168169theorem integerAbs.neg (z : Integer)170shows integerAbs(-z) = integerAbs(z)171proof172have equal := integerNatAbs.neg with*173simp [integerAbs]174175theorem integerAbs.idempotent (z : Integer)176shows integerAbs(integerAbs(z)) = integerAbs(z)177proof178simp [integerAbs, integerNatAbs.ofNat]179180theorem integerNatAbs.mul (x y : Integer)181shows integerNatAbs(x * y) = integerNatAbs(x) * integerNatAbs(y)182proof183obtain⟨m, mNat, xSign⟩:= Integer.signed_natural at x with*184obtain⟨n, nNat, ySign⟩:= Integer.signed_natural at y with*185cases xSign with xPositive | xNegative186 . cases ySign with yPositive | yNegative187 . simp [integerMulValue.ofNat, integerNatAbs.ofNat]188 . simp [integerMulValue.ofNat_negative, integerNatAbs.ofNat, integerNatAbs.ofNegativeNat]189 . cases ySign with yPositive | yNegative190 . simp [integerMulValue.negative_ofNat, integerNatAbs.ofNat, integerNatAbs.ofNegativeNat]191 . simp [integerMulValue.negative_negative, integerNatAbs.ofNat, integerNatAbs.ofNegativeNat]192193-- Adjust a coefficient when its input is represented with the opposite sign.194theorem integerMulValue.sign_adjust (u z : Integer, n : Nat)195requires sign : z = integerOfNat(n) ∨ z = integerNegativeOfNat(n)196shows∃ v, Integer(v) ∧ v * z = u * integerOfNat(n)197proof198cases sign with positive | negative199 . witness u200rw positive201rfl202 . have negativeInteger := integerNegValue.integer at u with*203have product := integerMulValue.neg_both at u, integerOfNat(n) with*204have flipped := integerOfNat.neg with*205rw [flipped, ← negative] at product206refine⟨-u, negativeInteger, product⟩207208theorem integerNatAbs.zero209shows integerNatAbs(integerZero) =0210proof211have value := integerNatAbs.ofNat at0with*212 simpa [integerZero, integerOfNat] using value213214theorem integerNatAbs.zero_iff (z : Integer)215shows integerNatAbs(z) =0↔ z = integerZero216proof217constructor218 . intro zero219have sign := integerNatAbs.cases with*220rw zero at sign221unfold integerZero222cases sign with positive | negative223 . simpa [integerOfNat] using positive224 . simpa [integerNegativeOfNat] using negative225 . intro zero226rw zero227exact integerNatAbs.zero228