1-- Rationals as signed natural fractions2-- 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.Rat.Defs8import Int.Core910-- ((a,b),m) represents (a-b)/m, with m nonzero. This presentation avoids11-- choosing representatives from integer quotient classes.12def positiveNaturals : Set:= { n ∈ ℕ | n ≠0 }13def rationalRepresentatives : Set:= integerPairs × positiveNaturals14def rationalEquivalent : Set:=15 { p ∈ rationalRepresentatives × rationalRepresentatives |16∃ a ∈ ℕ, ∃ b ∈ ℕ,17∃ m ∈ positiveNaturals, ∃ c ∈ ℕ,18∃ d ∈ ℕ, ∃ n ∈ positiveNaturals,19 p = (((a, b), m), ((c, d), n)) ∧20 n * a + m * d = m * c + n * b }2122def ℚ : Set:= (rationalRepresentatives ⧸ rationalEquivalent)23classRational (q : Set) := q ∈ ℚ2425-- Quotient classes are sets of rational representatives. These two views26-- keep client proofs at the rational level instead of reopening quotient27-- membership every time a representative is used.28theoremRational.representative (q u : Set)29requires rational : q ∈ ℚ30requires member : u ∈ q31shows u ∈ rationalRepresentatives32proof33unfold ℚ at rational34have bounded := quotient.subset_powerset at rationalRepresentatives, rationalEquivalent35have power := bounded with rational36have subset := powerset.membership_iff.forward with power37exact subset with member3839theorem rationalRepresentatives.pair (a b m : Nat)40requires nonzero : m ≠041shows ((a, b), m) ∈ rationalRepresentatives42proof43unfold rationalRepresentatives44apply product.pair45 . exact integerPairs.pair with*{2}46 . apply positiveNaturals.membership.backward at m47constructor48 . settlewith nat.omega49 . exact nonzero5051theorem rationalRepresentatives.coordinates (p : Set)52requires hp : p ∈ rationalRepresentatives53shows∃ a, Nat(a) ∧∃ b, Nat(b) ∧∃ m, Nat(m) ∧ m ≠0∧ p = ((a, b), m)54proof55unfold rationalRepresentatives at hp56simp [product.membership] at hp57rcases hp with⟨bounded, numerator, numeratorInteger, m, mPositive, shape⟩58obtain⟨a, haNat, b, hbNat, numeratorShape⟩:= integerPairs.coordinates with numeratorInteger59obtain⟨mNatSet, mNonzero⟩:= positiveNaturals.membership.forward with mPositive60have hmNat := nat.omega.backward with mNatSet61witness a62witness b63witness m64constructor65exact mNonzero66 rwa numeratorShape at shape6768theorem rationalEquivalent.relation69shows RelationOn(rationalEquivalent, rationalRepresentatives)70proof71intros p hp72simp [rationalEquivalent.membership] at hp73rcases hp with⟨bounded, witnesses⟩74exact bounded7576theorem rationalEquivalent.reflexive_pair (a b m : Nat)77requires nonzero : m ≠078shows relates(rationalEquivalent, ((a, b), m), ((a, b), m))79proof80unfold relates81apply rationalEquivalent.membership.backward82constructor83 . apply product.pair at ((a, b), m), ((a, b), m), rationalRepresentatives, rationalRepresentatives84 . exact rationalRepresentatives.pair with nonzero85 . exact rationalRepresentatives.pair with nonzero86 . witness a87constructor88 . settlewith nat.omega89 . witness b90constructor91 . settlewith nat.omega92 . witness m93constructor94 . apply positiveNaturals.membership.backward at m95constructor96 . settlewith nat.omega97 . exact nonzero98 . witness a99constructor100 . settlewith nat.omega101 . witness b102constructor103 . settlewith nat.omega104 . witness m105constructor106 . apply positiveNaturals.membership.backward at m107constructor108 . settlewith nat.omega109 . exact nonzero110refine⟨rfl, rfl⟩111112theorem rationalEquivalent.relates_representatives (a b m c d n : Nat)113requires mNonzero : m ≠0114requires nNonzero : n ≠0115shows relates(rationalEquivalent, ((a, b), m), ((c, d), n)) ↔ n * a + m * d = m * c + n * b116proof117constructor118 . intro h119unfold relates at h120simp [rationalEquivalent.membership] at h121rcases h with⟨bounded, wa, waNat, wb, wbNat, wm, wmPositive, wc, wcNat, wd, wdNat, wn, wnPositive, shape, equation⟩122obtain⟨leftShape, rightShape⟩:= orderedPair.injective with shape123obtain⟨numeratorLeft, denominatorLeft⟩:= orderedPair.injective with leftShape124obtain⟨numeratorRight, denominatorRight⟩:= orderedPair.injective with rightShape125obtain⟨aEquals, bEquals⟩:= orderedPair.injective with numeratorLeft126obtain⟨cEquals, dEquals⟩:= orderedPair.injective with numeratorRight127simp128 . intro equation129unfold relates130apply rationalEquivalent.membership.backward131constructor132 . apply product.pair at ((a, b), m), ((c, d), n), rationalRepresentatives, rationalRepresentatives133 . exact rationalRepresentatives.pair with mNonzero134 . exact rationalRepresentatives.pair with nNonzero135 . witness a136constructor137 . settlewith nat.omega138 . witness b139constructor140 . settlewith nat.omega141 . witness m142constructor143 . apply positiveNaturals.membership.backward at m144constructor145 . settlewith nat.omega146 . exact mNonzero147 . witness c148constructor149 . settlewith nat.omega150 . witness d151constructor152 . settlewith nat.omega153 . witness n154constructor155 . apply positiveNaturals.membership.backward at n156constructor157 . settlewith nat.omega158 . exact nNonzero159refine⟨rfl, equation⟩160161theorem rationalEquivalent.cross_symmetric (a b m c d n : Nat)162requires h : n * a + m * d = m * c + n * b163shows m * c + n * b = n * a + m * d164proof165simp166167theorem rationalEquivalent.cross_transitive_scaled (a b m c d n e f k : Nat)168requiresleft : n * a + m * d = m * c + n * b169requiresright : k * c + n * f = n * e + k * d170shows n * (k * a + m * f) = n * (m * e + k * b)171proof172linear_combination k *left+ m *right173174theorem rationalEquivalent.cross_transitive (a b m c d n e f k : Nat)175requires nNonzero : n ≠0176requiresleft : n * a + m * d = m * c + n * b177requiresright : k * c + n * f = n * e + k * d178shows k * a + m * f = m * e + k * b179proof180have scaled := rationalEquivalent.cross_transitive_scaled at a, b, m, c, d, n, e, f, k with*181exact mul.left_cancel_positive with nNonzero, scaled182183theorem rationalEquivalent.reflexive184shows ReflexiveOn(rationalRepresentatives, rationalEquivalent)185proof186intros p hp187obtain⟨a, haNat, b, hbNat, m, hmNat, mNonzero, shape⟩:= rationalRepresentatives.coordinates with hp188rw shape189exact rationalEquivalent.reflexive_pair with haNat, hbNat, hmNat, mNonzero190191theorem rationalEquivalent.symmetric192shows SymmetricOn(rationalRepresentatives, rationalEquivalent)193proof194intros p hp q hq hpq195obtain⟨a, haNat, b, hbNat, m, hmNat, mNonzero, pShape⟩:= rationalRepresentatives.coordinates with hp196obtain⟨c, hcNat, d, hdNat, n, hnNat, nNonzero, qShape⟩:= rationalRepresentatives.coordinates with hq197rw [pShape, qShape] at hpq198rw [pShape, qShape]199have characterization := rationalEquivalent.relates_representatives with haNat, hbNat, hmNat, hcNat, hdNat, hnNat, mNonzero, nNonzero200have equation := characterization.forward with hpq201have reverse := rationalEquivalent.cross_symmetric with haNat, hbNat, hmNat, hcNat, hdNat, hnNat, equation202have reverseCharacterization := rationalEquivalent.relates_representatives with hcNat, hdNat, hnNat, haNat, hbNat, hmNat, nNonzero, mNonzero203apply reverseCharacterization.backward204exact reverse205206theorem rationalEquivalent.transitive207shows TransitiveOn(rationalRepresentatives, rationalEquivalent)208proof209intros p hp q hq r hr hpq hqr210obtain⟨a, haNat, b, hbNat, m, hmNat, mNonzero, pShape⟩:= rationalRepresentatives.coordinates with hp211obtain⟨c, hcNat, d, hdNat, n, hnNat, nNonzero, qShape⟩:= rationalRepresentatives.coordinates with hq212obtain⟨e, heNat, f, hfNat, k, hkNat, kNonzero, rShape⟩:= rationalRepresentatives.coordinates with hr213rw [pShape, qShape] at hpq214rw [qShape, rShape] at hqr215rw [pShape, rShape]216have firstCharacterization := rationalEquivalent.relates_representatives with haNat, hbNat, hmNat, hcNat, hdNat, hnNat, mNonzero, nNonzero217have firstEquation := firstCharacterization.forward with hpq218have secondCharacterization := rationalEquivalent.relates_representatives with hcNat, hdNat, hnNat, heNat, hfNat, hkNat, nNonzero, kNonzero219have secondEquation := secondCharacterization.forward with hqr220have combined := rationalEquivalent.cross_transitive with haNat, hbNat, hmNat, hcNat, hdNat, hnNat, heNat, hfNat, hkNat, nNonzero, firstEquation, secondEquation221have resultCharacterization := rationalEquivalent.relates_representatives with haNat, hbNat, hmNat, heNat, hfNat, hkNat, mNonzero, kNonzero222apply resultCharacterization.backward223exact combined224225theorem rationalEquivalent.equivalence226shows Equivalence(rationalRepresentatives, rationalEquivalent)227proof228refine⟨rationalEquivalent.relation, rationalEquivalent.reflexive, rationalEquivalent.symmetric, rationalEquivalent.transitive⟩229230-- A rational class always has a representative. Client proofs231-- should use this boundary instead of reopening quotient and Power Set data.232theoremRational.some_representative (q : Set)233requires rational : q ∈ ℚ234shows∃ u ∈ q, u ∈ rationalRepresentatives235proof236have quotientMember := rational237unfold ℚ at quotientMember238obtain⟨u, hu⟩:= quotient.member_nonempty with rationalEquivalent.equivalence, quotientMember239have representative :=Rational.representative with rational, hu240refine⟨u, hu, representative⟩241242theoremRational.members_related (q u v : Set)243requires rational : q ∈ ℚ244requires hu : u ∈ q245requires hv : v ∈ q246shows relates(rationalEquivalent, u, v)247proof248unfold ℚ at rational249exact quotient.members_related with rationalEquivalent.equivalence, rational, hu, hv250251-- Related representatives determine the same rational point, regardless of252-- which representatives were chosen from the two quotient classes.253theoremRational.eq_of_related_members (q r u v : Set)254requires qRational : q ∈ ℚ255requires rRational : r ∈ ℚ256requires hu : u ∈ q257requires hv : v ∈ r258requires related : relates(rationalEquivalent, u, v)259shows q = r260proof261have uRepresentative :=Rational.representative with qRational, hu262have vRepresentative :=Rational.representative with rRational, hv263have qQuotient := qRational264unfold ℚ at qQuotient265have rQuotient := rRational266unfold ℚ at rQuotient267have qClass := quotient.class_of_member with rationalEquivalent.equivalence, qQuotient, hu268have rClass := quotient.class_of_member with rationalEquivalent.equivalence, rQuotient, hv269have sameClass := equivalenceClass.eq with270 rationalEquivalent.equivalence, uRepresentative, vRepresentative, related271 rwa [qClass, rClass]272273theorem rationals.membership (q : Set)274shows q ∈ ℚ ↔ q ∈ (rationalRepresentatives ⧸ rationalEquivalent)275proof276simp [ℚ]277