1-- The rational intervals: open intervals with rational endpoints form a2-- countable basis of the real line, by the density of ℚ in ℝ3-- (Real/Embedding)4-- Part of Cumulus, the Grace17 mathematics library.5-- Copyright (c) 2026 Grant Passmore.6-- Released under the Apache License 2.0. See LICENSE in the repository root.7-- Authors: Grant Passmore89module Grace.Cumulus.Topology.Real.RationalBase10import Basis11import Rat.Countable1213-- The open intervals with rational endpoints.14def rationalIntervals : Set:=15 { W ∈𝒫(ℝ) |∃ p ∈ ℚ, ∃ q ∈ ℚ, p < q ∧16 W = openInterval(rationalCut(p), rationalCut(q)) }1718theorem openInterval.member_intervals (p q : Rational)19requires less : p < q20shows openInterval(rationalCut(p), rationalCut(q)) ∈ rationalIntervals21proof22have realP := rationalCut.real at p withassumption23have realQ := rationalCut.real at q withassumption24have pInQ : p ∈ ℚ bytypecheck25have qInQ : q ∈ ℚ bytypecheck26apply rationalIntervals.membership.backward27refine⟨?_, p, pInQ, q, qInQ, less, rfl⟩28apply powerset.membership_iff.backward29exact openInterval.subset_reals at rationalCut(p), rationalCut(q)3031theorem rationalIntervals.open32shows rationalIntervals ⊆ realTopology33proof34intros W hW35have parts := rationalIntervals.membership.forward with hW36obtain⟨p, hp, q, hq, less, shape⟩:= parts.right37have realP := rationalCut.real at p with hp38have realQ := rationalCut.real at q with hq39rw shape40exact openInterval.open at rationalCut(p), rationalCut(q)4142-- Every open set around a real contains a rational interval around it.43theorem rationalIntervals.basis44shows Basis(ℝ, realTopology, rationalIntervals)45proof46constructor47 . exact rationalIntervals.open48 . intros U hU x hx49have parts := realTopology.membership.forward with hU50have inside := powerset.membership_iff.forward with parts.left51have realX := inside with x, hx52obtain⟨E, hE, positive, below⟩:= parts.right with x, hx53have lowerReal : x - E ∈ ℝ bytypecheck54have upperReal : x + E ∈ ℝ bytypecheck55have lowerLess : x - E < x bylinarith56have upperLess : x < x + E bylinarith57obtain⟨p, hp, lowerP, upperP⟩:= rationalCut.between with lowerLess58obtain⟨q, hq, lowerQ, upperQ⟩:= rationalCut.between with upperLess59have realP := rationalCut.real at p with hp60have realQ := rationalCut.real at q with hq61have cutsOrdered := realLess.transitive with upperP, lowerQ62have proper := realLess.characterization.forward with cutsOrdered63haveordered:= rationalCut.lt_of_cut_lt with proper64have found := openInterval.member_intervals withordered65have center : x ∈ openInterval(rationalCut(p), rationalCut(q)) :=66 openInterval.membership.backward with⟨realX, upperP, lowerQ⟩67refine⟨openInterval(rationalCut(p), rationalCut(q)), found, center, ?_⟩68 . intros y hy69obtain⟨realY, lowerY, upperY⟩:=70 openInterval.membership.forward with hy71have bounds : x - E < y ∧ y < x + E72constructor73 . linarith74 . linarith75have inBall := openBall.order_characterization.backward with bounds76exact below with y, inBall7778-- The pairs of rationals in increasing order index the rational intervals.79def rationalPairs : Set:=80 { r ∈ ℚ × ℚ | relates(rationalLess, fst(r), snd(r)) }8182theorem rationalPairs.countable83shows Countable(rationalPairs)84proof85have rationals := rationals.countable86have pairs := Countable.product at ℚ, ℚ with rationals, rationals87have subset : rationalPairs ⊆ ℚ × ℚ88intros r hr89have parts := rationalPairs.membership.forward with hr90exact parts.left91exact Countable.subset with pairs, subset9293defgraph rationalInterval (r ∈ rationalPairs) : rationalIntervals :=94 openInterval(rationalCut(fst(r)), rationalCut(snd(r)))95proof96have parts := rationalPairs.membership.forward with member97obtain⟨bound, p, hp, q, hq, shape⟩:=98 product.membership.forward with parts.left99have less := parts.right100rw [shape, fst.pair, snd.pair] at less101rw [shape, fst.pair, snd.pair]102exact openInterval.member_intervals with less103104theorem rationalInterval.surjective105shows SurjectiveBetween(rationalInterval, rationalPairs, rationalIntervals)106proof107constructor108 . exact rationalInterval.function109 . intros W hW110have parts := rationalIntervals.membership.forward with hW111obtain⟨p, hp, q, hq, less, shape⟩:= parts.right112have pairIn : (p, q) ∈ ℚ × ℚ := product.pair with hp, hq113have inPairs : (p, q) ∈ rationalPairs114apply rationalPairs.membership.backward115refine⟨pairIn, ?_⟩116rw [fst.pair, snd.pair]117exact less118have value := rationalInterval.relates with inPairs119rw [fst.pair, snd.pair, ← shape] at value120exact⟨(p, q), inPairs, value⟩121122theorem rationalIntervals.countable123shows Countable(rationalIntervals)124proof125have countable := rationalPairs.countable126have surjection := rationalInterval.surjective127exact Countable.of_surjection with countable, surjection128