2014-09-28 04:47:37 +00:00
|
|
|
-- 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
|
|
|
|
|
|
|
|
-- algebra.group
|
|
|
|
-- =============
|
|
|
|
|
|
|
|
-- Various structures with 1, *, inv, including groups.
|
|
|
|
|
2014-10-05 17:50:13 +00:00
|
|
|
import logic.eq logic.connectives
|
2014-09-28 04:47:37 +00:00
|
|
|
import data.unit data.sigma data.prod
|
|
|
|
import algebra.function algebra.binary
|
|
|
|
|
|
|
|
open eq
|
|
|
|
|
|
|
|
namespace algebra
|
|
|
|
|
|
|
|
-- classes for notation
|
|
|
|
-- --------------------
|
|
|
|
|
|
|
|
inductive has_mul [class] (A : Type) : Type := mk : (A → A → A) → has_mul A
|
|
|
|
inductive has_one [class] (A : Type) : Type := mk : A → has_one A
|
|
|
|
inductive has_inv [class] (A : Type) : Type := mk : (A → A) → has_inv A
|
|
|
|
|
2014-10-03 20:54:11 +00:00
|
|
|
definition mul {A : Type} {s : has_mul A} (a b : A) : A := has_mul.rec (λf, f) s a b
|
|
|
|
definition one {A : Type} {s : has_one A} : A := has_one.rec (λo, o) s
|
|
|
|
definition inv {A : Type} {s : has_inv A} (a : A) : A := has_inv.rec (λi, i) s a
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
infix `*` := mul
|
|
|
|
postfix `⁻¹` := inv
|
|
|
|
notation 1 := one
|
|
|
|
|
|
|
|
-- semigroup
|
|
|
|
-- ---------
|
|
|
|
|
|
|
|
inductive semigroup [class] (A : Type) : Type :=
|
|
|
|
mk : Π mul: A → A → A,
|
|
|
|
(∀a b c : A, (mul (mul a b) c = mul a (mul b c))) →
|
|
|
|
semigroup A
|
|
|
|
|
|
|
|
namespace semigroup
|
2014-10-03 20:54:11 +00:00
|
|
|
section
|
2014-09-28 04:47:37 +00:00
|
|
|
parameters {A : Type} {s : semigroup A}
|
2014-10-03 16:20:49 +00:00
|
|
|
variables a b c : A
|
|
|
|
definition mul := semigroup.rec (λmul assoc, mul) s a b
|
2014-10-03 20:54:11 +00:00
|
|
|
context
|
|
|
|
infixl `*` := mul
|
|
|
|
definition assoc : (a * b) * c = a * (b * c) :=
|
|
|
|
semigroup.rec (λmul assoc, assoc) s a b c
|
2014-09-28 04:47:37 +00:00
|
|
|
end
|
2014-10-03 20:54:11 +00:00
|
|
|
end
|
2014-09-28 04:47:37 +00:00
|
|
|
end semigroup
|
|
|
|
|
|
|
|
section
|
|
|
|
parameters {A : Type} {s : semigroup A}
|
2014-10-03 15:52:35 +00:00
|
|
|
include s
|
2014-10-03 20:54:11 +00:00
|
|
|
definition semigroup_has_mul [instance] : has_mul A := has_mul.mk semigroup.mul
|
2014-09-28 04:47:37 +00:00
|
|
|
|
2014-10-03 15:52:35 +00:00
|
|
|
theorem mul_assoc [instance] (a b c : A) : a * b * c = a * (b * c) :=
|
2014-10-03 16:20:49 +00:00
|
|
|
!semigroup.assoc
|
2014-09-28 04:47:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- comm_semigroup
|
|
|
|
-- --------------
|
|
|
|
|
|
|
|
inductive comm_semigroup [class] (A : Type) : Type :=
|
2014-10-03 20:54:11 +00:00
|
|
|
mk : Π (mul: A → A → A)
|
|
|
|
(infixl `*` := mul),
|
|
|
|
(∀a b c, (a * b) * c = a * (b * c)) →
|
|
|
|
(∀a b, a * b = b * a) →
|
2014-09-28 04:47:37 +00:00
|
|
|
comm_semigroup A
|
|
|
|
|
|
|
|
namespace comm_semigroup
|
2014-10-03 20:54:11 +00:00
|
|
|
section
|
2014-09-28 04:47:37 +00:00
|
|
|
parameters {A : Type} {s : comm_semigroup A}
|
2014-10-03 15:52:35 +00:00
|
|
|
variables a b c : A
|
2014-09-28 04:47:37 +00:00
|
|
|
definition mul (a b : A) : A := comm_semigroup.rec (λmul assoc comm, mul) s a b
|
2014-10-03 15:52:35 +00:00
|
|
|
definition assoc : mul (mul a b) c = mul a (mul b c) :=
|
2014-09-28 04:47:37 +00:00
|
|
|
comm_semigroup.rec (λmul assoc comm, assoc) s a b c
|
2014-10-03 15:52:35 +00:00
|
|
|
definition comm : mul a b = mul b a :=
|
2014-09-28 04:47:37 +00:00
|
|
|
comm_semigroup.rec (λmul assoc comm, comm) s a b
|
2014-10-03 20:54:11 +00:00
|
|
|
end
|
2014-09-28 04:47:37 +00:00
|
|
|
end comm_semigroup
|
|
|
|
|
|
|
|
section
|
|
|
|
parameters {A : Type} {s : comm_semigroup A}
|
2014-10-03 15:52:35 +00:00
|
|
|
variables a b c : A
|
|
|
|
include s
|
|
|
|
definition comm_semigroup_semigroup [instance] : semigroup A :=
|
|
|
|
semigroup.mk comm_semigroup.mul comm_semigroup.assoc
|
2014-09-28 04:47:37 +00:00
|
|
|
|
2014-10-03 15:52:35 +00:00
|
|
|
theorem mul_comm : a * b = b * a := !comm_semigroup.comm
|
2014-09-28 04:47:37 +00:00
|
|
|
|
2014-10-03 15:52:35 +00:00
|
|
|
theorem mul_left_comm : a * (b * c) = b * (a * c) :=
|
|
|
|
binary.left_comm mul_comm mul_assoc a b c
|
2014-09-28 04:47:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- monoid
|
|
|
|
-- ------
|
|
|
|
|
|
|
|
inductive monoid [class] (A : Type) : Type :=
|
2014-10-03 20:54:11 +00:00
|
|
|
mk : Π (mul: A → A → A) (one : A)
|
|
|
|
(infixl `*` := mul) (notation 1 := one),
|
|
|
|
(∀a b c, (a * b) * c = a * (b * c)) →
|
|
|
|
(∀a, a * 1 = a) →
|
|
|
|
(∀a, 1 * a = a) →
|
2014-09-28 04:47:37 +00:00
|
|
|
monoid A
|
|
|
|
|
|
|
|
namespace monoid
|
|
|
|
section
|
|
|
|
parameters {A : Type} {s : monoid A}
|
2014-10-03 15:52:35 +00:00
|
|
|
variables a b c : A
|
2014-10-03 20:54:11 +00:00
|
|
|
include s
|
|
|
|
context
|
2014-10-03 15:52:35 +00:00
|
|
|
definition mul := monoid.rec (λmul one assoc right_id left_id, mul) s a b
|
|
|
|
definition one := monoid.rec (λmul one assoc right_id left_id, one) s
|
2014-10-03 20:54:11 +00:00
|
|
|
infixl `*` := mul
|
|
|
|
notation 1 := one
|
|
|
|
definition assoc : (a * b) * c = a * (b * c) :=
|
2014-09-28 04:47:37 +00:00
|
|
|
monoid.rec (λmul one assoc right_id left_id, assoc) s a b c
|
2014-10-03 20:54:11 +00:00
|
|
|
definition right_id : a * 1 = a :=
|
2014-09-28 04:47:37 +00:00
|
|
|
monoid.rec (λmul one assoc right_id left_id, right_id) s a
|
2014-10-03 20:54:11 +00:00
|
|
|
definition left_id : 1 * a = a :=
|
2014-09-28 04:47:37 +00:00
|
|
|
monoid.rec (λmul one assoc right_id left_id, left_id) s a
|
|
|
|
end
|
2014-10-03 20:54:11 +00:00
|
|
|
end
|
2014-09-28 04:47:37 +00:00
|
|
|
end monoid
|
|
|
|
|
|
|
|
section
|
|
|
|
parameters {A : Type} {s : monoid A}
|
2014-10-03 15:52:35 +00:00
|
|
|
variable a : A
|
|
|
|
include s
|
|
|
|
definition monoid_has_one [instance] : has_one A := has_one.mk (monoid.one)
|
|
|
|
definition monoid_semigroup [instance] : semigroup A :=
|
|
|
|
semigroup.mk monoid.mul monoid.assoc
|
|
|
|
|
2014-10-03 20:54:11 +00:00
|
|
|
theorem mul_right_id : a * 1 = a := !monoid.right_id
|
|
|
|
theorem mul_left_id : 1 * a = a := !monoid.left_id
|
2014-09-28 04:47:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- comm_monoid
|
|
|
|
-- -----------
|
|
|
|
|
|
|
|
inductive comm_monoid [class] (A : Type) : Type :=
|
2014-10-03 20:54:11 +00:00
|
|
|
mk : Π (mul: A → A → A) (one : A)
|
|
|
|
(infixl `*` := mul) (notation 1 := one),
|
|
|
|
(∀a b c, (a * b) * c = a * (b * c)) →
|
|
|
|
(∀a, a * 1 = a) →
|
|
|
|
(∀a, 1 * a = a) →
|
|
|
|
(∀a b, a * b = b * a) →
|
|
|
|
comm_monoid A
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
namespace comm_monoid
|
|
|
|
section
|
|
|
|
parameters {A : Type} {s : comm_monoid A}
|
2014-10-03 15:52:35 +00:00
|
|
|
variables a b c : A
|
|
|
|
definition mul := comm_monoid.rec (λmul one assoc right_id left_id comm, mul) s a b
|
|
|
|
definition one := comm_monoid.rec (λmul one assoc right_id left_id comm, one) s
|
|
|
|
definition assoc : mul (mul a b) c = mul a (mul b c) :=
|
2014-09-28 04:47:37 +00:00
|
|
|
comm_monoid.rec (λmul one assoc right_id left_id comm, assoc) s a b c
|
2014-10-03 15:52:35 +00:00
|
|
|
definition right_id : mul a one = a :=
|
2014-09-28 04:47:37 +00:00
|
|
|
comm_monoid.rec (λmul one assoc right_id left_id comm, right_id) s a
|
2014-10-03 15:52:35 +00:00
|
|
|
definition left_id : mul one a = a :=
|
2014-09-28 04:47:37 +00:00
|
|
|
comm_monoid.rec (λmul one assoc right_id left_id comm, left_id) s a
|
2014-10-03 15:52:35 +00:00
|
|
|
definition comm : mul a b = mul b a :=
|
2014-09-28 04:47:37 +00:00
|
|
|
comm_monoid.rec (λmul one assoc right_id left_id comm, comm) s a b
|
|
|
|
end
|
|
|
|
end comm_monoid
|
|
|
|
|
|
|
|
section
|
|
|
|
parameters {A : Type} {s : comm_monoid A}
|
2014-10-03 15:52:35 +00:00
|
|
|
include s
|
|
|
|
definition comm_monoid_monoid [instance] : monoid A :=
|
|
|
|
monoid.mk comm_monoid.mul comm_monoid.one comm_monoid.assoc
|
|
|
|
comm_monoid.right_id comm_monoid.left_id
|
|
|
|
definition comm_monoid_comm_semigroup [instance] : comm_semigroup A :=
|
|
|
|
comm_semigroup.mk comm_monoid.mul comm_monoid.assoc comm_monoid.comm
|
2014-09-28 04:47:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- bundled structures
|
|
|
|
-- ------------------
|
|
|
|
|
|
|
|
inductive Semigroup [class] : Type := mk : Π carrier : Type, semigroup carrier → Semigroup
|
2014-10-03 15:52:35 +00:00
|
|
|
section
|
|
|
|
parameter S : Semigroup
|
|
|
|
definition Semigroup.carrier [coercion] : Type := Semigroup.rec (λc s, c) S
|
|
|
|
definition Semigroup.struc [instance] : semigroup S := Semigroup.rec (λc s, s) S
|
|
|
|
end
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
inductive CommSemigroup [class] : Type :=
|
|
|
|
mk : Π carrier : Type, comm_semigroup carrier → CommSemigroup
|
2014-10-03 15:52:35 +00:00
|
|
|
section
|
|
|
|
parameter S : CommSemigroup
|
|
|
|
definition CommSemigroup.carrier [coercion] : Type := CommSemigroup.rec (λc s, c) S
|
|
|
|
definition CommSemigroup.struc [instance] : comm_semigroup S := CommSemigroup.rec (λc s, s) S
|
|
|
|
end
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
inductive Monoid [class] : Type := mk : Π carrier : Type, monoid carrier → Monoid
|
2014-10-03 15:52:35 +00:00
|
|
|
section
|
|
|
|
parameter S : Monoid
|
|
|
|
definition Monoid.carrier [coercion] : Type := Monoid.rec (λc s, c) S
|
|
|
|
definition Monoid.struc [instance] : monoid S := Monoid.rec (λc s, s) S
|
|
|
|
end
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
inductive CommMonoid : Type := mk : Π carrier : Type, comm_monoid carrier → CommMonoid
|
2014-10-03 15:52:35 +00:00
|
|
|
section
|
|
|
|
parameter S : CommMonoid
|
|
|
|
definition CommMonoid.carrier [coercion] : Type := CommMonoid.rec (λc s, c) S
|
|
|
|
definition CommMonoid.struc [instance] : comm_monoid S := CommMonoid.rec (λc s, s) S
|
|
|
|
end
|
2014-09-28 04:47:37 +00:00
|
|
|
end algebra
|
|
|
|
|
|
|
|
open algebra
|
|
|
|
|
|
|
|
section examples
|
|
|
|
|
|
|
|
theorem test1 {S : Semigroup} (a b c d : S) : a * (b * c) * d = a * b * (c * d) :=
|
|
|
|
calc
|
2014-10-03 15:52:35 +00:00
|
|
|
a * (b * c) * d = a * b * c * d : {symm !mul_assoc}
|
|
|
|
... = a * b * (c * d) : !mul_assoc
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
theorem test2 {M : CommSemigroup} (a b : M) : a * b = a * b := rfl
|
|
|
|
|
|
|
|
theorem test3 {M : Monoid} (a b c d : M) : a * (b * c) * d = a * b * (c * d) :=
|
|
|
|
calc
|
2014-10-03 15:52:35 +00:00
|
|
|
a * (b * c) * d = a * b * c * d : {symm !mul_assoc}
|
|
|
|
... = a * b * (c * d) : !mul_assoc
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
-- for test4b to work, we need instances at the level of the bundled structures as well
|
|
|
|
definition Monoid_Semigroup [instance] (M : Monoid) : Semigroup :=
|
|
|
|
Semigroup.mk (Monoid.carrier M) _
|
|
|
|
|
|
|
|
theorem test4 {M : Monoid} (a b c d : M) : a * (b * c) * d = a * b * (c * d) :=
|
|
|
|
test1 a b c d
|
|
|
|
|
|
|
|
theorem test5 {M : Monoid} (a b c : M) : a * 1 * b * c = a * (b * c) :=
|
|
|
|
calc
|
2014-10-03 15:52:35 +00:00
|
|
|
a * 1 * b * c = a * b * c : {!mul_right_id}
|
|
|
|
... = a * (b * c) : !mul_assoc
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
theorem test5a {M : Monoid} (a b c : M) : a * 1 * b * c = a * (b * c) :=
|
|
|
|
calc
|
2014-10-03 15:52:35 +00:00
|
|
|
a * 1 * b * c = a * b * c : {!mul_right_id}
|
|
|
|
... = a * (b * c) : !mul_assoc
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
theorem test5b {A : Type} {M : monoid A} (a b c : A) : a * 1 * b * c = a * (b * c) :=
|
|
|
|
calc
|
2014-10-03 15:52:35 +00:00
|
|
|
a * 1 * b * c = a * b * c : {!mul_right_id}
|
|
|
|
... = a * (b * c) : !mul_assoc
|
2014-09-28 04:47:37 +00:00
|
|
|
|
|
|
|
theorem test6 {M : CommMonoid} (a b c : M) : a * 1 * b * c = a * (b * c) :=
|
|
|
|
calc
|
2014-10-03 15:52:35 +00:00
|
|
|
a * 1 * b * c = a * b * c : {!mul_right_id}
|
|
|
|
... = a * (b * c) : !mul_assoc
|
2014-09-28 04:47:37 +00:00
|
|
|
end examples
|