Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Spaces.Nat.Core Spaces.Nat.Arithmetic.(* Some of the material in abstract_algebra and canonical names could be selectively exported to the user, as is done in Groups/Group.v. *)Require Import Classes.interfaces.abstract_algebra.Require Import Algebra.Groups.Group Algebra.Groups.Subgroup.Require Export Algebra.AbGroups.AbelianGroup Algebra.AbGroups.Biproduct Algebra.AbGroups.FiniteSum.Require Export Classes.theory.rings.Require Import Modalities.ReflectiveSubuniverse.(** We make sure to treat [AbGroup] as if it has a [Plus], [Zero], and [Negate] operation from now on. *)Export AbelianGroup.AdditiveInstances.(** * Rings *)Declare Scope ring_scope.LocalOpen Scope ring_scope.(** We want to print equivalences as [≅]. *)LocalOpen Scope wc_iso_scope.(** A ring consists of the following data: *)RecordRing := Build_Ring' {
(** An underlying abelian group. *)
ring_abgroup :> AbGroup;
(** A multiplication operation. *)
ring_mult :: Mult ring_abgroup;
(** A multiplicative identity called [one]. *)
ring_one :: One ring_abgroup;
(** Such that all they all satisfy the axioms of a ring. *)
ring_isring :: IsRing ring_abgroup;
(** This field only exists so that opposite rings are definitionally involutive and can safely be ignored. *)
ring_mult_assoc_opp : forallzyx, (x * y) * z = x * (y * z);
}.Arguments ring_mult {R} : rename.Arguments ring_one {R} : rename.Arguments ring_isring {R} : rename.Definitionissig_Ring : _ <~> Ring := ltac:(issig).Instancering_plus {R : Ring} : Plus R := plus_abgroup (ring_abgroup R).Instancering_zero {R : Ring} : Zero R := zero_abgroup (ring_abgroup R).Instancering_negate {R : Ring} : Negate R := negate_abgroup (ring_abgroup R).(** A ring homomorphism between rings is a map of the underlying type and a proof that this map is a ring homomorphism. *)RecordRingHomomorphism (AB : Ring) := {
rng_homo_map :> A -> B;
rng_homo_ishomo :: IsSemiRingPreserving rng_homo_map;
}.Arguments Build_RingHomomorphism {_ _} _ _.Definitionissig_RingHomomorphism (AB : Ring)
: _ <~> RingHomomorphism A B
:= ltac:(issig).
H: Funext A, B: Ring f, g: RingHomomorphism A B
f == g <~> f = g
H: Funext A, B: Ring f, g: RingHomomorphism A B
f == g <~> f = g
H: Funext A, B: Ring f, g: RingHomomorphism A B
f == g <~>
(issig_RingHomomorphism A B)^-1 f =
(issig_RingHomomorphism A B)^-1 g
H: Funext A, B: Ring f, g: RingHomomorphism A B
f == g <~>
((issig_RingHomomorphism A B)^-1 f).1 =
((issig_RingHomomorphism A B)^-1 g).1
apply equiv_path_forall.Defined.Definitionrng_homo_id (A : Ring) : RingHomomorphism A A
:= Build_RingHomomorphism idmap (Build_IsSemiRingPreserving _ _ _).
A, B, C: Ring f: RingHomomorphism B C g: RingHomomorphism A B
RingHomomorphism A C
A, B, C: Ring f: RingHomomorphism B C g: RingHomomorphism A B
RingHomomorphism A C
A, B, C: Ring f: RingHomomorphism B C g: RingHomomorphism A B
A -> C
A, B, C: Ring f: RingHomomorphism B C g: RingHomomorphism A B
IsSemiRingPreserving ?rng_homo_map
A, B, C: Ring f: RingHomomorphism B C g: RingHomomorphism A B
IsSemiRingPreserving (f o g)
rapply compose_sr_morphism.Defined.(** ** Ring laws *)SectionRingLaws.(** Many of these ring laws have already been proven. But we give them names here so that they are easy to find and use. *)Context {A : Ring} (xyz : A).Definitionrng_dist_l : x * (y + z) = x * y + x * z := simple_distribute_l _ _ _.Definitionrng_dist_r : (x + y) * z = x * z + y * z := simple_distribute_r _ _ _.Definitionrng_plus_zero_l : 0 + x = x := left_identity _.Definitionrng_plus_zero_r : x + 0 = x := right_identity _.Definitionrng_plus_negate_l : (- x) + x = 0 := left_inverse _.Definitionrng_plus_negate_r : x + (- x) = 0 := right_inverse _.Definitionrng_plus_comm : x + y = y + x := commutativity x y.Definitionrng_plus_assoc : x + (y + z) = (x + y) + z := simple_associativity x y z.Definitionrng_mult_assoc : x * (y * z) = (x * y) * z := simple_associativity x y z.Definitionrng_negate_negate : - (- x) = x := groups.inverse_involutive _.Definitionrng_negate_zero : - (0 : A) = 0 := groups.inverse_mon_unit.Definitionrng_negate_plus : - (x + y) = - x - y := negate_plus_distr _ _.Definitionrng_mult_one_l : 1 * x = x := left_identity _.Definitionrng_mult_one_r : x * 1 = x := right_identity _.Definitionrng_mult_zero_l : 0 * x = 0 := left_absorb _.Definitionrng_mult_zero_r : x * 0 = 0 := right_absorb _.Definitionrng_mult_negate : -1 * x = - x := (negate_mult_l _)^.Definitionrng_mult_negate_negate : -x * -y = x * y := negate_mult_negate _ _.Definitionrng_mult_negate_l : -x * y = -(x * y) := inverse (negate_mult_distr_l _ _).Definitionrng_mult_negate_r : x * -y = -(x * y) := inverse (negate_mult_distr_r _ _).EndRingLaws.
A: Ring x, y, z: A
x * (y - z) = x * y - x * z
A: Ring x, y, z: A
x * (y - z) = x * y - x * z
A: Ring x, y, z: A
x * y + x * - z = x * y - x * z
A: Ring x, y, z: A
x * - z = - (x * z)
napply rng_mult_negate_r.Defined.
A: Ring x, y, z: A
(x - y) * z = x * z - y * z
A: Ring x, y, z: A
(x - y) * z = x * z - y * z
A: Ring x, y, z: A
x * z + - y * z = x * z - y * z
A: Ring x, y, z: A
- y * z = - (y * z)
napply rng_mult_negate_l.Defined.SectionRingHomoLaws.Context {AB : Ring} (f : RingHomomorphism A B) (xy : A).Definitionrng_homo_plus : f (x + y) = f x + f y := preserves_plus x y.Definitionrng_homo_mult : f (x * y) = f x * f y := preserves_mult x y.Definitionrng_homo_zero : f 0 = 0 := preserves_0.Definitionrng_homo_one : f 1 = 1 := preserves_1.Definitionrng_homo_negate : f (-x) = -(f x) := preserves_negate x.Definitionrng_homo_minus_one : f (-1) = -1
:= preserves_negate _ @ ap negate preserves_1.EndRingHomoLaws.(** Isomorphisms of commutative rings *)RecordRingIsomorphism (AB : Ring) := {
rng_iso_homo : RingHomomorphism A B ;
isequiv_rng_iso_homo :: IsEquiv rng_iso_homo ;
}.Arguments rng_iso_homo {_ _ }.Coercionrng_iso_homo : RingIsomorphism >-> RingHomomorphism.Definitionissig_RingIsomorphism {AB : Ring}
: _ <~> RingIsomorphism A B := ltac:(issig).(** We can construct a ring isomorphism from an equivalence that preserves addition and multiplication. *)DefinitionBuild_RingIsomorphism' (AB : Ring) (e : A <~> B)
`{!IsSemiRingPreserving e}
: RingIsomorphism A B
:= Build_RingIsomorphism A B (Build_RingHomomorphism e _) _.(** The inverse of a Ring isomorphism *)
A, B: Ring
RingIsomorphism A B -> RingIsomorphism B A
A, B: Ring
RingIsomorphism A B -> RingIsomorphism B A
A, B: Ring f: RingHomomorphism A B e: IsEquiv f
RingIsomorphism B A
A, B: Ring f: RingHomomorphism A B e: IsEquiv f
RingHomomorphism B A
A, B: Ring f: RingHomomorphism A B e: IsEquiv f
IsEquiv ?rng_iso_homo
A, B: Ring f: RingHomomorphism A B e: IsEquiv f
RingHomomorphism B A
A, B: Ring f: RingHomomorphism A B e: IsEquiv f
B -> A
A, B: Ring f: RingHomomorphism A B e: IsEquiv f
IsSemiRingPreserving ?rng_homo_map
A, B: Ring f: RingHomomorphism A B e: IsEquiv f
IsSemiRingPreserving f^-1
exact _.
A, B: Ring f: RingHomomorphism A B e: IsEquiv f
IsEquiv
{|
rng_homo_map := f^-1;
rng_homo_ishomo :=
invert_sr_morphism f (rng_homo_ishomo A B f)
|}
exact _.Defined.(** Ring isomorphisms are a reflexive relation *)Instancereflexive_ringisomorphism : Reflexive RingIsomorphism
:= funx => Build_RingIsomorphism _ _ (rng_homo_id x) _.(** Ring isomorphisms are a symmetric relation *)Instancesymmetry_ringisomorphism : Symmetric RingIsomorphism
:= funxy => rng_iso_inverse.(** Ring isomorphisms are a transitive relation *)Instancetransitive_ringisomorphism : Transitive RingIsomorphism
:= funxyzfg => Build_RingIsomorphism _ _ (rng_homo_compose g f) _.(** Underlying group homomorphism of a ring homomorphism *)Definitiongrp_homo_rng_homo {RS : Ring}
: RingHomomorphism R S -> GroupHomomorphism R S
:= funf => @Build_GroupHomomorphism R S f _.Coerciongrp_homo_rng_homo : RingHomomorphism >-> GroupHomomorphism.(** We can construct a ring homomorphism from a group homomorphism that preserves multiplication *)DefinitionBuild_RingHomomorphism' (AB : Ring) (map : GroupHomomorphism A B)
{H : IsMonoidPreserving (Aop:=ring_mult) (Bop:=ring_mult)
(Aunit:=one) (Bunit:=one) map}
: RingHomomorphism A B
:= Build_RingHomomorphism map
(Build_IsSemiRingPreserving _ (ismonoidpreserving_grp_homo map) H).(** We can construct a ring isomorphism from a group isomorphism that preserves multiplication *)DefinitionBuild_RingIsomorphism'' (AB : Ring) (e : GroupIsomorphism A B)
{H : IsMonoidPreserving (Aop:=ring_mult) (Bop:=ring_mult) (Aunit:=one) (Bunit:=one) e}
: RingIsomorphism A B
:= @Build_RingIsomorphism' A B e (Build_IsSemiRingPreserving e _ H).(** Here is an alternative way to build a ring using the underlying abelian group. *)
R: AbGroup H: Mult R H0: One R Associative0: Associative mult LeftDistribute0: LeftDistribute mult plus RightDistribute0: RightDistribute mult plus LeftIdentity0: LeftIdentity mult 1 RightIdentity0: RightIdentity mult 1
Ring
R: AbGroup H: Mult R H0: One R Associative0: Associative mult LeftDistribute0: LeftDistribute mult plus RightDistribute0: RightDistribute mult plus LeftIdentity0: LeftIdentity mult 1 RightIdentity0: RightIdentity mult 1
Ring
R: AbGroup H: Mult R H0: One R Associative0: Associative mult LeftDistribute0: LeftDistribute mult plus RightDistribute0: RightDistribute mult plus LeftIdentity0: LeftIdentity mult 1 RightIdentity0: RightIdentity mult 1
IsRing R
R: AbGroup H: Mult R H0: One R Associative0: Associative mult LeftDistribute0: LeftDistribute mult plus RightDistribute0: RightDistribute mult plus LeftIdentity0: LeftIdentity mult 1 RightIdentity0: RightIdentity mult 1
forallzyx : R, x * y * z = x * (y * z)
R: AbGroup H: Mult R H0: One R Associative0: Associative mult LeftDistribute0: LeftDistribute mult plus RightDistribute0: RightDistribute mult plus LeftIdentity0: LeftIdentity mult 1 RightIdentity0: RightIdentity mult 1
IsRing R
R: AbGroup H: Mult R H0: One R Associative0: Associative mult LeftDistribute0: LeftDistribute mult plus RightDistribute0: RightDistribute mult plus LeftIdentity0: LeftIdentity mult 1 RightIdentity0: RightIdentity mult 1
IsMonoid R
repeatsplit; exact _.Defined.(** Scalar multiplication on the left is a group homomorphism. *)Definitiongrp_homo_rng_left_mult {R : Ring} (r : R)
: GroupHomomorphism R R
:= @Build_GroupHomomorphism R R (funs => r * s) (rng_dist_l r).(** Scalar multiplication on the right is a group homomorphism. *)Definitiongrp_homo_rng_right_mult {R : Ring} (r : R)
: GroupHomomorphism R R
:= @Build_GroupHomomorphism R R (funs => s * r) (funxy => rng_dist_r x y r).(** ** Ring movement lemmas *)SectionRingMovement.(** We adopt a similar naming convention to the [moveR_equiv] style lemmas that can be found in Types.Paths. *)Context {R : Ring} {xyz : R}.Definitionrng_moveL_Mr : - y + x = z <~> x = y + z := @grp_moveL_Mg R x y z.Definitionrng_moveL_rM : x + - z = y <~> x = y + z := @grp_moveL_gM R x y z.Definitionrng_moveR_Mr : y = - x + z <~> x + y = z := @grp_moveR_Mg R x y z.Definitionrng_moveR_rM : x = z + - y <~> x + y = z := @grp_moveR_gM R x y z.Definitionrng_moveL_Vr : x + y = z <~> y = - x + z := @grp_moveL_Vg R x y z.Definitionrng_moveL_rV : x + y = z <~> x = z + - y := @grp_moveL_gV R x y z.Definitionrng_moveR_Vr : x = y + z <~> - y + x = z := @grp_moveR_Vg R x y z.Definitionrng_moveR_rV : x = y + z <~> x + - z = y := @grp_moveR_gV R x y z.Definitionrng_moveL_M0 : - y + x = 0 <~> x = y := @grp_moveL_M1 R x y.Definitionrng_moveL_0M : x + - y = 0 <~> x = y := @grp_moveL_1M R x y.Definitionrng_moveR_M0 : 0 = - x + y <~> x = y := @grp_moveR_M1 R x y.Definitionrng_moveR_0M : 0 = y + - x <~> x = y := @grp_moveR_1M R x y.(** TODO: Movement laws about [mult] *)EndRingMovement.(** ** Wild category of rings *)Instanceisgraph_ring : IsGraph Ring
:= Build_IsGraph _ RingHomomorphism.Instanceis01cat_ring : Is01Cat Ring
:= Build_Is01Cat _ _ rng_homo_id (@rng_homo_compose).Instanceis2graph_ring : Is2Graph Ring
:= funAB => isgraph_induced (@rng_homo_map A B : _ -> (group_type _ $-> _)).Instanceis01cat_ringhomomorphism {AB : Ring} : Is01Cat (A $-> B)
:= is01cat_induced (@rng_homo_map A B).Instanceis0gpd_ringhomomorphism {AB : Ring} : Is0Gpd (A $-> B)
:= is0gpd_induced (@rng_homo_map A B).
A, B, C: Ring h: B $-> C
Is0Functor (cat_postcomp A h)
A, B, C: Ring h: B $-> C
Is0Functor (cat_postcomp A h)
A, B, C: Ring h: B $-> C
forallab : A $-> B,
(a $-> b) -> cat_postcomp A h a $-> cat_postcomp A h b
intros [f ?] [g ?] p a ; exact (ap h (p a)).Defined.
A, B, C: Ring h: A $-> B
Is0Functor (cat_precomp C h)
A, B, C: Ring h: A $-> B
Is0Functor (cat_precomp C h)
A, B, C: Ring h: A $-> B
forallab : B $-> C,
(a $-> b) -> cat_precomp C h a $-> cat_precomp C h b
intros [f ?] [g ?] p a ; exact (p (h a)).Defined.(** Ring forms a 1-category. *)
forall (ab : Ring) (f : a $-> b),
?CatIsEquiv' a b f -> ?CatEquiv' a b
forallab : Ring, ?CatEquiv' a b -> b $-> a
forall (ab : Ring) (f : ?CatEquiv' a b),
?CatIsEquiv' a b (?cate_fun' a b f)
forall (ab : Ring) (f : a $-> b)
(fe : ?CatIsEquiv' a b f),
?cate_fun' a b (?cate_buildequiv' a b f fe) $== f
forall (ab : Ring) (f : ?CatEquiv' a b),
?cate_inv' a b f $o ?cate_fun' a b f $== Id a
forall (ab : Ring) (f : ?CatEquiv' a b),
?cate_fun' a b f $o ?cate_inv' a b f $== Id b
forall (ab : Ring) (f : a $-> b) (g : b $-> a),
f $o g $== Id b ->
g $o f $== Id a -> ?CatIsEquiv' a b f
Ring -> Ring -> Type
exact RingIsomorphism.
forallab : Ring, (a $-> b) -> Type
exact (funGHf => IsEquiv f).
forallab : Ring, RingIsomorphism a b -> a $-> b
intros G H f; exact f.
forall (ab : Ring) (f : a $-> b),
(fun (GH : Ring) (f0 : G $-> H) => IsEquiv f0) a b f ->
RingIsomorphism a b
exact Build_RingIsomorphism.
forallab : Ring, RingIsomorphism a b -> b $-> a
intros G H; exact rng_iso_inverse.
forall (ab : Ring) (f : RingIsomorphism a b),
(fun (GH : Ring) (f0 : G $-> H) => IsEquiv f0) a b
((fun (GH : Ring) (f0 : RingIsomorphism G H) =>
rng_iso_homo f0) a b f)
cbn; exact _.
forall (ab : Ring) (f : a $-> b)
(fe : (fun (GH : Ring) (f0 : G $-> H) => IsEquiv f0)
a b f),
(fun (GH : Ring) (f0 : RingIsomorphism G H) =>
rng_iso_homo f0) a b
{| rng_iso_homo := f; isequiv_rng_iso_homo := fe |} $==
f
reflexivity.
forall (ab : Ring) (f : RingIsomorphism a b),
(fun (GH : Ring) (x : RingIsomorphism G H) =>
rng_iso_homo (rng_iso_inverse x)) a b f $o
(fun (GH : Ring) (f0 : RingIsomorphism G H) =>
rng_iso_homo f0) a b f $== Id a
intros ????; apply eissect.
forall (ab : Ring) (f : RingIsomorphism a b),
(fun (GH : Ring) (f0 : RingIsomorphism G H) =>
rng_iso_homo f0) a b f $o
(fun (GH : Ring) (x : RingIsomorphism G H) =>
rng_iso_homo (rng_iso_inverse x)) a b f $== Id b
intros ????; apply eisretr.
forall (ab : Ring) (f : a $-> b) (g : b $-> a),
f $o g $== Id b ->
g $o f $== Id a ->
(fun (GH : Ring) (f0 : G $-> H) => IsEquiv f0) a b f
G, H: Ring f: G $-> H g: H $-> G p: f $o g $== Id H q: g $o f $== Id G
(fun (GH : Ring) (f : G $-> H) => IsEquiv f) G H f
exact (isequiv_adjointify f g p q).Defined.(** ** Subrings *)(** TODO: factor out this definition as a submonoid *)(** A subring is a subgroup of the underlying abelian group of a ring that is closed under multiplication and contains [1]. *)ClassIsSubring {R : Ring} (S : R -> Type) := {
issubring_issubgroup :: IsSubgroup S;
issubring_mult {x y} : S x -> S y -> S (x * y);
issubring_one : S 1;
}.Definitionissig_IsSubring {R : Ring} (S : R -> Type)
: _ <~> IsSubring S
:= ltac:(issig).
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
IsSubring S
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
IsSubring S
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
IsSubgroup S
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
forallxy : R, S x -> S y -> S (x * y)
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
S 1
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
IsSubgroup S
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
forallx : R, IsHProp (S x)
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
S mon_unit
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
forallxy : R, S x -> S y -> S (sg_op x (inv y))
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
forallx : R, IsHProp (S x)
exact _.
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
S mon_unit
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1 p:= H1 11 H3 H3: S (1 - 1)
S mon_unit
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1 p: S 0
S mon_unit
exact p.
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
forallxy : R, S x -> S y -> S (sg_op x (inv y))
exact H1.
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
forallxy : R, S x -> S y -> S (x * y)
exact H2.
R: Ring S: R -> Type H: forallx : R, IsHProp (S x) H1: forallxy : R, S x -> S y -> S (x - y) H2: forallxy : R, S x -> S y -> S (x * y) H3: S 1
R: Ring S: Subgroup R H1: forallxy : R, S x -> S y -> S (x * y) H2: S 1
Subring R
R: Ring S: Subgroup R H1: forallxy : R, S x -> S y -> S (x * y) H2: S 1
Subring R
R: Ring S: Subgroup R H1: forallxy : R, S x -> S y -> S (x * y) H2: S 1
IsSubring S
R: Ring S: Subgroup R H1: forallxy : R, S x -> S y -> S (x * y) H2: S 1
IsSubgroup S
R: Ring S: Subgroup R H1: forallxy : R, S x -> S y -> S (x * y) H2: S 1
forallxy : R, S x -> S y -> S (x * y)
R: Ring S: Subgroup R H1: forallxy : R, S x -> S y -> S (x * y) H2: S 1
S 1
R: Ring S: Subgroup R H1: forallxy : R, S x -> S y -> S (x * y) H2: S 1
IsSubgroup S
exact _.
R: Ring S: Subgroup R H1: forallxy : R, S x -> S y -> S (x * y) H2: S 1
forallxy : R, S x -> S y -> S (x * y)
exact H1.
R: Ring S: Subgroup R H1: forallxy : R, S x -> S y -> S (x * y) H2: S 1
S 1
exact H2.Defined.DefinitionBuild_Subring' {R : Ring} (S : R -> Type)
(H : forallx, IsHProp (S x))
(H1 : forallxy, S x -> S y -> S (x - y))
(H2 : forallxy, S x -> S y -> S (x * y))
(H3 : S 1)
: Subring R
:= Build_Subring R S (Build_IsSubring' S H H1 H2 H3).(** The underlying subgroup of a subring. *)Coercionsubgroup_subring {R} : Subring R -> Subgroup R
:= funS => Build_Subgroup R S _.(** The ring given by a subring. *)
R: Ring S: Subring R
Ring
R: Ring S: Subring R
Ring
R: Ring S: Subring R
Mult S
R: Ring S: Subring R
One S
R: Ring S: Subring R
Associative mult
R: Ring S: Subring R
LeftDistribute mult plus
R: Ring S: Subring R
RightDistribute mult plus
R: Ring S: Subring R
LeftIdentity mult 1
R: Ring S: Subring R
RightIdentity mult 1
R: Ring S: Subring R
Mult S
R: Ring S: Subring R
One S
R: Ring S: Subring R x, y, z: S
(x * (y * z)).1 = (x * y * z).1
R: Ring S: Subring R a, b, c: S
(a * (b + c)).1 = (a * b + a * c).1
R: Ring S: Subring R a, b, c: S
((a + b) * c).1 = (a * c + b * c).1
R: Ring S: Subring R y: S
(1 * y).1 = y.1
R: Ring S: Subring R x: S
(x * 1).1 = x.1
R: Ring S: Subring R
Mult S
R: Ring S: Subring R r: R proj2: S r s: R proj0: S s
S (r * s)
byapply issubring_mult.
R: Ring S: Subring R
One S
R: Ring S: Subring R
S 1
exact issubring_one.
R: Ring S: Subring R x, y, z: S
(x * (y * z)).1 = (x * y * z).1
napply rng_mult_assoc.
R: Ring S: Subring R a, b, c: S
(a * (b + c)).1 = (a * b + a * c).1
napply rng_dist_l.
R: Ring S: Subring R a, b, c: S
((a + b) * c).1 = (a * c + b * c).1
napply rng_dist_r.
R: Ring S: Subring R y: S
(1 * y).1 = y.1
napply rng_mult_one_l.
R: Ring S: Subring R x: S
(x * 1).1 = x.1
napply rng_mult_one_r.Defined.(** ** Product ring *)
uncurry (ring_product_corec R S T)
o (funf : R $-> S × T =>
(ring_product_fst $o f, ring_product_snd $o f)) ==
idmap
H: Funext R, S, T: Ring
(funf : R $-> S × T =>
(ring_product_fst $o f, ring_product_snd $o f))
o uncurry (ring_product_corec R S T) == idmap
H: Funext R, S, T: Ring
uncurry (ring_product_corec R S T)
o (funf : R $-> S × T =>
(ring_product_fst $o f, ring_product_snd $o f)) ==
idmap
H: Funext R, S, T: Ring f: R $-> S × T
uncurry (ring_product_corec R S T)
(ring_product_fst $o f, ring_product_snd $o f) = f
byapply path_hom.
H: Funext R, S, T: Ring
(funf : R $-> S × T =>
(ring_product_fst $o f, ring_product_snd $o f))
o uncurry (ring_product_corec R S T) == idmap
H: Funext R, S, T: Ring f: R $-> S g: R $-> T
(ring_product_fst $o
uncurry (ring_product_corec R S T) (f, g),
ring_product_snd $o
uncurry (ring_product_corec R S T) (f, g)) = (f, g)
H: Funext R, S, T: Ring f: R $-> S g: R $-> T
fst
(ring_product_fst $o
uncurry (ring_product_corec R S T) (f, g),
ring_product_snd $o
uncurry (ring_product_corec R S T) (f, g)) =
fst (f, g)
H: Funext R, S, T: Ring f: R $-> S g: R $-> T
snd
(ring_product_fst $o
uncurry (ring_product_corec R S T) (f, g),
ring_product_snd $o
uncurry (ring_product_corec R S T) (f, g)) =
snd (f, g)
1,2: byapply path_hom.Defined.
HasBinaryProducts Ring
HasBinaryProducts Ring
R, S: Ring
BinaryProduct R S
R, S: Ring
Ring
R, S: Ring
?cat_binprod' $-> R
R, S: Ring
?cat_binprod' $-> S
R, S: Ring
forallz : Ring,
(z $-> R) -> (z $-> S) -> z $-> ?cat_binprod'
R, S: Ring
forall (z : Ring) (f : z $-> R) (g : z $-> S),
?cat_pr1 $o ?cat_binprod_corec z f g $== f
R, S: Ring
forall (z : Ring) (f : z $-> R) (g : z $-> S),
?cat_pr2 $o ?cat_binprod_corec z f g $== g
R, S: Ring
forall (z : Ring) (fg : z $-> ?cat_binprod'),
?cat_pr1 $o f $== ?cat_pr1 $o g ->
?cat_pr2 $o f $== ?cat_pr2 $o g -> f $== g
R, S: Ring
Ring
exact (R × S).
R, S: Ring
R × S $-> R
exact ring_product_fst.
R, S: Ring
R × S $-> S
exact ring_product_snd.
R, S: Ring
forallz : Ring, (z $-> R) -> (z $-> S) -> z $-> R × S
exact (funT => ring_product_corec T R S).
R, S: Ring
forall (z : Ring) (f : z $-> R) (g : z $-> S),
ring_product_fst $o
(funT : Ring => ring_product_corec T R S) z f g $== f
cbn; reflexivity.
R, S: Ring
forall (z : Ring) (f : z $-> R) (g : z $-> S),
ring_product_snd $o
(funT : Ring => ring_product_corec T R S) z f g $== g
cbn; reflexivity.
R, S: Ring
forall (z : Ring) (fg : z $-> R × S),
ring_product_fst $o f $== ring_product_fst $o g ->
ring_product_snd $o f $== ring_product_snd $o g ->
f $== g
R, S, T: Ring f, g: T $-> R × S p: ring_product_fst $o f $== ring_product_fst $o g q: ring_product_snd $o f $== ring_product_snd $o g x: T
f x = g x
exact (path_prod' (p x) (q x)).Defined.(** ** Image ring *)(** The image of a ring homomorphism *)
R, S: Ring f: R $-> S
Subring S
R, S: Ring f: R $-> S
Subring S
R, S: Ring f: R $-> S
forallxy : S,
grp_image f x -> grp_image f y -> grp_image f (x * y)
R, S: Ring f: R $-> S
grp_image f 1
R, S: Ring f: R $-> S
forallxy : S,
grp_image f x -> grp_image f y -> grp_image f (x * y)
R, S: Ring f: R $-> S
forallxy : S,
Tr (-1) {x0 : R & f x0 = x} ->
Tr (-1) {x0 : R & f x0 = y} ->
Tr (-1) {x0 : R & f x0 = x * y}
R, S: Ring f: R $-> S x, y: S p: Tr (-1) {x0 : R & f x0 = x} q: Tr (-1) {x : R & f x = y}
Tr (-1) {x0 : R & f x0 = x * y}
R, S: Ring f: R $-> S x, y: S q: {x : R & f x = y} p: {x0 : R & f x0 = x}
{x0 : R & f x0 = x * y}
R, S: Ring f: R $-> S x, y: S b: R q': f b = y a: R p': f a = x
{x0 : R & f x0 = x * y}
R, S: Ring f: R $-> S x, y: S b: R q': f b = y a: R p': f a = x
f (a * b) = x * y
R, S: Ring f: R $-> S x, y: S b: R q': f b = y a: R p': f a = x
f a * f b = x * y
f_ap.
R, S: Ring f: R $-> S
grp_image f 1
R, S: Ring f: R $-> S
{x : R & f x = 1}
R, S: Ring f: R $-> S
f 1 = 1
exact (rng_homo_one f).Defined.
R, S: Ring f: RingHomomorphism R S
(rng_image f : Ring) $-> S
R, S: Ring f: RingHomomorphism R S
(rng_image f : Ring) $-> S
R, S: Ring f: RingHomomorphism R S
rng_image f -> S
R, S: Ring f: RingHomomorphism R S
IsSemiRingPreserving ?rng_homo_map
R, S: Ring f: RingHomomorphism R S
IsSemiRingPreserving pr1
repeatsplit.Defined.(** Image of a surjective ring homomorphism *)
R, S: Ring f: RingHomomorphism R S issurj: IsConnMap (Tr (-1)) f
(rng_image f : Ring) ≅ S
R, S: Ring f: RingHomomorphism R S issurj: IsConnMap (Tr (-1)) f
(rng_image f : Ring) ≅ S
R, S: Ring f: RingHomomorphism R S issurj: IsConnMap (Tr (-1)) f
RingHomomorphism (rng_image f) S
R, S: Ring f: RingHomomorphism R S issurj: IsConnMap (Tr (-1)) f
IsEquiv ?rng_iso_homo
R, S: Ring f: RingHomomorphism R S issurj: IsConnMap (Tr (-1)) f
IsEquiv (rng_homo_image_incl f)
exact _.Defined.(** ** Opposite Ring *)(** Given a ring [R] we can reverse the order of the multiplication to get another ring [R^op]. *)
Ring -> Ring
Ring -> Ring
(** Let's carefully pull apart the ring structure and put it back together. Unfortunately, our definition of ring has some redundant data such as multiple hset assumptions, due to the mixing of algebraic structures. This isn't a problem in practice, but it does mean using typeclass inference here will pick up the wrong instance, therefore we carefully put it back together. See test/Algebra/Rings/Ring.v for a test checking this operation is definitionally involutive. *)
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
Ring
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
AbGroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
Mult ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
One ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
IsRing ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
forallzyx : ?ring_abgroup, x * y * z = x * (y * z)
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
AbGroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
Mult ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
One ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
IsAbGroup ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
IsMonoid ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
LeftDistribute canonical_names.mult plus
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
RightDistribute canonical_names.mult plus
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
forallzyx : ?ring_abgroup, x * y * z = x * (y * z)
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
AbGroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
Mult ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
One ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
IsAbGroup ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
IsSemiGroup ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
LeftIdentity sg_op mon_unit
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
RightIdentity sg_op mon_unit
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
LeftDistribute canonical_names.mult plus
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
RightDistribute canonical_names.mult plus
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
forallzyx : ?ring_abgroup, x * y * z = x * (y * z)
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
AbGroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
Mult ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
One ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
IsAbGroup ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
IsHSet ?ring_abgroup
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
Associative sg_op
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
LeftIdentity sg_op mon_unit
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
RightIdentity sg_op mon_unit
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
LeftDistribute canonical_names.mult plus
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
RightDistribute canonical_names.mult plus
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
forallzyx : ?ring_abgroup, x * y * z = x * (y * z)
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
AbGroup
exact R.
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
Mult R
exact (funxy => mult y x).
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
One R
exact one.
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
IsAbGroup R
exact is_abgroup.
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
IsHSet R
exact monoid_ishset.
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
Associative sg_op
exact mult_assoc_opp.
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
LeftIdentity sg_op mon_unit
exact ri.
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
RightIdentity sg_op mon_unit
exact li.
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
LeftDistribute canonical_names.mult plus
exact (funxyz => rd y z x).
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
RightDistribute canonical_names.mult plus
exact (funxyz => ld z x y).
R: AbGroup mult: Mult R one: One R is_abgroup: IsAbGroup R monoid_ishset: IsHSet R mult_assoc: Associative sg_op li: LeftIdentity sg_op mon_unit ri: RightIdentity sg_op mon_unit ld: LeftDistribute canonical_names.mult plus rd: RightDistribute canonical_names.mult plus mult_assoc_opp: forallzyx : R,
x * y * z = x * (y * z)
forallzyx : R, x * y * z = x * (y * z)
exact mult_assoc.Defined.(** The opposite ring is a functor. *)
Is0Functor rng_op
Is0Functor rng_op
forallab : Ring, (a $-> b) -> rng_op a $-> rng_op b
R, S: Ring f: R $-> S
rng_op R $-> rng_op S
R, S: Ring f: R $-> S
GroupHomomorphism (rng_op R) (rng_op S)
R, S: Ring f: R $-> S
IsMonoidPreserving ?map
R, S: Ring f: R $-> S
GroupHomomorphism (rng_op R) (rng_op S)
exact f.
R, S: Ring f: R $-> S
IsMonoidPreserving f
R, S: Ring f: R $-> S
IsSemiGroupPreserving f
R, S: Ring f: R $-> S
IsUnitPreserving f
R, S: Ring f: R $-> S
IsSemiGroupPreserving f
exact (funxy => rng_homo_mult f y x).
R, S: Ring f: R $-> S
IsUnitPreserving f
exact (rng_homo_one f).Defined.
Is1Functor rng_op
Is1Functor rng_op
forall (ab : Ring) (fg : a $-> b),
f $== g -> fmap rng_op f $== fmap rng_op g
foralla : Ring, fmap rng_op (Id a) $== Id (rng_op a)
forall (abc : Ring) (f : a $-> b) (g : b $-> c),
fmap rng_op (g $o f) $==
fmap rng_op g $o fmap rng_op f
forall (ab : Ring) (fg : a $-> b),
f $== g -> fmap rng_op f $== fmap rng_op g
R, S: Ring f, g: R $-> S p: f $== g
fmap rng_op f $== fmap rng_op g
exact p.
foralla : Ring, fmap rng_op (Id a) $== Id (rng_op a)
intros R; cbn; reflexivity.
forall (abc : Ring) (f : a $-> b) (g : b $-> c),
fmap rng_op (g $o f) $==
fmap rng_op g $o fmap rng_op f
intros R S T f g; cbn; reflexivity.Defined.(** ** Powers *)(** Powers of ring elements *)Definitionrng_power {R : Ring} (x : R) (n : nat) : R := nat_iter n (x *.) ring_one.(** Power laws *)
R: Ring x: R n, m: nat
rng_power x n * rng_power x m = rng_power x (n + m)
R: Ring x: R n, m: nat
rng_power x n * rng_power x m = rng_power x (n + m)
R: Ring x: R m: nat
rng_power x 0 * rng_power x m = rng_power x (0 + m)
R: Ring x: R n, m: nat IHn: rng_power x n * rng_power x m = rng_power x (n + m)
rng_power x n.+1 * rng_power x m =
rng_power x (n.+1 + m)
R: Ring x: R n, m: nat IHn: rng_power x n * rng_power x m = rng_power x (n + m)
rng_power x n.+1 * rng_power x m =
rng_power x (n.+1 + m)
R: Ring x: R n, m: nat IHn: rng_power x n * rng_power x m = rng_power x (n + m)
x * (nat_iter n (mult x) ring_one * rng_power x m) =
rng_power x (n.+1 + m)
exact (ap (x *.) IHn).Defined.(** ** Finite Sums *)(** Ring multiplication distributes over finite sums on the left. *)
R: Ring n: nat f: forallk : nat, (k < n)%nat -> R r: R
r * ab_sum n f =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) => r * f k Hk)
R: Ring n: nat f: forallk : nat, (k < n)%nat -> R r: R
r * ab_sum n f =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) => r * f k Hk)
R: Ring f: forallk : nat, (k < 0)%nat -> R r: R
r * ab_sum 0 f =
ab_sum 0
(fun (k : nat) (Hk : (k < 0)%nat) => r * f k Hk)
R: Ring n: nat f: forallk : nat, (k < n.+1)%nat -> R r: R IHn: forallf : forallk : nat, (k < n)%nat -> R,
r * ab_sum n f = ab_sum n (fun (k : nat) (Hk : (k < n)%nat) => r * f k Hk)
r * ab_sum n.+1 f =
ab_sum n.+1
(fun (k : nat) (Hk : (k < n.+1)%nat) => r * f k Hk)
R: Ring n: nat f: forallk : nat, (k < n.+1)%nat -> R r: R IHn: forallf : forallk : nat, (k < n)%nat -> R,
r * ab_sum n f = ab_sum n (fun (k : nat) (Hk : (k < n)%nat) => r * f k Hk)
r * ab_sum n.+1 f =
ab_sum n.+1
(fun (k : nat) (Hk : (k < n.+1)%nat) => r * f k Hk)
lhs napply rng_dist_l; simpl; f_ap.Defined.(** Ring multiplication distributes over finite sums on the right. *)
R: Ring n: nat f: forallk : nat, (k < n)%nat -> R r: R
ab_sum n f * r =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) => f k Hk * r)
R: Ring n: nat f: forallk : nat, (k < n)%nat -> R r: R
ab_sum n f * r =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) => f k Hk * r)
R: Ring f: forallk : nat, (k < 0)%nat -> R r: R
ab_sum 0 f * r =
ab_sum 0
(fun (k : nat) (Hk : (k < 0)%nat) => f k Hk * r)
R: Ring n: nat f: forallk : nat, (k < n.+1)%nat -> R r: R IHn: forallf : forallk : nat, (k < n)%nat -> R,
ab_sum n f * r = ab_sum n (fun (k : nat) (Hk : (k < n)%nat) => f k Hk * r)
ab_sum n.+1 f * r =
ab_sum n.+1
(fun (k : nat) (Hk : (k < n.+1)%nat) => f k Hk * r)
R: Ring n: nat f: forallk : nat, (k < n.+1)%nat -> R r: R IHn: forallf : forallk : nat, (k < n)%nat -> R,
ab_sum n f * r = ab_sum n (fun (k : nat) (Hk : (k < n)%nat) => f k Hk * r)
ab_sum n.+1 f * r =
ab_sum n.+1
(fun (k : nat) (Hk : (k < n.+1)%nat) => f k Hk * r)
lhs napply rng_dist_r; simpl; f_ap.Defined.(** ** Invertible elements *)(** An element [x] of a ring [R] is left invertible if there exists an element [y] such that [y * x = 1]. *)ClassIsLeftInvertible (R : Ring) (x : R) := {
left_inverse_elem : R;
left_inverse_eq : left_inverse_elem * x = 1;
}.Arguments left_inverse_elem {R} x {_}.Arguments left_inverse_eq {R} x {_}.Definitionissig_IsLeftInvertible {R : Ring} (x : R)
: _ <~> IsLeftInvertible R x
:= ltac:(issig).(** An element [x] of a ring [R] is right invertible if there exists an element [y] such that [x * y = 1]. We state this as a left invertible element of the opposite ring. *)ClassIsRightInvertible (R : Ring) (x : R)
:= isleftinvertible_rng_op :: IsLeftInvertible (rng_op R) x.Definitionright_inverse_elem {R} x `{!IsRightInvertible R x} : R
:= left_inverse_elem (R:=rng_op R) x.Definitionright_inverse_eq {R} x `{!IsRightInvertible R x}
: x * right_inverse_elem x = 1
:= left_inverse_eq (R:=rng_op R) x.(** An element [x] of a ring [R] is invertible if it is both left and right invertible. *)ClassIsInvertible (R : Ring) (x : R) := Build_IsInvertible' {
isleftinvertible_isinvertible :: IsLeftInvertible R x;
isrightinvertible_isinvertible :: IsRightInvertible R x;
}.(** We can show an element is invertible by providing an inverse element which is a left and right inverse simultaneously. We will later show that the two inverses of an invertible element must be equal anyway. *)
R: Ring x, inv: R inv_l: inv * x = 1 inv_r: x * inv = 1
IsInvertible R x
R: Ring x, inv: R inv_l: inv * x = 1 inv_r: x * inv = 1
IsInvertible R x
R: Ring x, inv: R inv_l: inv * x = 1 inv_r: x * inv = 1
IsLeftInvertible R x
R: Ring x, inv: R inv_l: inv * x = 1 inv_r: x * inv = 1
IsRightInvertible R x
R: Ring x, inv: R inv_l: inv * x = 1 inv_r: x * inv = 1
IsLeftInvertible R x
byexistsinv.
R: Ring x, inv: R inv_l: inv * x = 1 inv_r: x * inv = 1
IsRightInvertible R x
R: Ring x, inv: R inv_l: inv * x = 1 inv_r: x * inv = 1
IsLeftInvertible (rng_op R) x
byexists (inv : rng_op R).Defined.(** The invertible elements in [R] and [rng_op R] agree, by swapping the proofs of left and right invertibility. *)
R: Ring x: R IsInvertible0: IsInvertible R x
IsInvertible (rng_op R) x
R: Ring x: R IsInvertible0: IsInvertible R x
IsInvertible (rng_op R) x
R: Ring x: R IsInvertible0: IsInvertible R x
IsLeftInvertible (rng_op R) x
R: Ring x: R IsInvertible0: IsInvertible R x
IsRightInvertible (rng_op R) x
R: Ring x: R IsInvertible0: IsInvertible R x
IsLeftInvertible (rng_op R) x
exact (isrightinvertible_isinvertible).
R: Ring x: R IsInvertible0: IsInvertible R x
IsRightInvertible (rng_op R) x
exact (isleftinvertible_isinvertible).Defined.(** *** Uniqueness of inverses *)(** This general lemma will be used for uniqueness results. *)
R: Ring x, x', x'': R p: x' * x = 1 q: x * x'' = 1
x' = x''
R: Ring x, x', x'': R p: x' * x = 1 q: x * x'' = 1
x' = x''
R: Ring x, x', x'': R p: x' * x = 1 q: x * x'' = 1
x' = 1 * x''
R: Ring x, x', x'': R p: x' * x = 1 q: x * x'' = 1
x' = x' * x * x''
R: Ring x, x', x'': R p: x' * x = 1 q: x * x'' = 1
x' = x' * (x * x'')
R: Ring x, x', x'': R p: x' * x = 1 q: x * x'' = 1
x' = x' * 1
R: Ring x, x', x'': R p: x' * x = 1 q: x * x'' = 1
x' * 1 = x'
apply rng_mult_one_r.Defined.(** The left and right inverse of an invertible element are necessarily equal. *)
R: Ring x: R IsInvertible0: IsInvertible R x
left_inverse_elem x = right_inverse_elem x
R: Ring x: R IsInvertible0: IsInvertible R x
left_inverse_elem x = right_inverse_elem x
R: Ring x: R IsInvertible0: IsInvertible R x
left_inverse_elem x * x = 1
R: Ring x: R IsInvertible0: IsInvertible R x
x * right_inverse_elem x = 1
R: Ring x: R IsInvertible0: IsInvertible R x
left_inverse_elem x * x = 1
apply left_inverse_eq.
R: Ring x: R IsInvertible0: IsInvertible R x
x * right_inverse_elem x = 1
apply right_inverse_eq.Defined.(** It is therefore well-defined to talk about the inverse of an invertible element. *)Definitioninverse_elem {R : Ring} (x : R) `{IsInvertible R x} : R
:= left_inverse_elem x.(** Left cancellation for an invertible element. *)
R: Ring x: R H: IsInvertible R x
inverse_elem x * x = 1
R: Ring x: R H: IsInvertible R x
inverse_elem x * x = 1
apply left_inverse_eq.Defined.(** Right cancellation for an invertible element. *)
R: Ring x: R H: IsInvertible R x
x * inverse_elem x = 1
R: Ring x: R H: IsInvertible R x
x * inverse_elem x = 1
R: Ring x: R H: IsInvertible R x
x * inverse_elem x = x * right_inverse_elem x
R: Ring x: R H: IsInvertible R x
inverse_elem x = right_inverse_elem x
apply path_left_inverse_elem_right_inverse_elem.Defined.(** Equal elements have equal inverses. Note that we don't require that the proofs of invertibility are equal (over [p]). It follows that the inverse of an invertible element [x] depends only on [x]. *)
R: Ring x, y: R H: IsInvertible R x H0: IsInvertible R y p: x = y
inverse_elem x = inverse_elem y
R: Ring x, y: R H: IsInvertible R x H0: IsInvertible R y p: x = y
inverse_elem x = inverse_elem y
R: Ring x: R H, H0: IsInvertible R x
inverse_elem x = inverse_elem x
R: Ring x: R H, H0: IsInvertible R x
inverse_elem x * x = 1
R: Ring x: R H, H0: IsInvertible R x
x * inverse_elem x = 1
R: Ring x: R H, H0: IsInvertible R x
inverse_elem x * x = 1
apply rng_inv_l.
R: Ring x: R H, H0: IsInvertible R x
x * inverse_elem x = 1
apply rng_inv_r.Defined.(** We can show that being invertible is equivalent to having an inverse element that is simultaneously a left and right inverse. *)
R: Ring x: R
{inv : R & ((mult inv x = 1) * (mult x inv = 1))%type} <~>
IsInvertible R x
R: Ring x: R
{inv : R & ((mult inv x = 1) * (mult x inv = 1))%type} <~>
IsInvertible R x
R: Ring x: R
{inv : R & ((mult inv x = 1) * (mult x inv = 1))%type} <~>
{i : IsInvertible R x &
right_inverse_elem x = left_inverse_elem x}
R: Ring x: R
{i : IsInvertible R x &
right_inverse_elem x = left_inverse_elem x} <~>
IsInvertible R x
R: Ring x: R
{i : IsInvertible R x &
right_inverse_elem x = left_inverse_elem x} <~>
IsInvertible R x
R: Ring x: R i: IsInvertible R x
Contr (right_inverse_elem x = left_inverse_elem x)
R: Ring x: R i: IsInvertible R x
right_inverse_elem x = left_inverse_elem x
symmetry; apply path_left_inverse_elem_right_inverse_elem.Defined.(** Being invertible is a proposition. *)
R: Ring x: R
IsHProp (IsInvertible R x)
R: Ring x: R
IsHProp (IsInvertible R x)
R: Ring x: R
IsHProp
{inv : R &
((mult inv x = 1) * (mult x inv = 1))%type}
R: Ring x, y: R p1: y * x = 1 p2: x * y = 1 z: R q1: z * x = 1 q2: x * z = 1
(y; (p1, p2)) = (z; (q1, q2))
R: Ring x, y: R p1: y * x = 1 p2: x * y = 1 z: R q1: z * x = 1 q2: x * z = 1
y = z
exact (path_left_right_inverse x y z p1 q2).Defined.(** *** Closure of invertible elements under multiplication *)(** Left invertible elements are closed under multiplication. *)
R: Ring x, y: R
IsLeftInvertible R x ->
IsLeftInvertible R y -> IsLeftInvertible R (x * y)
R: Ring x, y: R
IsLeftInvertible R x ->
IsLeftInvertible R y -> IsLeftInvertible R (x * y)
R: Ring x, y, x': R p: x' * x = 1 y': R q: y' * y = 1
IsLeftInvertible R (x * y)
R: Ring x, y, x': R p: x' * x = 1 y': R q: y' * y = 1
y' * x' * (x * y) = 1
R: Ring x, y, x': R p: x' * x = 1 y': R q: y' * y = 1
y' * x' * (x * y) = y' * y
R: Ring x, y, x': R p: x' * x = 1 y': R q: y' * y = 1
y' * x' * x * y = y' * y
R: Ring x, y, x': R p: x' * x = 1 y': R q: y' * y = 1
y' * x' * x = y'
R: Ring x, y, x': R p: x' * x = 1 y': R q: y' * y = 1
y' * x' * x = y' * 1
R: Ring x, y, x': R p: x' * x = 1 y': R q: y' * y = 1
y' * (x' * x) = y' * 1
f_ap.Defined.(** Right invertible elements are closed under multiplication. *)
R: Ring x, y: R
IsRightInvertible R x ->
IsRightInvertible R y -> IsRightInvertible R (x * y)
R: Ring x, y: R
IsRightInvertible R x ->
IsRightInvertible R y -> IsRightInvertible R (x * y)
R: Ring x, y: R
IsRightInvertible R x ->
IsRightInvertible R y ->
IsRightInvertible R (ring_mult y x)
R: Ring x, y: R
IsLeftInvertible (rng_op R) x ->
IsLeftInvertible (rng_op R) y ->
IsLeftInvertible (rng_op R) (ring_mult y x)
exact _.Defined.(** Invertible elements are closed under multiplication. *)Instanceisinvertible_mult {R : Ring} (xy : R)
: IsInvertible R x -> IsInvertible R y -> IsInvertible R (x * y)
:= {}.(** Left invertible elements are closed under negation. *)
R: Ring x: R
IsLeftInvertible R x -> IsLeftInvertible R (- x)
R: Ring x: R
IsLeftInvertible R x -> IsLeftInvertible R (- x)
R: Ring x: R H: IsLeftInvertible R x
IsLeftInvertible R (- x)
R: Ring x: R H: IsLeftInvertible R x
- left_inverse_elem x * - x = 1
R: Ring x: R H: IsLeftInvertible R x
left_inverse_elem x * x = 1
apply left_inverse_eq.Defined.(** Right invertible elements are closed under negation. *)
R: Ring x: R
IsRightInvertible R x -> IsRightInvertible R (- x)
R: Ring x: R
IsRightInvertible R x -> IsRightInvertible R (- x)
R: Ring x: R H: IsRightInvertible R x
IsRightInvertible R (- x)
rapply isleftinvertible_neg.Defined.(** Invertible elements are closed under negation. *)Instanceisinvertible_neg {R : Ring} (x : R)
: IsInvertible R x -> IsInvertible R (-x)
:= {}.(** Inverses of left invertible elements are themselves right invertible. *)
R: Ring x: R H: IsLeftInvertible R x
IsRightInvertible R (left_inverse_elem x)
R: Ring x: R H: IsLeftInvertible R x
IsRightInvertible R (left_inverse_elem x)
R: Ring x: R H: IsLeftInvertible R x
x * left_inverse_elem x = 1
exact (left_inverse_eq x).Defined.(** Inverses of right invertible elements are themselves left invertible. *)
R: Ring x: R H: IsRightInvertible R x
IsLeftInvertible R (right_inverse_elem x)
R: Ring x: R H: IsRightInvertible R x
IsLeftInvertible R (right_inverse_elem x)
R: Ring x: R H: IsRightInvertible R x
x * right_inverse_elem x = 1
exact (right_inverse_eq x).Defined.(** Inverses of invertible elements are themselves invertible. We take both inverses of [inverse_elem x] to be [x]. *)
R: Ring x: R H: IsInvertible R x
IsInvertible R (inverse_elem x)
R: Ring x: R H: IsInvertible R x
IsInvertible R (inverse_elem x)
R: Ring x: R H: IsInvertible R x
IsLeftInvertible R (inverse_elem x)
R: Ring x: R H: IsInvertible R x
IsRightInvertible R (inverse_elem x)
R: Ring x: R H: IsInvertible R x
IsLeftInvertible R (inverse_elem x)
existsx; apply rng_inv_r.
R: Ring x: R H: IsInvertible R x
IsRightInvertible R (inverse_elem x)
apply isrightinvertible_left_inverse_elem.Defined.(** Since [inverse_elem (inverse_elem x) = x], we get the following equivalence. *)
R: Ring x, y: R H: IsInvertible R x H0: IsInvertible R y
x = y <~> inverse_elem x = inverse_elem y
R: Ring x, y: R H: IsInvertible R x H0: IsInvertible R y
x = y <~> inverse_elem x = inverse_elem y
R: Ring x, y: R H: IsInvertible R x H0: IsInvertible R y
x = y -> inverse_elem x = inverse_elem y
R: Ring x, y: R H: IsInvertible R x H0: IsInvertible R y
inverse_elem x = inverse_elem y -> x = y
R: Ring x, y: R H: IsInvertible R x H0: IsInvertible R y
x = y -> inverse_elem x = inverse_elem y
exact (isinvertible_unique x y).
R: Ring x, y: R H: IsInvertible R x H0: IsInvertible R y
inverse_elem x = inverse_elem y -> x = y
exact (isinvertible_unique (inverse_elem x) (inverse_elem y)).Defined.(** [1] is always invertible, and by the above [-1]. *)
R: Ring
IsInvertible R 1
R: Ring
IsInvertible R 1
R: Ring
R
R: Ring
?inv * 1 = 1
R: Ring
1 * ?inv = 1
R: Ring
R
exact one.
R: Ring
1 * 1 = 1
apply rng_mult_one_l.
R: Ring
1 * 1 = 1
apply rng_mult_one_l.Defined.(** Ring homomorphisms preserve invertible elements. *)
R, S: Ring f: R $-> S
forallx : R, IsInvertible R x -> IsInvertible S (f x)
R, S: Ring f: R $-> S
forallx : R, IsInvertible R x -> IsInvertible S (f x)
R, S: Ring f: R $-> S x: R H: IsInvertible R x
IsInvertible S (f x)
R, S: Ring f: R $-> S x: R H: IsInvertible R x
S
R, S: Ring f: R $-> S x: R H: IsInvertible R x
?inv * f x = 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
f x * ?inv = 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
f (inverse_elem x) * f x = 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
f x * f (inverse_elem x) = 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
f (inverse_elem x * x) = 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
f (x * inverse_elem x) = 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
f (inverse_elem x * x) = f 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
f (x * inverse_elem x) = f 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
inverse_elem x * x = 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
x * inverse_elem x = 1
R, S: Ring f: R $-> S x: R H: IsInvertible R x
inverse_elem x * x = 1
exact (rng_inv_l x).
R, S: Ring f: R $-> S x: R H: IsInvertible R x
x * inverse_elem x = 1
exact (rng_inv_r x).Defined.(** *** Group of units *)(** Invertible elements are typically called "units" in ring theory and the collection of units forms a group under the ring multiplication. *)
R: Ring
Group
R: Ring
Group
(** TODO: Use a generalised version of [Build_Subgroup] that works for subgroups of monoids. *)
R: Ring
Type
R: Ring
SgOp ?G
R: Ring
MonUnit ?G
R: Ring
Inverse ?G
R: Ring
IsGroup ?G
R: Ring
Type
exact {x : R & IsInvertible R x}.
R: Ring
SgOp {x : R & IsInvertible R x}
R: Ring x: R p: IsInvertible R x y: R q: IsInvertible R y
{x : R & IsInvertible R x}
R: Ring x: R p: IsInvertible R x y: R q: IsInvertible R y
IsInvertible R (x * y)
exact _.
R: Ring
MonUnit {x : R & IsInvertible R x}
R: Ring
IsInvertible R 1
exact _.
R: Ring
Inverse {x : R & IsInvertible R x}
R: Ring x: R p: IsInvertible R x
{x : R & IsInvertible R x}
R: Ring x: R p: IsInvertible R x
IsInvertible R (inverse_elem x)
exact _.
R: Ring
IsGroup {x : R & IsInvertible R x}
R: Ring
IsHSet {x : R & IsInvertible R x}
R: Ring
Associative sg_op
R: Ring
LeftIdentity sg_op mon_unit
R: Ring
RightIdentity sg_op mon_unit
R: Ring
LeftInverse sg_op inv mon_unit
R: Ring
RightInverse sg_op inv mon_unit
R: Ring
Associative sg_op
R: Ring
LeftIdentity sg_op mon_unit
R: Ring
RightIdentity sg_op mon_unit
R: Ring
LeftInverse sg_op inv mon_unit
R: Ring
RightInverse sg_op inv mon_unit
R: Ring x, y, z: {x : R & IsInvertible R x}
(sg_op x (sg_op y z)).1 = (sg_op (sg_op x y) z).1
R: Ring y: {x : R & IsInvertible R x}
(sg_op mon_unit y).1 = y.1
R: Ring x: {x : R & IsInvertible R x}
(sg_op x mon_unit).1 = x.1
R: Ring x: {x : R & IsInvertible R x}
(sg_op (inv x) x).1 = mon_unit.1
R: Ring x: {x : R & IsInvertible R x}
(sg_op x (inv x)).1 = mon_unit.1
R: Ring x, y, z: {x : R & IsInvertible R x}
(sg_op x (sg_op y z)).1 = (sg_op (sg_op x y) z).1
rapply simple_associativity.
R: Ring y: {x : R & IsInvertible R x}
(sg_op mon_unit y).1 = y.1
rapply left_identity.
R: Ring x: {x : R & IsInvertible R x}
(sg_op x mon_unit).1 = x.1
rapply right_identity.
R: Ring x: {x : R & IsInvertible R x}
(sg_op (inv x) x).1 = mon_unit.1
apply rng_inv_l.
R: Ring x: {x : R & IsInvertible R x}
(sg_op x (inv x)).1 = mon_unit.1
apply rng_inv_r.Defined.(** *** Multiplication by an invertible element is an equivalence *)
R: Ring x: R H: IsInvertible R x
IsEquiv (mult x)
R: Ring x: R H: IsInvertible R x
IsEquiv (mult x)
R: Ring x: R H: IsInvertible R x
R -> R
R: Ring x: R H: IsInvertible R x
mult x o ?g == idmap
R: Ring x: R H: IsInvertible R x
?g o mult x == idmap
R: Ring x: R H: IsInvertible R x
mult x o mult (inverse_elem x) == idmap
R: Ring x: R H: IsInvertible R x
mult (inverse_elem x) o mult x == idmap
R: Ring x: R H: IsInvertible R x y: R
x * (inverse_elem x * y) = y
R: Ring x: R H: IsInvertible R x y: R
inverse_elem x * (x * y) = y
R: Ring x: R H: IsInvertible R x y: R
x * inverse_elem x * y = y
R: Ring x: R H: IsInvertible R x y: R
inverse_elem x * x * y = y
R: Ring x: R H: IsInvertible R x y: R
x * inverse_elem x * y = 1 * y
R: Ring x: R H: IsInvertible R x y: R
inverse_elem x * x * y = 1 * y
R: Ring x: R H: IsInvertible R x y: R
x * inverse_elem x = 1
R: Ring x: R H: IsInvertible R x y: R
inverse_elem x * x = 1
R: Ring x: R H: IsInvertible R x y: R
x * inverse_elem x = 1
napply rng_inv_r.
R: Ring x: R H: IsInvertible R x y: R
inverse_elem x * x = 1
napply rng_inv_l.Defined.(** This can be proved by combining [isequiv_rng_inv_mult_l (R:=rng_op R)] with [isinvertible_rng_op], but then the inverse map is given by multiplying by [right_inverse_elem x] not [inverse_elem x], which complicates calculations. *)
R: Ring x: R H: IsInvertible R x
IsEquiv (funy : R => y * x)
R: Ring x: R H: IsInvertible R x
IsEquiv (funy : R => y * x)
R: Ring x: R H: IsInvertible R x
R -> R
R: Ring x: R H: IsInvertible R x
(funy : R => y * x) o ?g == idmap
R: Ring x: R H: IsInvertible R x
?g o (funy : R => y * x) == idmap
R: Ring x: R H: IsInvertible R x
(funy : R => y * x)
o (funy : R => y * inverse_elem x) == idmap
R: Ring x: R H: IsInvertible R x
(funy : R => y * inverse_elem x)
o (funy : R => y * x) == idmap
R: Ring x: R H: IsInvertible R x y: R
y * inverse_elem x * x = y
R: Ring x: R H: IsInvertible R x y: R
y * x * inverse_elem x = y
R: Ring x: R H: IsInvertible R x y: R
y * (inverse_elem x * x) = y
R: Ring x: R H: IsInvertible R x y: R
y * (x * inverse_elem x) = y
R: Ring x: R H: IsInvertible R x y: R
y * (inverse_elem x * x) = y * 1
R: Ring x: R H: IsInvertible R x y: R
y * (x * inverse_elem x) = y * 1
R: Ring x: R H: IsInvertible R x y: R
inverse_elem x * x = 1
R: Ring x: R H: IsInvertible R x y: R
x * inverse_elem x = 1
R: Ring x: R H: IsInvertible R x y: R
inverse_elem x * x = 1
napply rng_inv_l.
R: Ring x: R H: IsInvertible R x y: R
x * inverse_elem x = 1
napply rng_inv_r.Defined.(** *** Invertible element movement lemmas *)(** These cannot be proven using the corresponding group laws in the group of units since not all elements involved are invertible. *)Definitionrng_inv_moveL_Vr {R : Ring} {xyz : R} `{IsInvertible R y}
: y * x = z <~> x = inverse_elem y * z
:= equiv_moveL_equiv_V (f := (y *.)) z x.Definitionrng_inv_moveL_rV {R : Ring} {xyz : R} `{IsInvertible R y}
: x * y = z <~> x = z * inverse_elem y
:= equiv_moveL_equiv_V (f := (.* y)) z x.Definitionrng_inv_moveR_Vr {R : Ring} {xyz : R} `{IsInvertible R y}
: x = y * z <~> inverse_elem y * x = z
:= equiv_moveR_equiv_V (f := (y *.)) x z.Definitionrng_inv_moveR_rV {R : Ring} {xyz : R} `{IsInvertible R y}
: x = z * y <~> x * inverse_elem y = z
:= equiv_moveR_equiv_V (f := (.* y)) x z.(** TODO: The group of units construction is a functor from [Ring -> Group] and is right adjoint to the group ring construction. *)