The rationals

Аналіз I, Розділ 4.2: Раціональні числа

Цей файл є перекладом розділу 4.2 книги Analysis I на Lean 4. Уся нумерація відповідає оригінальному тексту.

Я (пр.перекл. Терренс Тао) намагався зробити переклад якомога точнішим перефразуванням оригінального тексту. Коли є вибір між більш ідіоматичним рішенням Lean та більш точним перекладом, я зазвичай обирав останній. Зокрема, будуть місця, де код Lean можна було б "підбуцнути", щоб зробити його більш елегантним та ідіоматичним, але я свідомо уникав цього вибору.

Основні побудови та результати цього розділу:

  • Визначення раціональних чисел «Розділу 4.2» Section_4_2.Rat : TypeSection_4_2.Rat як формальних часток Unknown identifier `a`sorry // sorry : Section_4_2.Rata // Unknown identifier `b`b цілих чисел , з точністю до еквівалентності. (Це фактортип допоміжного типу Section_4_2.PreRat : TypeSection_4_2.PreRat, який складається з формальних часток без накладеної еквівалентності.)

  • Операції поля та порядок на цих раціональних числах, а також вкладення ℕ і ℤ.

  • Еквівалентність із раціональними числами Mathlib Rat : Type_root_.Rat (або : Type), які ми надалі використовуватимемо.

Примітка: тут (і надалі) ми використовуємо натуральні числа : Type та цілі числа : Type із Mathlib, а не натуральні числа розділу 2 та цілі числа розділу 4.1.

Підказки від попередніх користувачів

Користувачі супровідного матеріалу, які виконали вправи в цьому розділі, можуть надсилати свої поради майбутнім користувачам цього розділу як PRи.

  • (Додайте підказку тут)

namespace Section_4_2structure PreRat where numerator : denominator : nonzero : denominator 0

Вправа 4.2.1

instance declaration uses 'sorry'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.instSetoid

Ми надаємо діленню «сміттєве» значення 0//1, якщо знаменник дорівнює нулю

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 01 0 All goals completed! 🐙 )
infix:100 " // " => Rat.formalDiv

Визначення 4.2.1 (Раціональні числа)

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 0a // b = c // d a * d = c * b All goals completed! 🐙

Визначення 4.2.1 (Раціональні числа)

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! 🐙

Розв’язність рівності. Підказка: змініть доведення DecidableEq : TypeDecidableEq Int із попереднього розділу. Однак, оскільки формальне ділення окремо обробляє випадок нульового знаменника, може бути зручніше уникати цієї операції та працювати безпосередньо з API Quotient.{u} {α : Sort u} (s : Setoid α) : Sort uQuotient.

instance declaration uses 'sorry'Rat.decidableEq : DecidableEq Rat := DecidableEq Rat All goals completed! 🐙

Лема 4.2.3 (Додавання коректно визначене)

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' * da * 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' * da' * b * d * d' + b * b' * (c' * d) = (a' * d' + b' * c') * (b * d) All goals completed! 🐙 )

Визначення 4.2.2 (Додавання раціональних чисел)

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 0a // b + c // d = (a * d + b * c) // (b * d) a:c:b:d:hb:b 0hd:d 0a = (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 0d = (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 0b = (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 0c = (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 0b = (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 0d = (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 0a = (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 0d = (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 0b = (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 0c = (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 0b = (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 0d = (if h : d 0 then { numerator := c, denominator := d, nonzero := h } else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominator All goals completed! 🐙

Лема 4.2.3 (Множення коректно визначене)

instance declaration uses 'sorry'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! 🐙)

Визначення 4.2.2 (Множення раціональних чисел)

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 0a // b * c // d = (a * c) // (b * d) a:c:b:d:hb:b 0hd:d 0a = (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 0c = (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 0b = (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 0d = (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 0a = (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 0c = (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 0b = (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 0d = (if h : d 0 then { numerator := c, denominator := d, nonzero := h } else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominator All goals completed! 🐙

Лема 4.2.3 (Протилежний елемент коректно визначени)

instance declaration uses 'sorry'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! 🐙)

