The rationals
Analysis I, Section 4.2
This file is a translation of Section 4.2 of Analysis I to Lean 4. All numbering refers to the original text.
I have attempted to make the translation as faithful a paraphrasing as possible of the original text. When there is a choice between a more idiomatic Lean solution and a more faithful translation, I have generally chosen the latter. In particular, there will be places where the Lean code could be "golfed" to be more elegant and idiomatic, but I have consciously avoided doing so.
Main constructions and results of this section:
-
Definition of the "Section 4.2" rationals,
Section_4_2.Rat, as formal quotientsa // bof integers, up to equivalence. (This is a quotient of a scaffolding typeSection_4_2.PreRat, which consists of formal quotients without any equivalence imposed.) -
Field operations and order on these rationals, as well as an embedding of ℕ and ℤ.
-
Equivalence with the Mathlib rationals
_root_.Rat(orℚ), which we will use going forward.
Note: here (and in the sequel) we use Mathlib's natural numbers ℕ and integers ℤ rather than
the Chapter 2 natural numbers and Section 4.1 integers.
Tips from past users
Users of the companion who have completed the exercises in this section are welcome to send their tips for future users in this section as PRs.
-
(Add tip here)
namespace Section_4_2structure PreRat where
numerator : ℤ
denominator : ℤ
nonzero : denominator ≠ 0Exercise 4.2.1
instance PreRat.instSetoid : Setoid PreRat where
r a b := a.numerator * b.denominator = b.numerator * a.denominator
iseqv := {
refl := ⊢ ∀ (x : PreRat), x.numerator * x.denominator = x.numerator * x.denominator All goals completed! 🐙
symm := ⊢ ∀ {x y : PreRat},
x.numerator * y.denominator = y.numerator * x.denominator → y.numerator * x.denominator = x.numerator * y.denominator All goals completed! 🐙
trans := ⊢ ∀ {x y z : PreRat},
x.numerator * y.denominator = y.numerator * x.denominator →
y.numerator * z.denominator = z.numerator * y.denominator →
x.numerator * z.denominator = z.numerator * x.denominator All goals completed! 🐙
}@[simp]
theorem PreRat.eq (a b c d:ℤ) (hb: b ≠ 0) (hd: d ≠ 0) :
(⟨ a,b,hb ⟩: PreRat) ≈ ⟨ c,d,hd ⟩ ↔ a * d = c * b := a:ℤb:ℤc:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ { numerator := a, denominator := b, nonzero := hb } ≈ { numerator := c, denominator := d, nonzero := hd } ↔
a * d = c * b All goals completed! 🐙abbrev Rat := Quotient PreRat.instSetoidWe give division a "junk" value of 0//1 if the denominator is zero
abbrev Rat.formalDiv (a b:ℤ) : Rat :=
Quotient.mk PreRat.instSetoid (if h:b ≠ 0 then ⟨ a,b,h ⟩ else ⟨ 0, 1, a:ℤb:ℤh:¬b ≠ 0⊢ 1 ≠ 0 All goals completed! 🐙 ⟩)infix:100 " // " => Rat.formalDivDefinition 4.2.1 (Rationals)
theorem Rat.eq (a c:ℤ) {b d:ℤ} (hb: b ≠ 0) (hd: d ≠ 0): a // b = c // d ↔ a * d = c * b := a:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ a // b = c // d ↔ a * d = c * b
All goals completed! 🐙Definition 4.2.1 (Rationals)
theorem Rat.eq_diff (n:Rat) : ∃ a b, b ≠ 0 ∧ n = a // b := n:Rat⊢ ∃ a b, b ≠ 0 ∧ n = a // b
n:Rat⊢ ∀ (a : PreRat), ∃ a_1 b, b ≠ 0 ∧ ⟦a⟧ = a_1 // b; n:Rata:ℤb:ℤh:b ≠ 0⊢ ∃ a_1 b_1, b_1 ≠ 0 ∧ ⟦{ numerator := a, denominator := b, nonzero := h }⟧ = a_1 // b_1
n:Rata:ℤb:ℤh:b ≠ 0⊢ ⟦{ numerator := a, denominator := b, nonzero := h }⟧ = a // b
All goals completed! 🐙
Decidability of equality. Hint: modify the proof of DecidableEq Int from the previous
section. However, because formal division handles the case of zero denominator separately, it
may be more convenient to avoid that operation and work directly with the Quotient API.
instance Rat.decidableEq : DecidableEq Rat := ⊢ DecidableEq Rat
All goals completed! 🐙Lemma 4.2.3 (Addition well-defined)
instance Rat.add_inst : Add Rat where
add := Quotient.lift₂ (fun ⟨ a, b, h1 ⟩ ⟨ c, d, h2 ⟩ ↦ (a*d+b*c) // (b*d)) (⊢ ∀ (a₁ b₁ a₂ b₂ : PreRat),
a₁ ≈ a₂ →
b₁ ≈ b₂ →
(fun x x_1 =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } =>
match x_1 with
| { numerator := c, denominator := d, nonzero := h2 } => (a * d + b * c) // (b * d))
a₁ b₁ =
(fun x x_1 =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } =>
match x_1 with
| { numerator := c, denominator := d, nonzero := h2 } => (a * d + b * c) // (b * d))
a₂ b₂
a:ℤb:ℤh1:b ≠ 0c:ℤd:ℤh2:d ≠ 0a':ℤb':ℤh1':b' ≠ 0c':ℤd':ℤh2':d' ≠ 0h3:{ numerator := a, denominator := b, nonzero := h1 } ≈ { numerator := a', denominator := b', nonzero := h1' }h4:{ numerator := c, denominator := d, nonzero := h2 } ≈ { numerator := c', denominator := d', nonzero := h2' }⊢ (fun x x_1 =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } =>
match x_1 with
| { numerator := c, denominator := d, nonzero := h2 } => (a * d + b * c) // (b * d))
{ numerator := a, denominator := b, nonzero := h1 } { numerator := c, denominator := d, nonzero := h2 } =
(fun x x_1 =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } =>
match x_1 with
| { numerator := c, denominator := d, nonzero := h2 } => (a * d + b * c) // (b * d))
{ numerator := a', denominator := b', nonzero := h1' } { numerator := c', denominator := d', nonzero := h2' }
a:ℤb:ℤh1:b ≠ 0c:ℤd:ℤh2:d ≠ 0a':ℤb':ℤh1':b' ≠ 0c':ℤd':ℤh2':d' ≠ 0h3:a * b' = a' * bh4:c * d' = c' * d⊢ (a * d + b * c) * (b' * d') = (a' * d' + b' * c') * (b * d)
calc
_ = (a*b')*d*d' + b*b'*(c*d') := a:ℤb:ℤh1:b ≠ 0c:ℤd:ℤh2:d ≠ 0a':ℤb':ℤh1':b' ≠ 0c':ℤd':ℤh2':d' ≠ 0h3:a * b' = a' * bh4:c * d' = c' * d⊢ (a * d + b * c) * (b' * d') = a * b' * d * d' + b * b' * (c * d') All goals completed! 🐙
_ = (a'*b)*d*d' + b*b'*(c'*d) := a:ℤb:ℤh1:b ≠ 0c:ℤd:ℤh2:d ≠ 0a':ℤb':ℤh1':b' ≠ 0c':ℤd':ℤh2':d' ≠ 0h3:a * b' = a' * bh4:c * d' = c' * d⊢ a * b' * d * d' + b * b' * (c * d') = a' * b * d * d' + b * b' * (c' * d) All goals completed! 🐙
_ = _ := a:ℤb:ℤh1:b ≠ 0c:ℤd:ℤh2:d ≠ 0a':ℤb':ℤh1':b' ≠ 0c':ℤd':ℤh2':d' ≠ 0h3:a * b' = a' * bh4:c * d' = c' * d⊢ a' * b * d * d' + b * b' * (c' * d) = (a' * d' + b' * c') * (b * d) All goals completed! 🐙
)Definition 4.2.2 (Addition of rationals)
theorem Rat.add_eq (a c:ℤ) {b d:ℤ} (hb: b ≠ 0) (hd: d ≠ 0) :
(a // b) + (c // d) = (a*d + b*c) // (b*d) := a:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ a // b + c // d = (a * d + b * c) // (b * d)
a:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ a =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ d =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ c =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ d =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominator a:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ a =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ d =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ c =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ d =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominator All goals completed! 🐙Lemma 4.2.3 (Multiplication well-defined)
instance Rat.mul_inst : Mul Rat where
mul := Quotient.lift₂ (fun ⟨ a, b, h1 ⟩ ⟨ c, d, h2 ⟩ ↦ (a*c) // (b*d)) (⊢ ∀ (a₁ b₁ a₂ b₂ : PreRat),
a₁ ≈ a₂ →
b₁ ≈ b₂ →
(fun x x_1 =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } =>
match x_1 with
| { numerator := c, denominator := d, nonzero := h2 } => (a * c) // (b * d))
a₁ b₁ =
(fun x x_1 =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } =>
match x_1 with
| { numerator := c, denominator := d, nonzero := h2 } => (a * c) // (b * d))
a₂ b₂ All goals completed! 🐙)Definition 4.2.2 (Multiplication of rationals)
theorem Rat.mul_eq (a c:ℤ) {b d:ℤ} (hb: b ≠ 0) (hd: d ≠ 0) :
(a // b) * (c // d) = (a*c) // (b*d) := a:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ a // b * c // d = (a * c) // (b * d)
a:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ a =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ c =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ d =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominator a:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ a =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ c =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤc:ℤb:ℤd:ℤhb:b ≠ 0hd:d ≠ 0⊢ d =
(if h : d ≠ 0 then { numerator := c, denominator := d, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominator All goals completed! 🐙Lemma 4.2.3 (Negation well-defined)
instance Rat.neg_inst : Neg Rat where
neg := Quotient.lift (fun ⟨ a, b, h1 ⟩ ↦ (-a) // b) (⊢ ∀ (a b : PreRat),
a ≈ b →
(fun x =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } => (-a) // b)
a =
(fun x =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } => (-a) // b)
b All goals completed! 🐙)Definition 4.2.2 (Negation of rationals)
theorem Rat.neg_eq (a:ℤ) {b:ℤ} (hb: b ≠ 0) : - (a // b) = (-a) // b := a:ℤb:ℤhb:b ≠ 0⊢ -a // b = (-a) // b
a:ℤb:ℤhb:b ≠ 0⊢ a =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤb:ℤhb:b ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominator a:ℤb:ℤhb:b ≠ 0⊢ a =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:ℤb:ℤhb:b ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominator All goals completed! 🐙Embedding the integers in the rationals
instance Rat.instIntCast : IntCast Rat where
intCast a := a // 1instance Rat.instNatCast : NatCast Rat where
natCast n := (n:ℤ) // 1instance Rat.instOfNat {n:ℕ} : OfNat Rat n where
ofNat := (n:ℤ) // 1theorem Rat.coe_Int_eq (a:ℤ) : (a:Rat) = a // 1 := rfltheorem Rat.coe_Nat_eq (n:ℕ) : (n:Rat) = n // 1 := rfltheorem Rat.of_Nat_eq (n:ℕ) : (ofNat(n):Rat) = (ofNat(n):Nat) // 1 := rflnatCast distributes over successor
theorem Rat.natCast_succ (n: ℕ) : ((n + 1: ℕ): Rat) = (n: Rat) + 1 := n:ℕ⊢ ↑(n + 1) = ↑n + 1 All goals completed! 🐙intCast distributes over addition
lemma Rat.intCast_add (a b:ℤ) : (a:Rat) + (b:Rat) = (a+b:ℤ) := a:ℤb:ℤ⊢ ↑a + ↑b = ↑(a + b) All goals completed! 🐙intCast distributes over multiplication
lemma Rat.intCast_mul (a b:ℤ) : (a:Rat) * (b:Rat) = (a*b:ℤ) := a:ℤb:ℤ⊢ ↑a * ↑b = ↑(a * b) All goals completed! 🐙theorem Rat.coe_Int_inj : Function.Injective (fun n:ℤ ↦ (n:Rat)) := ⊢ Function.Injective fun n => ↑n All goals completed! 🐙Whereas the book leaves the inverse of 0 undefined, it is more convenient in Lean to assign a "junk" value to this inverse; we arbitrarily choose this junk value to be 0.
instance Rat.instInv : Inv Rat where
inv := Quotient.lift (fun ⟨ a, b, h1 ⟩ ↦ b // a) (⊢ ∀ (a b : PreRat),
a ≈ b →
(fun x =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } => b // a)
a =
(fun x =>
match x with
| { numerator := a, denominator := b, nonzero := h1 } => b // a)
b
All goals completed! 🐙 -- hint: split into the `a=0` and `a≠0` cases
)lemma Rat.inv_eq (a:ℤ) {b:ℤ} (hb: b ≠ 0) : (a // b)⁻¹ = b // a := a:ℤb:ℤhb:b ≠ 0⊢ (a // b)⁻¹ = b // a
a:ℤb:ℤhb:b ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤb:ℤhb:b ≠ 0⊢ a =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numerator a:ℤb:ℤhb:b ≠ 0⊢ b =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:ℤb:ℤhb:b ≠ 0⊢ a =
(if h : b ≠ 0 then { numerator := a, denominator := b, nonzero := h }
else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numerator All goals completed! 🐙@[simp]
theorem Rat.inv_zero : (0:Rat)⁻¹ = 0 := rflProposition 4.2.4 (laws of algebra) / Exercise 4.2.3
instance Rat.addGroup_inst : AddGroup Rat :=
AddGroup.ofLeftAxioms (⊢ ∀ (a b c : Rat), a + b + c = a + (b + c)
-- this proof is written to follow the structure of the original text.
x:Raty:Ratz:Rat⊢ x + y + z = x + (y + z)
y:Ratz:Rata:ℤb:ℤhb:b ≠ 0⊢ a // b + y + z = a // b + (y + z)
z:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0⊢ a // b + c // d + z = a // b + (c // d + z)
a:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0e:ℤf:ℤhf:f ≠ 0⊢ a // b + c // d + e // f = a // b + (c // d + e // f)
a:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0e:ℤf:ℤhf:f ≠ 0hbd:_fvar.38578 * _fvar.38654 ≠ 0 := Int.mul_ne_zero _fvar.38600 _fvar.38672⊢ a // b + c // d + e // f = a // b + (c // d + e // f) -- can also use `observe hbd : b*d ≠ 0` here
a:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0e:ℤf:ℤhf:f ≠ 0hbd:_fvar.38578 * _fvar.38654 ≠ 0 := Int.mul_ne_zero _fvar.38600 _fvar.38672hdf:_fvar.38654 * _fvar.38726 ≠ 0 := Int.mul_ne_zero _fvar.38672 _fvar.38744⊢ a // b + c // d + e // f = a // b + (c // d + e // f) -- can also use `observe hdf : d*f ≠ 0` here
a:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0e:ℤf:ℤhf:f ≠ 0hbd:_fvar.38578 * _fvar.38654 ≠ 0 := Int.mul_ne_zero _fvar.38600 _fvar.38672hdf:_fvar.38654 * _fvar.38726 ≠ 0 := Int.mul_ne_zero _fvar.38672 _fvar.38744hbdf:_fvar.38578 * _fvar.38654 * _fvar.38726 ≠ 0 := Int.mul_ne_zero _fvar.38859 _fvar.38744⊢ a // b + c // d + e // f = a // b + (c // d + e // f) -- can also use `observe hbdf : b*d*f ≠ 0` here
a:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0e:ℤf:ℤhf:f ≠ 0hbd:_fvar.38578 * _fvar.38654 ≠ 0 := Int.mul_ne_zero _fvar.38600 _fvar.38672hdf:_fvar.38654 * _fvar.38726 ≠ 0 := Int.mul_ne_zero _fvar.38672 _fvar.38744hbdf:_fvar.38578 * _fvar.38654 * _fvar.38726 ≠ 0 := Int.mul_ne_zero _fvar.38859 _fvar.38744⊢ ((a * d + b * c) * f + b * d * e) * (b * d * f) = (a * (d * f) + b * (c * f + d * e)) * (b * d * f)
All goals completed! 🐙
)
(⊢ ∀ (a : Rat), 0 + a = a All goals completed! 🐙) (⊢ ∀ (a : Rat), -a + a = 0 All goals completed! 🐙)Proposition 4.2.4 (laws of algebra) / Exercise 4.2.3
instance Rat.instAddCommGroup : AddCommGroup Rat where
add_comm := ⊢ ∀ (a b : Rat), a + b = b + a All goals completed! 🐙Proposition 4.2.4 (laws of algebra) / Exercise 4.2.3
instance Rat.instCommMonoid : CommMonoid Rat where
mul_comm := ⊢ ∀ (a b : Rat), a * b = b * a All goals completed! 🐙
mul_assoc := ⊢ ∀ (a b c : Rat), a * b * c = a * (b * c) All goals completed! 🐙
one_mul := ⊢ ∀ (a : Rat), 1 * a = a All goals completed! 🐙
mul_one := ⊢ ∀ (a : Rat), a * 1 = a All goals completed! 🐙Proposition 4.2.4 (laws of algebra) / Exercise 4.2.3
instance Rat.instCommRing : CommRing Rat where
left_distrib := ⊢ ∀ (a b c : Rat), a * (b + c) = a * b + a * c All goals completed! 🐙
right_distrib := ⊢ ∀ (a b c : Rat), (a + b) * c = a * c + b * c All goals completed! 🐙
zero_mul := ⊢ ∀ (a : Rat), 0 * a = 0 All goals completed! 🐙
mul_zero := ⊢ ∀ (a : Rat), a * 0 = 0 All goals completed! 🐙
mul_assoc := ⊢ ∀ (a b c : Rat), a * b * c = a * (b * c) All goals completed! 🐙
-- Usually CommRing will generate a natCast instance and a proof for this.
-- However, we are using a custom natCast for which `natCast_succ` cannot
-- be proven automatically by `rfl`. Luckily we have proven it already.
natCast_succ := natCast_succinstance Rat.instRatCast : RatCast Rat where
ratCast q := q.num // q.dentheorem Rat.ratCast_inj : Function.Injective (fun n:ℚ ↦ (n:Rat)) := ⊢ Function.Injective fun n => ↑n All goals completed! 🐙theorem Rat.coe_Rat_eq (a:ℤ) {b:ℤ} (hb: b ≠ 0) : (a/b:ℚ) = a // b := a:ℤb:ℤhb:b ≠ 0⊢ ↑(↑a / ↑b) = a // b
a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388⊢ ↑q = a // b
a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)⊢ ↑q = a // b
a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)⊢ ↑q = a // b
have hden : den ≠ 0 := a:ℤb:ℤhb:b ≠ 0⊢ ↑(↑a / ↑b) = a // b All goals completed! 🐙
a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:_fvar.43699 ≠ 0 := ?_mvar.43808⊢ num // den = a // b
a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:_fvar.43699 ≠ 0 := ?_mvar.43808⊢ num * b = a * den
a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:_fvar.43699 ≠ 0 := ?_mvar.43808⊢ ↑num * ↑b = ↑a * ↑den
a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:_fvar.43699 ≠ 0 := ?_mvar.43808hq:↑_fvar.43609 / ↑_fvar.43699 = _fvar.43551 := Rat.num_div_den _fvar.43551⊢ ↑num * ↑b = ↑a * ↑den
rwa [div_eq_div_iffa:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:_fvar.43699 ≠ 0 := ?_mvar.43808hq:↑num * ↑b = ↑a * ↑den⊢ ↑num * ↑b = ↑a * ↑dena:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:_fvar.43699 ≠ 0 := ?_mvar.43808hq:↑_fvar.43609 / ↑_fvar.43699 = _fvar.43551 := Rat.num_div_den _fvar.43551⊢ ↑den ≠ 0a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:_fvar.43699 ≠ 0 := ?_mvar.43808hq:↑_fvar.43609 / ↑_fvar.43699 = _fvar.43551 := Rat.num_div_den _fvar.43551⊢ ↑b ≠ 0 at hq a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:_fvar.43699 ≠ 0 := ?_mvar.43808hq:↑_fvar.43609 / ↑_fvar.43699 = _fvar.43551 := Rat.num_div_den _fvar.43551⊢ ↑den ≠ 0a:ℤb:ℤhb:b ≠ 0q:ℚ := ↑_fvar.43387 / ↑_fvar.43388num:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:_fvar.43699 ≠ 0 := ?_mvar.43808hq:↑_fvar.43609 / ↑_fvar.43699 = _fvar.43551 := Rat.num_div_den _fvar.43551⊢ ↑b ≠ 0 All goals completed! 🐙
theorem Rat.div_eq (q r:Rat) : q/r = q * r⁻¹ := q:Ratr:Rat⊢ q / r = q * r⁻¹ All goals completed! 🐙Proposition 4.2.4 (laws of algebra) / Exercise 4.2.3
instance Rat.instField : Field Rat where
exists_pair_ne := ⊢ ∃ x y, x ≠ y All goals completed! 🐙
mul_inv_cancel := ⊢ ∀ (a : Rat), a ≠ 0 → a * a⁻¹ = 1 All goals completed! 🐙
inv_zero := rfl
ratCast_def := ⊢ ∀ (q : ℚ), ↑q = ↑q.num / ↑q.den
q:ℚ⊢ ↑q = ↑q.num / ↑q.den
q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)⊢ ↑q = ↑num / ↑q.den
q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)⊢ ↑q = ↑num / ↑den
have hden : (den:ℤ) ≠ 0 := ⊢ ∀ (q : ℚ), ↑q = ↑q.num / ↑q.den All goals completed! 🐙
q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ ↑(↑q.num / ↑q.den) = ↑num / ↑den
q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ ↑num / ↑den = q.num // ↑den
q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ num * 1 * ↑den = q.num * (1 * ↑den)q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ 1 * ↑den ≠ 0q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ ↑den ≠ 0q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ 1 ≠ 0q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ ↑den ≠ 0q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ 1 ≠ 0 q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ num * 1 * ↑den = q.num * (1 * ↑den)q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ 1 * ↑den ≠ 0q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ ↑den ≠ 0q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ 1 ≠ 0q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ ↑den ≠ 0q:ℚnum:ℤ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)den:ℕ := failed to pretty print expression (use 'set_option pp.rawOnError true' for raw representation)hden:↑_fvar.47889 ≠ 0 := ?_mvar.48005⊢ 1 ≠ 0 All goals completed! 🐙
qsmul := _
nnqsmul := _example : (3//4) / (5//6) = 9 // 10 := ⊢ 3 // 4 / 5 // 6 = 9 // 10 All goals completed! 🐙def Rat.coe_int_hom : ℤ →+* Rat where
toFun n := (n:Rat)
map_zero' := rfl
map_one' := rfl
map_add' := ⊢ ∀ (x y : ℤ), ↑(x + y) = ↑x + ↑y All goals completed! 🐙
map_mul' := ⊢ ∀ (x y : ℤ), ↑(x * y) = ↑x * ↑y All goals completed! 🐙
Lemma 4.2.7 (trichotomy of rationals) / Exercise 4.2.4
theorem Rat.trichotomous (x:Rat) : x = 0 ∨ x.isPos ∨ x.isNeg := x:Rat⊢ x = 0 ∨ x.isPos ∨ x.isNeg All goals completed! 🐙Lemma 4.2.7 (trichotomy of rationals) / Exercise 4.2.4
theorem Rat.not_zero_and_pos (x:Rat) : ¬(x = 0 ∧ x.isPos) := x:Rat⊢ ¬(x = 0 ∧ x.isPos) All goals completed! 🐙Lemma 4.2.7 (trichotomy of rationals) / Exercise 4.2.4
theorem Rat.not_zero_and_neg (x:Rat) : ¬(x = 0 ∧ x.isNeg) := x:Rat⊢ ¬(x = 0 ∧ x.isNeg) All goals completed! 🐙Lemma 4.2.7 (trichotomy of rationals) / Exercise 4.2.4
theorem Rat.not_pos_and_neg (x:Rat) : ¬(x.isPos ∧ x.isNeg) := x:Rat⊢ ¬(x.isPos ∧ x.isNeg) All goals completed! 🐙Definition 4.2.8 (Ordering of the rationals)
instance Rat.instLT : LT Rat where
lt x y := (x-y).isNegDefinition 4.2.8 (Ordering of the rationals)
instance Rat.instLE : LE Rat where
le x y := (x < y) ∨ (x = y)theorem Rat.lt_iff (x y:Rat) : x < y ↔ (x-y).isNeg := x:Raty:Rat⊢ x < y ↔ (x - y).isNeg All goals completed! 🐙theorem Rat.le_iff (x y:Rat) : x ≤ y ↔ (x < y) ∨ (x = y) := x:Raty:Rat⊢ x ≤ y ↔ x < y ∨ x = y All goals completed! 🐙theorem Rat.gt_iff (x y:Rat) : x > y ↔ (x-y).isPos := x:Raty:Rat⊢ x > y ↔ (x - y).isPos All goals completed! 🐙theorem Rat.ge_iff (x y:Rat) : x ≥ y ↔ (x > y) ∨ (x = y) := x:Raty:Rat⊢ x ≥ y ↔ x > y ∨ x = y All goals completed! 🐙Proposition 4.2.9(a) (order trichotomy) / Exercise 4.2.5
theorem Rat.trichotomous' (x y:Rat) : x > y ∨ x < y ∨ x = y := x:Raty:Rat⊢ x > y ∨ x < y ∨ x = y All goals completed! 🐙Proposition 4.2.9(a) (order trichotomy) / Exercise 4.2.5
theorem Rat.not_gt_and_lt (x y:Rat) : ¬ (x > y ∧ x < y):= x:Raty:Rat⊢ ¬(x > y ∧ x < y) All goals completed! 🐙Proposition 4.2.9(a) (order trichotomy) / Exercise 4.2.5
theorem Rat.not_gt_and_eq (x y:Rat) : ¬ (x > y ∧ x = y):= x:Raty:Rat⊢ ¬(x > y ∧ x = y) All goals completed! 🐙Proposition 4.2.9(a) (order trichotomy) / Exercise 4.2.5
theorem Rat.not_lt_and_eq (x y:Rat) : ¬ (x < y ∧ x = y):= x:Raty:Rat⊢ ¬(x < y ∧ x = y) All goals completed! 🐙Proposition 4.2.9(b) (order is anti-symmetric) / Exercise 4.2.5
theorem Rat.antisymm (x y:Rat) : x < y ↔ y > x := x:Raty:Rat⊢ x < y ↔ y > x All goals completed! 🐙Proposition 4.2.9(c) (order is transitive) / Exercise 4.2.5
theorem Rat.lt_trans {x y z:Rat} (hxy: x < y) (hyz: y < z) : x < z := x:Raty:Ratz:Rathxy:x < yhyz:y < z⊢ x < z All goals completed! 🐙Proposition 4.2.9(d) (addition preserves order) / Exercise 4.2.5
theorem Rat.add_lt_add_right {x y:Rat} (z:Rat) (hxy: x < y) : x + z < y + z := x:Raty:Ratz:Rathxy:x < y⊢ x + z < y + z All goals completed! 🐙Proposition 4.2.9(e) (positive multiplication preserves order) / Exercise 4.2.5
theorem Rat.mul_lt_mul_right {x y z:Rat} (hxy: x < y) (hz: z.isPos) : x * z < y * z := x:Raty:Ratz:Rathxy:x < yhz:z.isPos⊢ x * z < y * z All goals completed! 🐙(Not from textbook) Establish the decidability of this order.
instance Rat.decidableRel : DecidableRel (·≤ ·: Rat → Rat → Prop) := ⊢ DecidableRel fun x1 x2 => x1 ≤ x2
n:Ratm:Rat⊢ Decidable ((fun x1 x2 => x1 ≤ x2) n m)
have : ∀ (n:PreRat) (m: PreRat),
Decidable (Quotient.mk PreRat.instSetoid n ≤ Quotient.mk PreRat.instSetoid m) := ⊢ DecidableRel fun x1 x2 => x1 ≤ x2
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0⊢ Decidable
(⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧)
-- at this point, the goal is morally `Decidable(a//b ≤ c//d)`, but there are technical
-- issues due to the junk value of formal division when the denominator vanishes.
-- It may be more convenient to avoid formal division and work directly with `Quotient.mk`.
cases (0:ℤ).decLe (b*d) with
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:0 ≤ b * d⊢ Decidable
(⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧)
cases (a * d).decLe (b * c) with
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:0 ≤ b * dh:a * d ≤ b * c⊢ Decidable
(⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧)
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:0 ≤ b * dh:a * d ≤ b * c⊢ ⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧
All goals completed! 🐙
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:0 ≤ b * dh:¬a * d ≤ b * c⊢ Decidable
(⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧)
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:0 ≤ b * dh:¬a * d ≤ b * c⊢ ¬⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧
All goals completed! 🐙
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:¬0 ≤ b * d⊢ Decidable
(⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧)
cases (b * c).decLe (a * d) with
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:¬0 ≤ b * dh:b * c ≤ a * d⊢ Decidable
(⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧)
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:¬0 ≤ b * dh:b * c ≤ a * d⊢ ⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧
All goals completed! 🐙
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:¬0 ≤ b * dh:¬b * c ≤ a * d⊢ Decidable
(⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧)
n:Ratm:Rata:ℤb:ℤhb:b ≠ 0c:ℤd:ℤhd:d ≠ 0hbd:¬0 ≤ b * dh:¬b * c ≤ a * d⊢ ¬⟦{ numerator := a, denominator := b, nonzero := hb }⟧ ≤ ⟦{ numerator := c, denominator := d, nonzero := hd }⟧
All goals completed! 🐙
All goals completed! 🐙(Not from textbook) Rat has the structure of a linear ordering.
instance Rat.instLinearOrder : LinearOrder Rat where
le_refl := sorry
le_trans := sorry
lt_iff_le_not_ge := sorry
le_antisymm := sorry
le_total := sorry
toDecidableLE := decidableRel(Not from textbook) Rat has the structure of a strict ordered ring.
instance Rat.instIsStrictOrderedRing : IsStrictOrderedRing Rat where
add_le_add_left := ⊢ ∀ (a b : Rat), a ≤ b → ∀ (c : Rat), c + a ≤ c + b All goals completed! 🐙
add_le_add_right := ⊢ ∀ (a b : Rat), a ≤ b → ∀ (c : Rat), a + c ≤ b + c All goals completed! 🐙
mul_lt_mul_of_pos_left := ⊢ ∀ (a b c : Rat), a < b → 0 < c → c * a < c * b All goals completed! 🐙
mul_lt_mul_of_pos_right := ⊢ ∀ (a b c : Rat), a < b → 0 < c → a * c < b * c All goals completed! 🐙
le_of_add_le_add_left := ⊢ ∀ (a b c : Rat), a + b ≤ a + c → b ≤ c All goals completed! 🐙
zero_le_one := ⊢ 0 ≤ 1 All goals completed! 🐙Exercise 4.2.6
theorem Rat.mul_lt_mul_right_of_neg (x y z:Rat) (hxy: x < y) (hz: z.isNeg) : x * z > y * z := x:Raty:Ratz:Rathxy:x < yhz:z.isNeg⊢ x * z > y * z
All goals completed! 🐙Not in textbook: create an equivalence between Rat and ℚ. This requires some familiarity with the API for Mathlib's version of the rationals.
abbrev Rat.equivRat : Rat ≃ ℚ where
toFun := Quotient.lift (fun ⟨ a, b, h ⟩ ↦ a / b) (⊢ ∀ (a b : PreRat),
a ≈ b →
(fun x =>
match x with
| { numerator := a, denominator := b, nonzero := h } => ↑a / ↑b)
a =
(fun x =>
match x with
| { numerator := a, denominator := b, nonzero := h } => ↑a / ↑b)
b
All goals completed! 🐙)
invFun := fun n: ℚ ↦ (n:Rat)
left_inv n := sorry
right_inv n := sorryNot in textbook: equivalence preserves order
abbrev Rat.equivRat_order : Rat ≃o ℚ where
toEquiv := equivRat
map_rel_iff' := ⊢ ∀ {a b : Rat}, equivRat a ≤ equivRat b ↔ a ≤ b All goals completed! 🐙Not in textbook: equivalence preserves ring operations
abbrev Rat.equivRat_ring : Rat ≃+* ℚ where
toEquiv := equivRat
map_add' := ⊢ ∀ (x y : Rat), equivRat.toFun (x + y) = equivRat.toFun x + equivRat.toFun y All goals completed! 🐙
map_mul' := ⊢ ∀ (x y : Rat), equivRat.toFun (x * y) = equivRat.toFun x * equivRat.toFun y All goals completed! 🐙(Not from textbook) The textbook rationals are isomorphic (as a field) to the Mathlib rationals.
def Rat.equivRat_ring_symm : ℚ ≃+* Rat := Rat.equivRat_ring.symmend Section_4_2