a618bd7d6c
Before this commit we were using overloading for concrete structures and type classes for abstract ones. This is the first of series of commits that implement this modification
587 lines
20 KiB
Text
587 lines
20 KiB
Text
/-
|
|
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Authors: Jeremy Avigad, Leonardo de Moura
|
|
|
|
Various multiplicative and additive structures. Partially modeled on Isabelle's library.
|
|
-/
|
|
|
|
import logic.eq data.unit data.sigma data.prod
|
|
import algebra.binary algebra.priority
|
|
|
|
open eq eq.ops -- note: ⁻¹ will be overloaded
|
|
open binary
|
|
|
|
namespace algebra
|
|
|
|
variable {A : Type}
|
|
|
|
structure has_one [class] (A : Type) :=
|
|
(one : A)
|
|
|
|
structure has_zero [class] (A : Type) :=
|
|
(zero : A)
|
|
|
|
notation 1 := !has_one.one
|
|
notation 0 := !has_zero.zero
|
|
|
|
/- semigroup -/
|
|
|
|
structure semigroup [class] (A : Type) extends has_mul A :=
|
|
(mul_assoc : ∀a b c, mul (mul a b) c = mul a (mul b c))
|
|
|
|
theorem mul.assoc [s : semigroup A] (a b c : A) : a * b * c = a * (b * c) :=
|
|
!semigroup.mul_assoc
|
|
|
|
structure comm_semigroup [class] (A : Type) extends semigroup A :=
|
|
(mul_comm : ∀a b, mul a b = mul b a)
|
|
|
|
theorem mul.comm [s : comm_semigroup A] (a b : A) : a * b = b * a :=
|
|
!comm_semigroup.mul_comm
|
|
|
|
theorem mul.left_comm [s : comm_semigroup A] (a b c : A) : a * (b * c) = b * (a * c) :=
|
|
binary.left_comm (@mul.comm A s) (@mul.assoc A s) a b c
|
|
|
|
theorem mul.right_comm [s : comm_semigroup A] (a b c : A) : (a * b) * c = (a * c) * b :=
|
|
binary.right_comm (@mul.comm A s) (@mul.assoc A s) a b c
|
|
|
|
structure left_cancel_semigroup [class] (A : Type) extends semigroup A :=
|
|
(mul_left_cancel : ∀a b c, mul a b = mul a c → b = c)
|
|
|
|
theorem mul.left_cancel [s : left_cancel_semigroup A] {a b c : A} :
|
|
a * b = a * c → b = c :=
|
|
!left_cancel_semigroup.mul_left_cancel
|
|
|
|
abbreviation eq_of_mul_eq_mul_left' := @mul.left_cancel
|
|
|
|
structure right_cancel_semigroup [class] (A : Type) extends semigroup A :=
|
|
(mul_right_cancel : ∀a b c, mul a b = mul c b → a = c)
|
|
|
|
theorem mul.right_cancel [s : right_cancel_semigroup A] {a b c : A} :
|
|
a * b = c * b → a = c :=
|
|
!right_cancel_semigroup.mul_right_cancel
|
|
|
|
abbreviation eq_of_mul_eq_mul_right' := @mul.right_cancel
|
|
|
|
/- additive semigroup -/
|
|
|
|
structure add_semigroup [class] (A : Type) extends has_add A :=
|
|
(add_assoc : ∀a b c, add (add a b) c = add a (add b c))
|
|
|
|
theorem add.assoc [s : add_semigroup A] (a b c : A) : a + b + c = a + (b + c) :=
|
|
!add_semigroup.add_assoc
|
|
|
|
structure add_comm_semigroup [class] (A : Type) extends add_semigroup A :=
|
|
(add_comm : ∀a b, add a b = add b a)
|
|
|
|
theorem add.comm [s : add_comm_semigroup A] (a b : A) : a + b = b + a :=
|
|
!add_comm_semigroup.add_comm
|
|
|
|
theorem add.left_comm [s : add_comm_semigroup A] (a b c : A) :
|
|
a + (b + c) = b + (a + c) :=
|
|
binary.left_comm (@add.comm A s) (@add.assoc A s) a b c
|
|
|
|
theorem add.right_comm [s : add_comm_semigroup A] (a b c : A) : (a + b) + c = (a + c) + b :=
|
|
binary.right_comm (@add.comm A s) (@add.assoc A s) a b c
|
|
|
|
structure add_left_cancel_semigroup [class] (A : Type) extends add_semigroup A :=
|
|
(add_left_cancel : ∀a b c, add a b = add a c → b = c)
|
|
|
|
theorem add.left_cancel [s : add_left_cancel_semigroup A] {a b c : A} :
|
|
a + b = a + c → b = c :=
|
|
!add_left_cancel_semigroup.add_left_cancel
|
|
|
|
abbreviation eq_of_add_eq_add_left := @add.left_cancel
|
|
|
|
structure add_right_cancel_semigroup [class] (A : Type) extends add_semigroup A :=
|
|
(add_right_cancel : ∀a b c, add a b = add c b → a = c)
|
|
|
|
theorem add.right_cancel [s : add_right_cancel_semigroup A] {a b c : A} :
|
|
a + b = c + b → a = c :=
|
|
!add_right_cancel_semigroup.add_right_cancel
|
|
|
|
abbreviation eq_of_add_eq_add_right := @add.right_cancel
|
|
|
|
/- monoid -/
|
|
|
|
structure monoid [class] (A : Type) extends semigroup A, has_one A :=
|
|
(one_mul : ∀a, mul one a = a) (mul_one : ∀a, mul a one = a)
|
|
|
|
theorem one_mul [s : monoid A] (a : A) : 1 * a = a := !monoid.one_mul
|
|
|
|
theorem mul_one [s : monoid A] (a : A) : a * 1 = a := !monoid.mul_one
|
|
|
|
structure comm_monoid [class] (A : Type) extends monoid A, comm_semigroup A
|
|
|
|
/- additive monoid -/
|
|
|
|
structure add_monoid [class] (A : Type) extends add_semigroup A, has_zero A :=
|
|
(zero_add : ∀a, add zero a = a) (add_zero : ∀a, add a zero = a)
|
|
|
|
theorem zero_add [s : add_monoid A] (a : A) : 0 + a = a := !add_monoid.zero_add
|
|
|
|
theorem add_zero [s : add_monoid A] (a : A) : a + 0 = a := !add_monoid.add_zero
|
|
|
|
structure add_comm_monoid [class] (A : Type) extends add_monoid A, add_comm_semigroup A
|
|
|
|
definition add_monoid.to_monoid {A : Type} [s : add_monoid A] : monoid A :=
|
|
⦃ monoid,
|
|
mul := add_monoid.add,
|
|
mul_assoc := add_monoid.add_assoc,
|
|
one := add_monoid.zero A,
|
|
mul_one := add_monoid.add_zero,
|
|
one_mul := add_monoid.zero_add
|
|
⦄
|
|
|
|
definition add_comm_monoid.to_comm_monoid {A : Type} [s : add_comm_monoid A] : comm_monoid A :=
|
|
⦃ comm_monoid,
|
|
add_monoid.to_monoid,
|
|
mul_comm := add_comm_monoid.add_comm
|
|
⦄
|
|
|
|
section add_comm_monoid
|
|
|
|
theorem add_comm_three {A : Type} [s : add_comm_monoid A] (a b c : A) : a + b + c = c + b + a :=
|
|
by rewrite [{a + _}add.comm, {_ + c}add.comm, -*add.assoc]
|
|
|
|
end add_comm_monoid
|
|
|
|
/- group -/
|
|
|
|
structure group [class] (A : Type) extends monoid A, has_inv A :=
|
|
(mul_left_inv : ∀a, mul (inv a) a = one)
|
|
|
|
-- Note: with more work, we could derive the axiom one_mul
|
|
|
|
section group
|
|
|
|
variable [s : group A]
|
|
include s
|
|
|
|
theorem mul.left_inv (a : A) : a⁻¹ * a = 1 := !group.mul_left_inv
|
|
|
|
theorem inv_mul_cancel_left (a b : A) : a⁻¹ * (a * b) = b :=
|
|
by rewrite [-mul.assoc, mul.left_inv, one_mul]
|
|
|
|
theorem inv_mul_cancel_right (a b : A) : a * b⁻¹ * b = a :=
|
|
by rewrite [mul.assoc, mul.left_inv, mul_one]
|
|
|
|
theorem inv_eq_of_mul_eq_one {a b : A} (H : a * b = 1) : a⁻¹ = b :=
|
|
by rewrite [-mul_one a⁻¹, -H, inv_mul_cancel_left]
|
|
|
|
theorem one_inv : 1⁻¹ = (1 : A) := inv_eq_of_mul_eq_one (one_mul 1)
|
|
|
|
theorem inv_inv (a : A) : (a⁻¹)⁻¹ = a := inv_eq_of_mul_eq_one (mul.left_inv a)
|
|
|
|
theorem inv.inj {a b : A} (H : a⁻¹ = b⁻¹) : a = b :=
|
|
by rewrite [-inv_inv, H, inv_inv]
|
|
|
|
theorem inv_eq_inv_iff_eq (a b : A) : a⁻¹ = b⁻¹ ↔ a = b :=
|
|
iff.intro (assume H, inv.inj H) (assume H, congr_arg _ H)
|
|
|
|
theorem inv_eq_one_iff_eq_one (a : A) : a⁻¹ = 1 ↔ a = 1 :=
|
|
one_inv ▸ inv_eq_inv_iff_eq a 1
|
|
|
|
theorem eq_one_of_inv_eq_one (a : A) : a⁻¹ = 1 → a = 1 :=
|
|
iff.mp !inv_eq_one_iff_eq_one
|
|
|
|
theorem eq_inv_of_eq_inv {a b : A} (H : a = b⁻¹) : b = a⁻¹ :=
|
|
by rewrite [H, inv_inv]
|
|
|
|
theorem eq_inv_iff_eq_inv (a b : A) : a = b⁻¹ ↔ b = a⁻¹ :=
|
|
iff.intro !eq_inv_of_eq_inv !eq_inv_of_eq_inv
|
|
|
|
theorem eq_inv_of_mul_eq_one {a b : A} (H : a * b = 1) : a = b⁻¹ :=
|
|
begin rewrite [eq_inv_iff_eq_inv], apply eq.symm, exact inv_eq_of_mul_eq_one H end
|
|
|
|
theorem mul.right_inv (a : A) : a * a⁻¹ = 1 :=
|
|
calc
|
|
a * a⁻¹ = (a⁻¹)⁻¹ * a⁻¹ : inv_inv
|
|
... = 1 : mul.left_inv
|
|
|
|
theorem mul_inv_cancel_left (a b : A) : a * (a⁻¹ * b) = b :=
|
|
calc
|
|
a * (a⁻¹ * b) = a * a⁻¹ * b : by rewrite mul.assoc
|
|
... = 1 * b : mul.right_inv
|
|
... = b : one_mul
|
|
|
|
theorem mul_inv_cancel_right (a b : A) : a * b * b⁻¹ = a :=
|
|
calc
|
|
a * b * b⁻¹ = a * (b * b⁻¹) : mul.assoc
|
|
... = a * 1 : mul.right_inv
|
|
... = a : mul_one
|
|
|
|
theorem mul_inv (a b : A) : (a * b)⁻¹ = b⁻¹ * a⁻¹ :=
|
|
inv_eq_of_mul_eq_one
|
|
(calc
|
|
a * b * (b⁻¹ * a⁻¹) = a * (b * (b⁻¹ * a⁻¹)) : mul.assoc
|
|
... = a * a⁻¹ : mul_inv_cancel_left
|
|
... = 1 : mul.right_inv)
|
|
|
|
theorem eq_of_mul_inv_eq_one {a b : A} (H : a * b⁻¹ = 1) : a = b :=
|
|
calc
|
|
a = a * b⁻¹ * b : by rewrite inv_mul_cancel_right
|
|
... = 1 * b : H
|
|
... = b : one_mul
|
|
|
|
theorem eq_mul_inv_of_mul_eq {a b c : A} (H : a * c = b) : a = b * c⁻¹ :=
|
|
by rewrite [-H, mul_inv_cancel_right]
|
|
|
|
theorem eq_inv_mul_of_mul_eq {a b c : A} (H : b * a = c) : a = b⁻¹ * c :=
|
|
by rewrite [-H, inv_mul_cancel_left]
|
|
|
|
theorem inv_mul_eq_of_eq_mul {a b c : A} (H : b = a * c) : a⁻¹ * b = c :=
|
|
by rewrite [H, inv_mul_cancel_left]
|
|
|
|
theorem mul_inv_eq_of_eq_mul {a b c : A} (H : a = c * b) : a * b⁻¹ = c :=
|
|
by rewrite [H, mul_inv_cancel_right]
|
|
|
|
theorem eq_mul_of_mul_inv_eq {a b c : A} (H : a * c⁻¹ = b) : a = b * c :=
|
|
!inv_inv ▸ (eq_mul_inv_of_mul_eq H)
|
|
|
|
theorem eq_mul_of_inv_mul_eq {a b c : A} (H : b⁻¹ * a = c) : a = b * c :=
|
|
!inv_inv ▸ (eq_inv_mul_of_mul_eq H)
|
|
|
|
theorem mul_eq_of_eq_inv_mul {a b c : A} (H : b = a⁻¹ * c) : a * b = c :=
|
|
!inv_inv ▸ (inv_mul_eq_of_eq_mul H)
|
|
|
|
theorem mul_eq_of_eq_mul_inv {a b c : A} (H : a = c * b⁻¹) : a * b = c :=
|
|
!inv_inv ▸ (mul_inv_eq_of_eq_mul H)
|
|
|
|
theorem mul_eq_iff_eq_inv_mul (a b c : A) : a * b = c ↔ b = a⁻¹ * c :=
|
|
iff.intro eq_inv_mul_of_mul_eq mul_eq_of_eq_inv_mul
|
|
|
|
theorem mul_eq_iff_eq_mul_inv (a b c : A) : a * b = c ↔ a = c * b⁻¹ :=
|
|
iff.intro eq_mul_inv_of_mul_eq mul_eq_of_eq_mul_inv
|
|
|
|
theorem mul_left_cancel {a b c : A} (H : a * b = a * c) : b = c :=
|
|
by rewrite [-inv_mul_cancel_left a b, H, inv_mul_cancel_left]
|
|
|
|
theorem mul_right_cancel {a b c : A} (H : a * b = c * b) : a = c :=
|
|
by rewrite [-mul_inv_cancel_right a b, H, mul_inv_cancel_right]
|
|
|
|
theorem mul_eq_one_of_mul_eq_one {a b : A} (H : b * a = 1) : a * b = 1 :=
|
|
by rewrite [-inv_eq_of_mul_eq_one H, mul.left_inv]
|
|
|
|
theorem mul_eq_one_iff_mul_eq_one (a b : A) : a * b = 1 ↔ b * a = 1 :=
|
|
iff.intro !mul_eq_one_of_mul_eq_one !mul_eq_one_of_mul_eq_one
|
|
|
|
definition conj_by (g a : A) := g * a * g⁻¹
|
|
definition is_conjugate (a b : A) := ∃ x, conj_by x b = a
|
|
|
|
local infixl ` ~ ` := is_conjugate
|
|
local infixr ` ∘c `:55 := conj_by
|
|
|
|
lemma conj_compose (f g a : A) : f ∘c g ∘c a = f*g ∘c a :=
|
|
calc f ∘c g ∘c a = f * (g * a * g⁻¹) * f⁻¹ : rfl
|
|
... = f * (g * a) * g⁻¹ * f⁻¹ : mul.assoc
|
|
... = f * g * a * g⁻¹ * f⁻¹ : mul.assoc
|
|
... = f * g * a * (g⁻¹ * f⁻¹) : mul.assoc
|
|
... = f * g * a * (f * g)⁻¹ : mul_inv
|
|
lemma conj_id (a : A) : 1 ∘c a = a :=
|
|
calc 1 * a * 1⁻¹ = a * 1⁻¹ : one_mul
|
|
... = a * 1 : one_inv
|
|
... = a : mul_one
|
|
lemma conj_one (g : A) : g ∘c 1 = 1 :=
|
|
calc g * 1 * g⁻¹ = g * g⁻¹ : mul_one
|
|
... = 1 : mul.right_inv
|
|
lemma conj_inv_cancel (g : A) : ∀ a, g⁻¹ ∘c g ∘c a = a :=
|
|
assume a, calc
|
|
g⁻¹ ∘c g ∘c a = g⁻¹*g ∘c a : conj_compose
|
|
... = 1 ∘c a : mul.left_inv
|
|
... = a : conj_id
|
|
|
|
lemma conj_inv (g : A) : ∀ a, (g ∘c a)⁻¹ = g ∘c a⁻¹ :=
|
|
take a, calc
|
|
(g * a * g⁻¹)⁻¹ = g⁻¹⁻¹ * (g * a)⁻¹ : mul_inv
|
|
... = g⁻¹⁻¹ * (a⁻¹ * g⁻¹) : mul_inv
|
|
... = g⁻¹⁻¹ * a⁻¹ * g⁻¹ : mul.assoc
|
|
... = g * a⁻¹ * g⁻¹ : inv_inv
|
|
|
|
lemma is_conj.refl (a : A) : a ~ a := exists.intro 1 (conj_id a)
|
|
|
|
lemma is_conj.symm (a b : A) : a ~ b → b ~ a :=
|
|
assume Pab, obtain x (Pconj : x ∘c b = a), from Pab,
|
|
assert Pxinv : x⁻¹ ∘c x ∘c b = x⁻¹ ∘c a, from (congr_arg2 conj_by (eq.refl x⁻¹) Pconj),
|
|
exists.intro x⁻¹ (eq.symm (conj_inv_cancel x b ▸ Pxinv))
|
|
|
|
lemma is_conj.trans (a b c : A) : a ~ b → b ~ c → a ~ c :=
|
|
assume Pab, assume Pbc,
|
|
obtain x (Px : x ∘c b = a), from Pab,
|
|
obtain y (Py : y ∘c c = b), from Pbc,
|
|
exists.intro (x*y) (calc
|
|
x*y ∘c c = x ∘c y ∘c c : conj_compose
|
|
... = x ∘c b : Py
|
|
... = a : Px)
|
|
|
|
definition group.to_left_cancel_semigroup [trans-instance] [coercion] [reducible] :
|
|
left_cancel_semigroup A :=
|
|
⦃ left_cancel_semigroup, s,
|
|
mul_left_cancel := @mul_left_cancel A s ⦄
|
|
|
|
definition group.to_right_cancel_semigroup [trans-instance] [coercion] [reducible] :
|
|
right_cancel_semigroup A :=
|
|
⦃ right_cancel_semigroup, s,
|
|
mul_right_cancel := @mul_right_cancel A s ⦄
|
|
|
|
end group
|
|
|
|
structure comm_group [class] (A : Type) extends group A, comm_monoid A
|
|
|
|
/- additive group -/
|
|
|
|
structure add_group [class] (A : Type) extends add_monoid A, has_neg A :=
|
|
(add_left_inv : ∀a, add (neg a) a = zero)
|
|
|
|
definition add_group.to_group {A : Type} [s : add_group A] : group A :=
|
|
⦃ group, add_monoid.to_monoid,
|
|
mul_left_inv := add_group.add_left_inv ⦄
|
|
|
|
|
|
section add_group
|
|
|
|
variables [s : add_group A]
|
|
include s
|
|
|
|
theorem add.left_inv (a : A) : -a + a = 0 := !add_group.add_left_inv
|
|
|
|
theorem neg_add_cancel_left (a b : A) : -a + (a + b) = b :=
|
|
by rewrite [-add.assoc, add.left_inv, zero_add]
|
|
|
|
theorem neg_add_cancel_right (a b : A) : a + -b + b = a :=
|
|
by rewrite [add.assoc, add.left_inv, add_zero]
|
|
|
|
theorem neg_eq_of_add_eq_zero {a b : A} (H : a + b = 0) : -a = b :=
|
|
by rewrite [-add_zero, -H, neg_add_cancel_left]
|
|
|
|
theorem neg_zero : -0 = (0 : A) := neg_eq_of_add_eq_zero (zero_add 0)
|
|
|
|
theorem neg_neg (a : A) : -(-a) = a := neg_eq_of_add_eq_zero (add.left_inv a)
|
|
|
|
theorem eq_neg_of_add_eq_zero {a b : A} (H : a + b = 0) : a = -b :=
|
|
by rewrite [-neg_eq_of_add_eq_zero H, neg_neg]
|
|
|
|
theorem neg.inj {a b : A} (H : -a = -b) : a = b :=
|
|
calc
|
|
a = -(-a) : neg_neg
|
|
... = b : neg_eq_of_add_eq_zero (H⁻¹ ▸ (add.left_inv _))
|
|
|
|
theorem neg_eq_neg_iff_eq (a b : A) : -a = -b ↔ a = b :=
|
|
iff.intro (assume H, neg.inj H) (assume H, congr_arg _ H)
|
|
|
|
theorem eq_of_neg_eq_neg {a b : A} : -a = -b → a = b :=
|
|
iff.mp !neg_eq_neg_iff_eq
|
|
|
|
theorem neg_eq_zero_iff_eq_zero (a : A) : -a = 0 ↔ a = 0 :=
|
|
neg_zero ▸ !neg_eq_neg_iff_eq
|
|
|
|
theorem eq_zero_of_neg_eq_zero {a : A} : -a = 0 → a = 0 :=
|
|
iff.mp !neg_eq_zero_iff_eq_zero
|
|
|
|
theorem eq_neg_of_eq_neg {a b : A} (H : a = -b) : b = -a :=
|
|
H⁻¹ ▸ (neg_neg b)⁻¹
|
|
|
|
theorem eq_neg_iff_eq_neg (a b : A) : a = -b ↔ b = -a :=
|
|
iff.intro !eq_neg_of_eq_neg !eq_neg_of_eq_neg
|
|
|
|
theorem add.right_inv (a : A) : a + -a = 0 :=
|
|
calc
|
|
a + -a = -(-a) + -a : neg_neg
|
|
... = 0 : add.left_inv
|
|
|
|
theorem add_neg_cancel_left (a b : A) : a + (-a + b) = b :=
|
|
by rewrite [-add.assoc, add.right_inv, zero_add]
|
|
|
|
theorem add_neg_cancel_right (a b : A) : a + b + -b = a :=
|
|
by rewrite [add.assoc, add.right_inv, add_zero]
|
|
|
|
theorem neg_add_rev (a b : A) : -(a + b) = -b + -a :=
|
|
neg_eq_of_add_eq_zero
|
|
begin
|
|
rewrite [add.assoc, add_neg_cancel_left, add.right_inv]
|
|
end
|
|
|
|
-- TODO: delete these in favor of sub rules?
|
|
theorem eq_add_neg_of_add_eq {a b c : A} (H : a + c = b) : a = b + -c :=
|
|
H ▸ !add_neg_cancel_right⁻¹
|
|
|
|
theorem eq_neg_add_of_add_eq {a b c : A} (H : b + a = c) : a = -b + c :=
|
|
H ▸ !neg_add_cancel_left⁻¹
|
|
|
|
theorem neg_add_eq_of_eq_add {a b c : A} (H : b = a + c) : -a + b = c :=
|
|
H⁻¹ ▸ !neg_add_cancel_left
|
|
|
|
theorem add_neg_eq_of_eq_add {a b c : A} (H : a = c + b) : a + -b = c :=
|
|
H⁻¹ ▸ !add_neg_cancel_right
|
|
|
|
theorem eq_add_of_add_neg_eq {a b c : A} (H : a + -c = b) : a = b + c :=
|
|
!neg_neg ▸ (eq_add_neg_of_add_eq H)
|
|
|
|
theorem eq_add_of_neg_add_eq {a b c : A} (H : -b + a = c) : a = b + c :=
|
|
!neg_neg ▸ (eq_neg_add_of_add_eq H)
|
|
|
|
theorem add_eq_of_eq_neg_add {a b c : A} (H : b = -a + c) : a + b = c :=
|
|
!neg_neg ▸ (neg_add_eq_of_eq_add H)
|
|
|
|
theorem add_eq_of_eq_add_neg {a b c : A} (H : a = c + -b) : a + b = c :=
|
|
!neg_neg ▸ (add_neg_eq_of_eq_add H)
|
|
|
|
theorem add_eq_iff_eq_neg_add (a b c : A) : a + b = c ↔ b = -a + c :=
|
|
iff.intro eq_neg_add_of_add_eq add_eq_of_eq_neg_add
|
|
|
|
theorem add_eq_iff_eq_add_neg (a b c : A) : a + b = c ↔ a = c + -b :=
|
|
iff.intro eq_add_neg_of_add_eq add_eq_of_eq_add_neg
|
|
|
|
theorem add_left_cancel {a b c : A} (H : a + b = a + c) : b = c :=
|
|
calc b = -a + (a + b) : !neg_add_cancel_left⁻¹
|
|
... = -a + (a + c) : H
|
|
... = c : neg_add_cancel_left
|
|
|
|
theorem add_right_cancel {a b c : A} (H : a + b = c + b) : a = c :=
|
|
calc a = (a + b) + -b : !add_neg_cancel_right⁻¹
|
|
... = (c + b) + -b : H
|
|
... = c : add_neg_cancel_right
|
|
|
|
definition add_group.to_left_cancel_semigroup [trans-instance] [coercion] [reducible] :
|
|
add_left_cancel_semigroup A :=
|
|
⦃ add_left_cancel_semigroup, s,
|
|
add_left_cancel := @add_left_cancel A s ⦄
|
|
|
|
definition add_group.to_add_right_cancel_semigroup [trans-instance] [coercion] [reducible] :
|
|
add_right_cancel_semigroup A :=
|
|
⦃ add_right_cancel_semigroup, s,
|
|
add_right_cancel := @add_right_cancel A s ⦄
|
|
|
|
theorem add_neg_eq_neg_add_rev {a b : A} : a + -b = -(b + -a) :=
|
|
by rewrite [neg_add_rev, neg_neg]
|
|
|
|
/- sub -/
|
|
|
|
-- TODO: derive corresponding facts for div in a field
|
|
definition sub [reducible] (a b : A) : A := a + -b
|
|
|
|
definition add_group_has_sub [reducible] [instance] : has_sub A :=
|
|
has_sub.mk algebra.sub
|
|
|
|
theorem sub_eq_add_neg (a b : A) : a - b = a + -b := rfl
|
|
|
|
theorem sub_self (a : A) : a - a = 0 := !add.right_inv
|
|
|
|
theorem sub_add_cancel (a b : A) : a - b + b = a := !neg_add_cancel_right
|
|
|
|
theorem add_sub_cancel (a b : A) : a + b - b = a := !add_neg_cancel_right
|
|
|
|
theorem eq_of_sub_eq_zero {a b : A} (H : a - b = 0) : a = b :=
|
|
calc
|
|
a = (a - b) + b : !sub_add_cancel⁻¹
|
|
... = 0 + b : H
|
|
... = b : zero_add
|
|
|
|
theorem eq_iff_sub_eq_zero (a b : A) : a = b ↔ a - b = 0 :=
|
|
iff.intro (assume H, H ▸ !sub_self) (assume H, eq_of_sub_eq_zero H)
|
|
|
|
theorem zero_sub (a : A) : 0 - a = -a := !zero_add
|
|
|
|
theorem sub_zero (a : A) : a - 0 = a :=
|
|
by rewrite [sub_eq_add_neg, neg_zero, add_zero]
|
|
|
|
theorem sub_neg_eq_add (a b : A) : a - (-b) = a + b :=
|
|
by change a + -(-b) = a + b; rewrite neg_neg
|
|
|
|
theorem neg_sub (a b : A) : -(a - b) = b - a :=
|
|
neg_eq_of_add_eq_zero
|
|
(calc
|
|
a - b + (b - a) = a - b + b - a : by krewrite -add.assoc
|
|
... = a - a : sub_add_cancel
|
|
... = 0 : sub_self)
|
|
|
|
theorem add_sub (a b c : A) : a + (b - c) = a + b - c := !add.assoc⁻¹
|
|
|
|
theorem sub_add_eq_sub_sub_swap (a b c : A) : a - (b + c) = a - c - b :=
|
|
calc
|
|
a - (b + c) = a + (-c - b) : by rewrite [sub_eq_add_neg, neg_add_rev]
|
|
... = a - c - b : by krewrite -add.assoc
|
|
|
|
theorem sub_eq_iff_eq_add (a b c : A) : a - b = c ↔ a = c + b :=
|
|
iff.intro (assume H, eq_add_of_add_neg_eq H) (assume H, add_neg_eq_of_eq_add H)
|
|
|
|
theorem eq_sub_iff_add_eq (a b c : A) : a = b - c ↔ a + c = b :=
|
|
iff.intro (assume H, add_eq_of_eq_add_neg H) (assume H, eq_add_neg_of_add_eq H)
|
|
|
|
theorem eq_iff_eq_of_sub_eq_sub {a b c d : A} (H : a - b = c - d) : a = b ↔ c = d :=
|
|
calc
|
|
a = b ↔ a - b = 0 : eq_iff_sub_eq_zero
|
|
... = (c - d = 0) : H
|
|
... ↔ c = d : iff.symm (eq_iff_sub_eq_zero c d)
|
|
|
|
theorem eq_sub_of_add_eq {a b c : A} (H : a + c = b) : a = b - c :=
|
|
!eq_add_neg_of_add_eq H
|
|
|
|
theorem sub_eq_of_eq_add {a b c : A} (H : a = c + b) : a - b = c :=
|
|
!add_neg_eq_of_eq_add H
|
|
|
|
theorem eq_add_of_sub_eq {a b c : A} (H : a - c = b) : a = b + c :=
|
|
eq_add_of_add_neg_eq H
|
|
|
|
theorem add_eq_of_eq_sub {a b c : A} (H : a = c - b) : a + b = c :=
|
|
add_eq_of_eq_add_neg H
|
|
|
|
end add_group
|
|
|
|
structure add_comm_group [class] (A : Type) extends add_group A, add_comm_monoid A
|
|
|
|
section add_comm_group
|
|
variable [s : add_comm_group A]
|
|
include s
|
|
|
|
theorem sub_add_eq_sub_sub (a b c : A) : a - (b + c) = a - b - c :=
|
|
!add.comm ▸ !sub_add_eq_sub_sub_swap
|
|
|
|
theorem neg_add_eq_sub (a b : A) : -a + b = b - a := !add.comm
|
|
|
|
theorem neg_add (a b : A) : -(a + b) = -a + -b := add.comm (-b) (-a) ▸ neg_add_rev a b
|
|
|
|
theorem sub_add_eq_add_sub (a b c : A) : a - b + c = a + c - b := !add.right_comm
|
|
|
|
theorem sub_sub (a b c : A) : a - b - c = a - (b + c) :=
|
|
by rewrite [▸ a + -b + -c = _, add.assoc, -neg_add]
|
|
|
|
theorem add_sub_add_left_eq_sub (a b c : A) : (c + a) - (c + b) = a - b :=
|
|
by rewrite [sub_add_eq_sub_sub, (add.comm c a), add_sub_cancel]
|
|
|
|
theorem eq_sub_of_add_eq' {a b c : A} (H : c + a = b) : a = b - c :=
|
|
!eq_sub_of_add_eq (!add.comm ▸ H)
|
|
|
|
theorem sub_eq_of_eq_add' {a b c : A} (H : a = b + c) : a - b = c :=
|
|
!sub_eq_of_eq_add (!add.comm ▸ H)
|
|
|
|
theorem eq_add_of_sub_eq' {a b c : A} (H : a - b = c) : a = b + c :=
|
|
!add.comm ▸ eq_add_of_sub_eq H
|
|
|
|
theorem add_eq_of_eq_sub' {a b c : A} (H : b = c - a) : a + b = c :=
|
|
!add.comm ▸ add_eq_of_eq_sub H
|
|
|
|
theorem sub_sub_self (a b : A) : a - (a - b) = b :=
|
|
by rewrite [sub_eq_add_neg, neg_sub, add.comm, sub_add_cancel]
|
|
|
|
theorem add_sub_comm (a b c d : A) : a + b - (c + d) = (a - c) + (b - d) :=
|
|
by rewrite [sub_add_eq_sub_sub, -sub_add_eq_add_sub a c b, add_sub]
|
|
|
|
theorem sub_eq_sub_add_sub (a b c : A) : a - b = c - b + (a - c) :=
|
|
by rewrite [add_sub, sub_add_cancel] ⬝ !add.comm
|
|
|
|
theorem neg_neg_sub_neg (a b : A) : - (-a - -b) = a - b :=
|
|
by rewrite [neg_sub, sub_neg_eq_add, neg_add_eq_sub]
|
|
end add_comm_group
|
|
|
|
definition group_of_add_group (A : Type) [G : add_group A] : group A :=
|
|
⦃group,
|
|
mul := has_add.add,
|
|
mul_assoc := add.assoc,
|
|
one := !has_zero.zero,
|
|
one_mul := zero_add,
|
|
mul_one := add_zero,
|
|
inv := has_neg.neg,
|
|
mul_left_inv := add.left_inv⦄
|
|
|
|
end algebra
|