/- Copyright (c) 2014 Robert Lewis. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Robert Lewis, Leonardo de Moura Structures with multiplicative and additive components, including division rings and fields. The development is modeled after Isabelle's library. -/ prelude import init.algebra.ring universe u /- Make sure instances defined in this file have lower priority than the ones defined for concrete structures -/ set_option default_priority 100 class division_ring (α : Type u) extends ring α, has_inv α, zero_ne_one_class α := (mul_inv_cancel : ∀ {a : α}, a ≠ 0 → a * a⁻¹ = 1) (inv_mul_cancel : ∀ {a : α}, a ≠ 0 → a⁻¹ * a = 1) variable {α : Type u} section division_ring variables [division_ring α] protected definition algebra.div (a b : α) : α := a * b⁻¹ instance division_ring_has_div [division_ring α] : has_div α := ⟨algebra.div⟩ lemma division_def (a b : α) : a / b = a * b⁻¹ := rfl @[simp] lemma mul_inv_cancel {a : α} (h : a ≠ 0) : a * a⁻¹ = 1 := division_ring.mul_inv_cancel h @[simp] lemma inv_mul_cancel {a : α} (h : a ≠ 0) : a⁻¹ * a = 1 := division_ring.inv_mul_cancel h @[simp] lemma one_div_eq_inv (a : α) : 1 / a = a⁻¹ := one_mul a⁻¹ lemma inv_eq_one_div (a : α) : a⁻¹ = 1 / a := by simp local attribute [simp] division_def mul_comm mul_assoc mul_left_comm mul_inv_cancel inv_mul_cancel lemma div_eq_mul_one_div (a b : α) : a / b = a * (1 / b) := by simp lemma mul_one_div_cancel {a : α} (h : a ≠ 0) : a * (1 / a) = 1 := by simp [h] lemma one_div_mul_cancel {a : α} (h : a ≠ 0) : (1 / a) * a = 1 := by simp [h] lemma div_self {a : α} (h : a ≠ 0) : a / a = 1 := by simp [h] lemma one_div_one : 1 / 1 = (1:α) := div_self (ne.symm zero_ne_one) lemma mul_div_assoc (a b c : α) : (a * b) / c = a * (b / c) := by simp lemma one_div_ne_zero {a : α} (h : a ≠ 0) : 1 / a ≠ 0 := suppose 1 / a = 0, have 0 = (1:α), from eq.symm (by rw [-(mul_one_div_cancel h), this, mul_zero]), absurd this zero_ne_one lemma one_inv_eq : 1⁻¹ = (1:α) := suffices 1 * 1⁻¹ = (1:α), begin simp at this, assumption end, mul_inv_cancel (ne.symm (@zero_ne_one α _)) local attribute [simp] one_inv_eq lemma div_one (a : α) : a / 1 = a := by simp lemma zero_div (a : α) : 0 / a = 0 := by simp -- note: integral domain has a "mul_ne_zero". α commutative division ring is an integral -- domain, but let's not define that class for now. lemma division_ring.mul_ne_zero {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) : a * b ≠ 0 := suppose a * b = 0, have a * 1 = 0, by rw [-(mul_one_div_cancel hb), -mul_assoc, this, zero_mul], have a = 0, by rwa mul_one at this, absurd this ha lemma mul_ne_zero_comm {a b : α} (h : a * b ≠ 0) : b * a ≠ 0 := have h₁ : a ≠ 0, from ne_zero_of_mul_ne_zero_right h, have h₂ : b ≠ 0, from ne_zero_of_mul_ne_zero_left h, division_ring.mul_ne_zero h₂ h₁ lemma eq_one_div_of_mul_eq_one {a b : α} (h : a * b = 1) : b = 1 / a := have a ≠ 0, from suppose a = 0, have 0 = (1:α), by rwa [this, zero_mul] at h, absurd this zero_ne_one, have b = (1 / a) * a * b, by rw [one_div_mul_cancel this, one_mul], show b = 1 / a, by rwa [mul_assoc, h, mul_one] at this lemma eq_one_div_of_mul_eq_one_left {a b : α} (h : b * a = 1) : b = 1 / a := have a ≠ 0, from suppose a = 0, have 0 = (1:α), by rwa [this, mul_zero] at h, absurd this zero_ne_one, by rw [-h, mul_div_assoc, div_self this, mul_one] lemma division_ring.one_div_mul_one_div {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) : (1 / a) * (1 / b) = 1 / (b * a) := have (b * a) * ((1 / a) * (1 / b)) = 1, by rw [mul_assoc, -(mul_assoc a), mul_one_div_cancel ha, one_mul, mul_one_div_cancel hb], eq_one_div_of_mul_eq_one this lemma one_div_neg_one_eq_neg_one : (1:α) / (-1) = -1 := have (-1) * (-1) = (1:α), by rw [neg_mul_neg, one_mul], eq.symm (eq_one_div_of_mul_eq_one this) lemma division_ring.one_div_neg_eq_neg_one_div {a : α} (h : a ≠ 0) : 1 / (- a) = - (1 / a) := have -1 ≠ (0:α), from (suppose -1 = 0, absurd (eq.symm (calc 1 = -(-1) : (neg_neg (1:α))^.symm ... = -0 : by rw this ... = (0:α) : neg_zero)) zero_ne_one), calc 1 / (- a) = 1 / ((-1) * a) : by rw neg_eq_neg_one_mul ... = (1 / a) * (1 / (- 1)) : by rw (division_ring.one_div_mul_one_div h this) ... = (1 / a) * (-1) : by rw one_div_neg_one_eq_neg_one ... = - (1 / a) : by rw [mul_neg_eq_neg_mul_symm, mul_one] lemma div_neg_eq_neg_div {a : α} (b : α) (ha : a ≠ 0) : b / (- a) = - (b / a) := calc b / (- a) = b * (1 / (- a)) : by rw [-inv_eq_one_div, division_def] ... = b * -(1 / a) : by rw (division_ring.one_div_neg_eq_neg_one_div ha) ... = -(b * (1 / a)) : by rw neg_mul_eq_mul_neg ... = - (b * a⁻¹) : by rw inv_eq_one_div lemma neg_div (a b : α) : (-b) / a = - (b / a) := by rw [neg_eq_neg_one_mul, mul_div_assoc, -neg_eq_neg_one_mul] lemma division_ring.neg_div_neg_eq (a : α) {b : α} (hb : b ≠ 0) : (-a) / (-b) = a / b := by rw [(div_neg_eq_neg_div _ hb), neg_div, neg_neg] lemma division_ring.one_div_one_div {a : α} (h : a ≠ 0) : 1 / (1 / a) = a := eq.symm (eq_one_div_of_mul_eq_one_left (mul_one_div_cancel h)) lemma division_ring.eq_of_one_div_eq_one_div {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) (h : 1 / a = 1 / b) : a = b := by rw [-(division_ring.one_div_one_div ha), h, (division_ring.one_div_one_div hb)] lemma mul_inv_eq {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) : (b * a)⁻¹ = a⁻¹ * b⁻¹ := eq.symm $ calc a⁻¹ * b⁻¹ = (1 / a) * (1 / b) : by simp ... = (1 / (b * a)) : division_ring.one_div_mul_one_div ha hb ... = (b * a)⁻¹ : by simp lemma mul_div_cancel (a : α) {b : α} (hb : b ≠ 0) : a * b / b = a := by simp [hb] lemma div_mul_cancel (a : α) {b : α} (hb : b ≠ 0) : a / b * b = a := by simp [hb] lemma div_add_div_same (a b c : α) : a / c + b / c = (a + b) / c := eq.symm $ right_distrib a b (c⁻¹) lemma div_sub_div_same (a b c : α) : (a / c) - (b / c) = (a - b) / c := by rw [sub_eq_add_neg, -neg_div, div_add_div_same, sub_eq_add_neg] lemma one_div_mul_add_mul_one_div_eq_one_div_add_one_div {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) : (1 / a) * (a + b) * (1 / b) = 1 / a + 1 / b := by rw [(left_distrib (1 / a)), (one_div_mul_cancel ha), right_distrib, one_mul, mul_assoc, (mul_one_div_cancel hb), mul_one, add_comm] lemma one_div_mul_sub_mul_one_div_eq_one_div_add_one_div {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) : (1 / a) * (b - a) * (1 / b) = 1 / a - 1 / b := by rw [(mul_sub_left_distrib (1 / a)), (one_div_mul_cancel ha), mul_sub_right_distrib, one_mul, mul_assoc, (mul_one_div_cancel hb), mul_one] lemma div_eq_one_iff_eq (a : α) {b : α} (hb : b ≠ 0) : a / b = 1 ↔ a = b := iff.intro (suppose a / b = 1, calc a = a / b * b : by simp [hb] ... = 1 * b : by rw this ... = b : by simp) (suppose a = b, by simp [this, hb]) lemma eq_of_div_eq_one (a : α) {b : α} (Hb : b ≠ 0) : a / b = 1 → a = b := iff.mp $ div_eq_one_iff_eq a Hb lemma eq_div_iff_mul_eq (a b : α) {c : α} (hc : c ≠ 0) : a = b / c ↔ a * c = b := iff.intro (suppose a = b / c, by rw [this, (div_mul_cancel _ hc)]) (suppose a * c = b, by rw [-this, mul_div_cancel _ hc]) lemma eq_div_of_mul_eq (a b : α) {c : α} (hc : c ≠ 0) : a * c = b → a = b / c := iff.mpr $ eq_div_iff_mul_eq a b hc lemma mul_eq_of_eq_div (a b: α) {c : α} (hc : c ≠ 0) : a = b / c → a * c = b := iff.mp $ eq_div_iff_mul_eq a b hc lemma add_div_eq_mul_add_div (a b : α) {c : α} (hc : c ≠ 0) : a + b / c = (a * c + b) / c := have (a + b / c) * c = a * c + b, by rw [right_distrib, (div_mul_cancel _ hc)], (iff.mpr (eq_div_iff_mul_eq _ _ hc)) this lemma mul_mul_div (a : α) {c : α} (hc : c ≠ 0) : a = a * c * (1 / c) := by simp [hc] end division_ring class field (α : Type u) extends division_ring α, comm_ring α section field variable [field α] lemma field.one_div_mul_one_div {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) : (1 / a) * (1 / b) = 1 / (a * b) := by rw [(division_ring.one_div_mul_one_div ha hb), mul_comm b] lemma field.div_mul_right {a b : α} (hb : b ≠ 0) (h : a * b ≠ 0) : a / (a * b) = 1 / b := have a ≠ 0, from ne_zero_of_mul_ne_zero_right h, eq.symm (calc 1 / b = a * ((1 / a) * (1 / b)) : by rw [-mul_assoc, mul_one_div_cancel this, one_mul] ... = a * (1 / (b * a)) : by rw (division_ring.one_div_mul_one_div this hb) ... = a * (a * b)⁻¹ : by rw [inv_eq_one_div, mul_comm a b]) lemma field.div_mul_left {a b : α} (ha : a ≠ 0) (h : a * b ≠ 0) : b / (a * b) = 1 / a := have b * a ≠ 0, from mul_ne_zero_comm h, by rw [mul_comm a, (field.div_mul_right ha this)] lemma mul_div_cancel_left {a : α} (b : α) (ha : a ≠ 0) : a * b / a = b := by rw [mul_comm a, (mul_div_cancel _ ha)] lemma mul_div_cancel' (a : α) {b : α} (hb : b ≠ 0) : b * (a / b) = a := by rw [mul_comm, (div_mul_cancel _ hb)] lemma one_div_add_one_div {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) : 1 / a + 1 / b = (a + b) / (a * b) := have a * b ≠ 0, from (division_ring.mul_ne_zero ha hb), by rw [add_comm, -(field.div_mul_left ha this), -(field.div_mul_right hb this), division_def, division_def, division_def, -right_distrib] lemma field.div_mul_div (a : α) {b : α} (c : α) {d : α} (hb : b ≠ 0) (hd : d ≠ 0) : (a / b) * (c / d) = (a * c) / (b * d) := begin simp [division_def], rw [mul_inv_eq hd hb, mul_comm d⁻¹] end lemma mul_div_mul_left (a : α) {b c : α} (hb : b ≠ 0) (hc : c ≠ 0) : (c * a) / (c * b) = a / b := by rw [-(field.div_mul_div _ _ hc hb), div_self hc, one_mul] lemma mul_div_mul_right (a : α) {b c : α} (hb : b ≠ 0) (hc : c ≠ 0) : (a * c) / (b * c) = a / b := by rw [mul_comm a, mul_comm b, mul_div_mul_left _ hb hc] lemma div_mul_eq_mul_div (a b c : α) : (b / c) * a = (b * a) / c := by simp [division_def] lemma field.div_mul_eq_mul_div_comm (a b : α) {c : α} (hc : c ≠ 0) : (b / c) * a = b * (a / c) := by rw [div_mul_eq_mul_div, -(one_mul c), -(field.div_mul_div _ _ (ne.symm zero_ne_one) hc), div_one, one_mul] lemma div_add_div (a : α) {b : α} (c : α) {d : α} (hb : b ≠ 0) (hd : d ≠ 0) : (a / b) + (c / d) = ((a * d) + (b * c)) / (b * d) := by rw [-(mul_div_mul_right _ hb hd), -(mul_div_mul_left _ hd hb), div_add_div_same] lemma div_sub_div (a : α) {b : α} (c : α) {d : α} (hb : b ≠ 0) (hd : d ≠ 0) : (a / b) - (c / d) = ((a * d) - (b * c)) / (b * d) := begin simp [sub_eq_add_neg], rw [neg_eq_neg_one_mul, -mul_div_assoc, div_add_div _ _ hb hd, -mul_assoc, mul_comm b, mul_assoc, -neg_eq_neg_one_mul] end lemma mul_eq_mul_of_div_eq_div (a : α) {b : α} (c : α) {d : α} (hb : b ≠ 0) (hd : d ≠ 0) (h : a / b = c / d) : a * d = c * b := by rw [-(mul_one (a*d)), mul_assoc, (mul_comm d), -mul_assoc, -(div_self hb), -(field.div_mul_eq_mul_div_comm _ _ hb), h, div_mul_eq_mul_div, div_mul_cancel _ hd] lemma field.one_div_div {a b : α} (ha : a ≠ 0) (hb : b ≠ 0) : 1 / (a / b) = b / a := have (a / b) * (b / a) = 1, from calc (a / b) * (b / a) = (a * b) / (b * a) : field.div_mul_div _ _ hb ha ... = (a * b) / (a * b) : by rw mul_comm ... = 1 : div_self (division_ring.mul_ne_zero ha hb), eq.symm (eq_one_div_of_mul_eq_one this) lemma field.div_div_eq_mul_div (a : α) {b c : α} (hb : b ≠ 0) (hc : c ≠ 0) : a / (b / c) = (a * c) / b := by rw [div_eq_mul_one_div, field.one_div_div hb hc, -mul_div_assoc] lemma field.div_div_eq_div_mul (a : α) {b c : α} (hb : b ≠ 0) (hc : c ≠ 0) : (a / b) / c = a / (b * c) := by rw [div_eq_mul_one_div, field.div_mul_div _ _ hb hc, mul_one] lemma field.div_div_div_div_eq (a : α) {b c d : α} (hb : b ≠ 0) (hc : c ≠ 0) (hd : d ≠ 0) : (a / b) / (c / d) = (a * d) / (b * c) := by rw [field.div_div_eq_mul_div _ hc hd, div_mul_eq_mul_div, field.div_div_eq_div_mul _ hb hc] lemma field.div_mul_eq_div_mul_one_div (a : α) {b c : α} (hb : b ≠ 0) (hc : c ≠ 0) : a / (b * c) = (a / b) * (1 / c) := by rw [-(field.div_div_eq_div_mul _ hb hc), -div_eq_mul_one_div] lemma eq_of_mul_eq_mul_of_nonzero_left {a b c : α} (h : a ≠ 0) (h₂ : a * b = a * c) : b = c := by rw [-one_mul b, -div_self h, div_mul_eq_mul_div, h₂, mul_div_cancel_left _ h] lemma eq_of_mul_eq_mul_of_nonzero_right {a b c : α} (h : c ≠ 0) (h2 : a * c = b * c) : a = b := by rw [-mul_one a, -div_self h, -mul_div_assoc, h2, mul_div_cancel _ h] end field class discrete_field (α : Type u) extends field α := (has_decidable_eq : decidable_eq α) (inv_zero : inv zero = zero) attribute [instance] discrete_field.has_decidable_eq section discrete_field variable [discrete_field α] -- many of the lemmas in discrete_field are the same as lemmas in field or division ring, -- but with fewer hypotheses since 0⁻¹ = 0 and equality is decidable. lemma discrete_field.eq_zero_or_eq_zero_of_mul_eq_zero (a b : α) (h : a * b = 0) : a = 0 ∨ b = 0 := decidable.by_cases (suppose a = 0, or.inl this) (suppose a ≠ 0, or.inr (by rw [-(one_mul b), -(inv_mul_cancel this), mul_assoc, h, mul_zero])) instance discrete_field.to_integral_domain [s : discrete_field α] : integral_domain α := {s with eq_zero_or_eq_zero_of_mul_eq_zero := discrete_field.eq_zero_or_eq_zero_of_mul_eq_zero} lemma inv_zero : 0⁻¹ = (0:α) := discrete_field.inv_zero α lemma one_div_zero : 1 / 0 = (0:α) := calc 1 / 0 = (1:α) * 0⁻¹ : by rw division_def ... = 1 * 0 : by rw inv_zero ... = (0:α) : by rw mul_zero lemma div_zero (a : α) : a / 0 = 0 := by rw [div_eq_mul_one_div, one_div_zero, mul_zero] lemma ne_zero_of_one_div_ne_zero {a : α} (h : 1 / a ≠ 0) : a ≠ 0 := assume ha : a = 0, begin rw [ha, one_div_zero] at h, contradiction end lemma eq_zero_of_one_div_eq_zero {a : α} (h : 1 / a = 0) : a = 0 := decidable.by_cases (assume ha, ha) (assume ha, false.elim ((one_div_ne_zero ha) h)) lemma one_div_mul_one_div' (a b : α) : (1 / a) * (1 / b) = 1 / (b * a) := decidable.by_cases (suppose a = 0, by rw [this, div_zero, zero_mul, mul_zero, div_zero]) (assume ha : a ≠ 0, decidable.by_cases (suppose b = 0, by rw [this, div_zero, mul_zero, zero_mul, div_zero]) (suppose b ≠ 0, division_ring.one_div_mul_one_div ha this)) lemma one_div_neg_eq_neg_one_div (a : α) : 1 / (- a) = - (1 / a) := decidable.by_cases (suppose a = 0, by rw [this, neg_zero, div_zero, neg_zero]) (suppose a ≠ 0, division_ring.one_div_neg_eq_neg_one_div this) lemma neg_div_neg_eq (a b : α) : (-a) / (-b) = a / b := decidable.by_cases (assume hb : b = 0, by rw [hb, neg_zero, div_zero, div_zero]) (assume hb : b ≠ 0, division_ring.neg_div_neg_eq _ hb) lemma one_div_one_div (a : α) : 1 / (1 / a) = a := decidable.by_cases (assume ha : a = 0, by rw [ha, div_zero, div_zero]) (assume ha : a ≠ 0, division_ring.one_div_one_div ha) lemma eq_of_one_div_eq_one_div {a b : α} (h : 1 / a = 1 / b) : a = b := decidable.by_cases (assume ha : a = 0, have hb : b = 0, from eq_zero_of_one_div_eq_zero (by rw [-h, ha, div_zero]), hb^.symm ▸ ha) (assume ha : a ≠ 0, have hb : b ≠ 0, from ne_zero_of_one_div_ne_zero (h ▸ (one_div_ne_zero ha)), division_ring.eq_of_one_div_eq_one_div ha hb h) lemma mul_inv' (a b : α) : (b * a)⁻¹ = a⁻¹ * b⁻¹ := decidable.by_cases (assume ha : a = 0, by rw [ha, mul_zero, inv_zero, zero_mul]) (assume ha : a ≠ 0, decidable.by_cases (assume hb : b = 0, by rw [hb, zero_mul, inv_zero, mul_zero]) (assume hb : b ≠ 0, mul_inv_eq ha hb)) -- the following are specifically for fields lemma one_div_mul_one_div (a b : α) : (1 / a) * (1 / b) = 1 / (a * b) := by rw [one_div_mul_one_div', mul_comm b] lemma div_mul_right {a : α} (b : α) (ha : a ≠ 0) : a / (a * b) = 1 / b := decidable.by_cases (assume hb : b = 0, by rw [hb, mul_zero, div_zero, div_zero]) (assume hb : b ≠ 0, field.div_mul_right hb (mul_ne_zero ha hb)) lemma div_mul_left (a : α) {b : α} (hb : b ≠ 0) : b / (a * b) = 1 / a := by rw [mul_comm a, div_mul_right _ hb] lemma div_mul_div (a b c d : α) : (a / b) * (c / d) = (a * c) / (b * d) := decidable.by_cases (assume hb : b = 0, by rw [hb, div_zero, zero_mul, zero_mul, div_zero]) (assume hb : b ≠ 0, decidable.by_cases (assume hd : d = 0, by rw [hd, div_zero, mul_zero, mul_zero, div_zero]) (assume hd : d ≠ 0, field.div_mul_div _ _ hb hd)) lemma mul_div_mul_left' (a b : α) {c : α} (hc : c ≠ 0) : (c * a) / (c * b) = a / b := decidable.by_cases (assume hb : b = 0, by rw [hb, mul_zero, div_zero, div_zero]) (assume hb : b ≠ 0, mul_div_mul_left _ hb hc) lemma mul_div_mul_right' (a b : α) {c : α} (hc : c ≠ 0) : (a * c) / (b * c) = a / b := by rw [mul_comm a, mul_comm b, (mul_div_mul_left' _ _ hc)] lemma div_mul_eq_mul_div_comm (a b c : α) : (b / c) * a = b * (a / c) := decidable.by_cases (assume hc : c = 0, by rw [hc, div_zero, zero_mul, div_zero, mul_zero]) (assume hc : c ≠ 0, field.div_mul_eq_mul_div_comm _ _ hc) lemma one_div_div (a b : α) : 1 / (a / b) = b / a := decidable.by_cases (assume ha : a = 0, by rw [ha, zero_div, div_zero, div_zero]) (assume ha : a ≠ 0, decidable.by_cases (assume hb : b = 0, by rw [hb, div_zero, zero_div, div_zero]) (assume hb : b ≠ 0, field.one_div_div ha hb)) lemma div_div_eq_mul_div (a b c : α) : a / (b / c) = (a * c) / b := by rw [div_eq_mul_one_div, one_div_div, -mul_div_assoc] lemma div_div_eq_div_mul (a b c : α) : (a / b) / c = a / (b * c) := by rw [div_eq_mul_one_div, div_mul_div, mul_one] lemma div_div_div_div_eq (a b c d : α) : (a / b) / (c / d) = (a * d) / (b * c) := by rw [div_div_eq_mul_div, div_mul_eq_mul_div, div_div_eq_div_mul] lemma div_helper {a : α} (b : α) (h : a ≠ 0) : (1 / (a * b)) * a = 1 / b := by rw [div_mul_eq_mul_div, one_mul, div_mul_right _ h] lemma div_mul_eq_div_mul_one_div (a b c : α) : a / (b * c) = (a / b) * (1 / c) := by rw [-div_div_eq_div_mul, -div_eq_mul_one_div] end discrete_field