1-- The integers inside the reals: the embedding realInt sends the class of2-- (a, b) to a - b; it is an injective ring homomorphism agreeing with3-- realNat on the naturals, and its image is the set of differences of4-- naturals5-- 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.Real.Integer11import RootTwo12import Int1314-- The real number of an integer: the class of (a, b) goes to a - b, which15-- does not depend on the representative.16defunique realInt (z : Set) (x ∈ ℝ) :=17∃ a, Nat(a) ∧∃ b, Nat(b) ∧ z = integerClass(a, b) ∧18 x = (realNat(a):R) - (realNat(b):R)19requires integer : Integer(z)20proof21obtain⟨a, ha, b, hb, shape⟩:= Integer.representatives at z with*22have realA := realNat.real at a with ha23have realB := realNat.real at b with hb24have value : (realNat(a):R) - (realNat(b):R) ∈ ℝ bytypecheck25refine⟨(realNat(a):R) - (realNat(b):R), value, a, ha, b, hb, shape, rfl⟩26uniqueness27intros u hu first v hv second28obtain⟨a, ha, b, hb, shapeA, valueA⟩:= first29obtain⟨c, hc, d, hd, shapeC, valueC⟩:= second30have same : integerClass(a, b) = integerClass(c, d)31rw [← shapeA, ← shapeC]32rfl33have cross := integerClass.equivalent_of_eq at a, b, c, d with ha, hb, hc, hd, same34have realA := realNat.real at a with ha35have realB := realNat.real at b with hb36have realC := realNat.real at c with hc37have realD := realNat.real at d with hd38have realCross : (realNat(a):R) + (realNat(d):R) = (realNat(c):R) + (realNat(b):R)39rw [← realNat.add, ← realNat.add, cross]40rfl41rw [valueA, valueC]42linarith4344theorem realInt.real (z : Integer)45shows realInt(z) ∈ ℝ46proof47have selected := realInt.selected at z with*48exact selected.left4950-- The value on a class.51theorem realInt.class (a b : Nat)52shows realInt(integerClass(a, b)) = (realNat(a):R) - (realNat(b):R)53proof54have integer := integerClass.integer at a, b with*55have selected := realInt.selected at integerClass(a, b) with integer56obtain⟨c, hc, d, hd, same, value⟩:= selected.right57have cross := integerClass.equivalent_of_eq at a, b, c, d with*58have realA := realNat.real at a59have realB := realNat.real at b60have realC := realNat.real at c with hc61have realD := realNat.real at d with hd62have realCross : (realNat(a):R) + (realNat(d):R) = (realNat(c):R) + (realNat(b):R)63rw [← realNat.add, ← realNat.add, cross]64rfl65rw value66linarith6768-- Agreement with realNat on the naturals, and the values at 0 and 1.69theorem realInt.nat (n : Nat)70shows realInt(integerOfNat(n)) = realNat(n)71proof72have realN := realNat.real at n73unfold integerOfNat74rw [realInt.class, realNat.zero]75ring7677theorem realInt.zero78shows realInt(integerZero) = (0:R)79proof80unfold integerZero81rw [realInt.class, realNat.zero]82ring8384theorem realInt.one85shows realInt(integerOne) = (1:R)86proof87unfold integerOne88rw [realInt.nat, realNat.one]89rfl9091-- The ring homomorphism laws.92theorem realInt.add (m n : Integer)93shows realInt(m + n) = (realInt(m):R) + (realInt(n):R)94proof95obtain⟨a, ha, b, hb, shapeM⟩:= Integer.representatives at m with*96obtain⟨c, hc, d, hd, shapeN⟩:= Integer.representatives at n with*97have realA := realNat.real at a with ha98have realB := realNat.real at b with hb99have realC := realNat.real at c with hc100have realD := realNat.real at d with hd101have sum := integerAddValue.classes at a, b, c, d with*102rw [shapeM, shapeN, sum]103unfold integerClassSum104rw [realInt.class, realInt.class, realInt.class, realNat.add, realNat.add]105ring106107theorem realInt.neg (n : Integer)108shows realInt(-n) = -(realInt(n):R)109proof110obtain⟨c, hc, d, hd, shapeN⟩:= Integer.representatives at n with*111have realC := realNat.real at c with hc112have realD := realNat.real at d with hd113have negative := integerNegValue.classes at c, d with*114rw [shapeN, negative]115unfold integerClassNeg116rw [realInt.class, realInt.class]117ring118119theorem realInt.mul (m n : Integer)120shows realInt(m * n) = (realInt(m):R) * (realInt(n):R)121proof122obtain⟨a, ha, b, hb, shapeM⟩:= Integer.representatives at m with*123obtain⟨c, hc, d, hd, shapeN⟩:= Integer.representatives at n with*124have realA := realNat.real at a with ha125have realB := realNat.real at b with hb126have realC := realNat.real at c with hc127have realD := realNat.real at d with hd128have product := integerMulValue.classes at a, b, c, d with*129rw [shapeM, shapeN, product]130unfold integerClassMul131rw [realInt.class, realInt.class, realInt.class, realNat.add, realNat.add,132 realNat.mul, realNat.mul, realNat.mul, realNat.mul]133ring134135theorem realInt.sub (m n : Integer)136shows realInt(m - n) = (realInt(m):R) - (realInt(n):R)137proof138have negative := integerNegValue.integer at n with*139have realM := realInt.real at m with*140have realN := realInt.real at n with*141unfold integerSubValue142rw [integerAddValue.notation, integerNegValue.notation, realInt.add, realInt.neg]143ring144145-- The embedding is injective.146theorem realInt.injective (m n : Integer)147requires equal : realInt(m) = realInt(n)148shows m = n149proof150obtain⟨a, ha, b, hb, shapeM⟩:= Integer.representatives at m with*151obtain⟨c, hc, d, hd, shapeN⟩:= Integer.representatives at n with*152have realA := realNat.real at a with ha153have realB := realNat.real at b with hb154have realC := realNat.real at c with hc155have realD := realNat.real at d with hd156rw [shapeM, shapeN, realInt.class, realInt.class] at equal157have cross : (realNat(a):R) + (realNat(d):R) = (realNat(c):R) + (realNat(b):R)158linarith159rw [← realNat.add, ← realNat.add] at cross160have natural := realNat.injective at a + d, c + b with cross161rw [shapeM, shapeN]162exact integerClass.eq at a, b, c, d with natural163164-- An integer is written as a real wherever a real is expected.165notation coercion realInt for Integer, Real166167-- The image of ℤ in ℝ is the set of differences of naturals.168theorem realInt.range (x : Set)169shows (∃ z ∈ ℤ, x = realInt(z)) ↔170∃ m ∈ ℕ, ∃ n ∈ ℕ, x = (realNat(m):R) - (realNat(n):R)171proof172constructor173 . intro image174obtain⟨z, hz, shape⟩:= image175obtain⟨a, ha, b, hb, zShape⟩:= Integer.representatives at z with hz176have value := realInt.class at a, b with ha, hb177rw [zShape, value] at shape178have aIn := nat.omega.forward with ha179have bIn := nat.omega.forward with hb180refine⟨a, aIn, b, bIn, shape⟩181 . intro difference182obtain⟨m, hm, n, hn, shape⟩:= difference183have natM := nat.omega.backward with hm184have natN := nat.omega.backward with hn185have integer := integerClass.integer at m, n with natM, natN186have value := realInt.class at m, n with natM, natN187refine⟨integerClass(m, n), integer, ?_⟩188rw [shape, value]189rfl190