Визначення 4.2.2 (Протилежний елемент раціональних чисел)

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 0a = (if h : b 0 then { numerator := a, denominator := b, nonzero := h } else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:b:hb:b 0b = (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 0a = (if h : b 0 then { numerator := a, denominator := b, nonzero := h } else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).numeratora:b:hb:b 0b = (if h : b 0 then { numerator := a, denominator := b, nonzero := h } else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominator All goals completed! 🐙

Вкладення цілих чисел у раціональні числа

instance Rat.instIntCast : IntCast Rat where intCast a := a // 1
instance 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 := rfl

natCast розподіляється на наступника

theorem declaration uses 'sorry'Rat.natCast_succ (n: ) : ((n + 1: ): Rat) = (n: Rat) + 1 := n:(n + 1) = n + 1 All goals completed! 🐙

intCast розподіляється на додавання

lemma declaration uses 'sorry'Rat.intCast_add (a b:) : (a:Rat) + (b:Rat) = (a+b:) := a:b:a + b = (a + b) All goals completed! 🐙

intCast розподіляється на множення

lemma declaration uses 'sorry'Rat.intCast_mul (a b:) : (a:Rat) * (b:Rat) = (a*b:) := a:b:a * b = (a * b) All goals completed! 🐙

intCast комутує з взяттям протилежного елемента

lemma Rat.intCast_neg (a:) : - (a:Rat) = (-a:) := rfl
theorem declaration uses 'sorry'Rat.coe_Int_inj : Function.Injective (fun n: (n:Rat)) := Function.Injective fun n => n All goals completed! 🐙

У той час як у книзі обернене число для 0 залишається невизначеним, у Lean зручніше призначити цьому оберненому числу «сміттєве» значення; ми довільно обираємо це сміттєве значення рівним 0.

instance declaration uses 'sorry'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! 🐙 -- підказка: розділіть на випадки `a = 0` та `a ≠ 0` )
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 0b = (if h : b 0 then { numerator := a, denominator := b, nonzero := h } else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:b:hb:b 0a = (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 0b = (if h : b 0 then { numerator := a, denominator := b, nonzero := h } else { numerator := 0, denominator := 1, nonzero := formalDiv._proof_1 }).denominatora:b:hb:b 0a = (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 := rfl

Твердження 4.2.4 (закони алгебри) / Вправа 4.2.3

instance declaration uses 'sorry'declaration uses 'sorry'Rat.addGroup_inst : AddGroup Rat := AddGroup.ofLeftAxioms ( (a b c : Rat), a + b + c = a + (b + c) -- цей доказ написан так, щоб співпадати із структурою орігінального тексту. x:Raty:Ratz:Ratx + y + z = x + (y + z) y:Ratz:Rata:b:hb:b 0a // b + y + z = a // b + (y + z) z:Rata:b:hb:b 0c:d:hd:d 0a // b + c // d + z = a // b + (c // d + z) a:b:hb:b 0c:d:hd:d 0e:f:hf:f 0a // 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.38672a // b + c // d + e // f = a // b + (c // d + e // f) -- тут також можна використати `observe hbd : b*d ≠ 0` 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.38744a // b + c // d + e // f = a // b + (c // d + e // f) -- тут також можна використати `observe hdf : d*f ≠ 0` 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.38744a // b + c // d + e // f = a // b + (c // d + e // f) -- тут також можна використати `observe hbdf : b*d*f ≠ 0` 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! 🐙)

Твердження 4.2.4 (закони алгебри) / Вправа 4.2.3

instance declaration uses 'sorry'Rat.instAddCommGroup : AddCommGroup Rat where add_comm := (a b : Rat), a + b = b + a All goals completed! 🐙

Твердження 4.2.4 (закони алгебри) / Вправа 4.2.3

instance declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'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! 🐙

Твердження 4.2.4 (закони алгебри) / Вправа 4.2.3

instance declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'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! 🐙 -- Зазвичай `CommRing` згенерує екземпляр `natCast` та доведення для цього. -- Однак ми використовуємо власний `natCast`, для якого `natCast_succ` не можна -- автоматично довести за допомогою `rfl`. На щастя, ми вже це довели. natCast_succ := natCast_succ
instance Rat.instRatCast : RatCast Rat where ratCast q := q.num // q.dentheorem declaration uses 'sorry'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.43388q = 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.43808num // 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.43808num * 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.43808num * 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.43551num * 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 * dennum * 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.43551den 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.43551b 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.43551den 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.43551b 0 All goals completed! 🐙

Default definition of division

instance Rat.instDivInvMonoid : DivInvMonoid Rat where
theorem Rat.div_eq (q r:Rat) : q/r = q * r⁻¹ := q:Ratr:Ratq / r = q * r⁻¹ All goals completed! 🐙

Твердження 4.2.4 (закони алгебри) / Вправа 4.2.3

instance declaration uses 'sorry'declaration uses 'sorry'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.48005num / 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.48005num * 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.480051 * 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.48005den 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.480051 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.48005den 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.480051 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.48005num * 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.480051 * 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.48005den 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.480051 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.48005den 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.480051 0 All goals completed! 🐙 qsmul := _ nnqsmul := _
declaration uses 'sorry'example : (3//4) / (5//6) = 9 // 10 := 3 // 4 / 5 // 6 = 9 // 10 All goals completed! 🐙

Визначення віднімання

theorem Rat.sub_eq (a b:Rat) : a - b = a + (-b) := a:Ratb:Rata - b = a + -b All goals completed! 🐙
def declaration uses 'sorry'declaration uses 'sorry'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! 🐙

Визначення 4.2.6 (позитивність)

def Rat.isPos (q:Rat) : Prop := a b:, a > 0 b > 0 q = a/b

Визначення 4.2.6 (негативність)

def Rat.isNeg (q:Rat) : Prop := r:Rat, r.isPos q = -r

Лема 4.2.7 (трихотомія раціональних чисел) / Вправа 4.2.4

theorem declaration uses 'sorry'Rat.trichotomous (x:Rat) : x = 0 x.isPos x.isNeg := x:Ratx = 0 x.isPos x.isNeg All goals completed! 🐙

Лема 4.2.7 (трихотомія раціональних чисел) / Вправа 4.2.4

theorem declaration uses 'sorry'Rat.not_zero_and_pos (x:Rat) : ¬(x = 0 x.isPos) := x:Rat¬(x = 0 x.isPos) All goals completed! 🐙

Лема 4.2.7 (трихотомія раціональних чисел) / Вправа 4.2.4

theorem declaration uses 'sorry'Rat.not_zero_and_neg (x:Rat) : ¬(x = 0 x.isNeg) := x:Rat¬(x = 0 x.isNeg) All goals completed! 🐙

Лема 4.2.7 (трихотомія раціональних чисел) / Вправа 4.2.4

theorem declaration uses 'sorry'Rat.not_pos_and_neg (x:Rat) : ¬(x.isPos x.isNeg) := x:Rat¬(x.isPos x.isNeg) All goals completed! 🐙

Визначення 4.2.8 (Порядок раціональних чисел)

instance Rat.instLT : LT Rat where lt x y := (x-y).isNeg

Визначення 4.2.8 (Порядок раціональних чисел)

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:Ratx < y (x - y).isNeg All goals completed! 🐙theorem Rat.le_iff (x y:Rat) : x y (x < y) (x = y) := x:Raty:Ratx y x < y x = y All goals completed! 🐙theorem declaration uses 'sorry'Rat.gt_iff (x y:Rat) : x > y (x-y).isPos := x:Raty:Ratx > y (x - y).isPos All goals completed! 🐙theorem declaration uses 'sorry'Rat.ge_iff (x y:Rat) : x y (x > y) (x = y) := x:Raty:Ratx y x > y x = y All goals completed! 🐙

Твердження 4.2.9(a) (трихотомія порядку) / Вправа 4.2.5

theorem declaration uses 'sorry'Rat.trichotomous' (x y:Rat) : x > y x < y x = y := x:Raty:Ratx > y x < y x = y All goals completed! 🐙

Твердження 4.2.9(a) (трихотомія порядку) / Вправа 4.2.5

theorem declaration uses 'sorry'Rat.not_gt_and_lt (x y:Rat) : ¬ (x > y x < y):= x:Raty:Rat¬(x > y x < y) All goals completed! 🐙

Твердження 4.2.9(a) (трихотомія порядку) / Вправа 4.2.5

theorem declaration uses 'sorry'Rat.not_gt_and_eq (x y:Rat) : ¬ (x > y x = y):= x:Raty:Rat¬(x > y x = y) All goals completed! 🐙

Твердження 4.2.9(a) (трихотомія порядку) / Вправа 4.2.5

theorem declaration uses 'sorry'Rat.not_lt_and_eq (x y:Rat) : ¬ (x < y x = y):= x:Raty:Rat¬(x < y x = y) All goals completed! 🐙

Твердження 4.2.9(b) (порядок є антисиметричним) / Вправа 4.2.5

theorem declaration uses 'sorry'Rat.antisymm (x y:Rat) : x < y y > x := x:Raty:Ratx < y y > x All goals completed! 🐙

Твердження 4.2.9(c) (порядок є транзитивним) / Вправа 4.2.5

theorem declaration uses 'sorry'Rat.lt_trans {x y z:Rat} (hxy: x < y) (hyz: y < z) : x < z := x:Raty:Ratz:Rathxy:x < yhyz:y < zx < z All goals completed! 🐙

Твердження 4.2.9(d) (додавання зберігає порядок) / Вправа 4.2.5

theorem declaration uses 'sorry'Rat.add_lt_add_right {x y:Rat} (z:Rat) (hxy: x < y) : x + z < y + z := x:Raty:Ratz:Rathxy:x < yx + z < y + z All goals completed! 🐙

Твердження 4.2.9(e) (множення на додатне число зберігає порядок) / Вправа 4.2.5

theorem declaration uses 'sorry'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.isPosx * z < y * z All goals completed! 🐙

(Не в підручнику) Встановіть розв’язність цього порядку.

instance declaration uses 'sorry'declaration uses 'sorry'Rat.decidableRel : DecidableRel (· ·: Rat Rat Prop) := DecidableRel fun x1 x2 => x1 x2 n:Ratm:RatDecidable ((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 0Decidable ({ numerator := a, denominator := b, nonzero := hb } { numerator := c, denominator := d, nonzero := hd }) -- на цьому етапі ціль фактично `Decidable(a//b ≤ c//d)`, але існують технічні -- проблеми через «сміттєве» значення формального ділення, коли знаменник дорівнює нулю. -- Може бути зручніше уникати формального ділення та працювати безпосередньо з `Quotient.mk`. cases (0:).decLe (b*d) with n:Ratm:Rata:b:hb:b 0c:d:hd:d 0hbd:0 b * dDecidable ({ 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 * cDecidable ({ 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 * cDecidable ({ 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 * dDecidable ({ 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 * dDecidable ({ 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 * dDecidable ({ 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! 🐙

(Не в підручнику) Раціональні числа мають структуру лінійного порядку.

instance declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'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

(Не в підручнику) Раціональні числа мають структуру строго впорядкованого кільця.

instance declaration uses 'sorry'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! 🐙

Вправа 4.2.6

theorem declaration uses 'sorry'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.isNegx * z > y * z All goals completed! 🐙

Не в підручнику: створіть еквівалентність між Section_4_2.Rat : TypeRat та : Type. Це вимагає певного знайомства з API для версії раціональних чисел у Mathlib.

abbrev declaration uses 'sorry'declaration uses 'sorry'declaration uses 'sorry'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 := sorry

Не в підручнику: еквівалентність зберігає порядок

abbrev declaration uses 'sorry'Rat.equivRat_order : Rat ≃o where toEquiv := equivRat map_rel_iff' := {a b : Rat}, equivRat a equivRat b a b All goals completed! 🐙

Не в підручнику: еквівалентність зберігає операції кільця

abbrev declaration uses 'sorry'declaration uses 'sorry'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! 🐙

(Не в підручнику) Раціональні числа з підручника ізоморфні (як поле) до раціональних чисел Mathlib.

def Rat.equivRat_ring_symm : ≃+* Rat := Rat.equivRat_ring.symm
end Section_4_2