-
Notifications
You must be signed in to change notification settings - Fork 298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Merged by Bors] - feat(algebra/ring_quot): quotients of noncommutative rings #4078
Closed
Closed
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
69fb2d7
quotients of noncommutative rings
semorrison fee007d
first cut
semorrison ed2853c
comment
semorrison b5724e5
fix
semorrison 920503e
fix
semorrison c60e8eb
use case
semorrison c67f886
Update src/algebra/ring_quot.lean
semorrison e3d47c7
Merge remote-tracking branch 'origin/master' into ring_quot
semorrison fca07ba
Merge branch 'ring_quot' of github.com:leanprover-community/mathlib i…
semorrison 40f33fd
merge/fix
semorrison 741a32f
Apply suggestions from code review
semorrison d51ae36
get things working again
semorrison 86c169b
Merge remote-tracking branch 'origin/master' into ring_quot
semorrison 56e3061
change apply lemma so it's actually about an application
semorrison 932e0c3
merge
semorrison b60a072
Apply suggestions from code review
semorrison 55b4174
missing doc-string
semorrison 8f8cca3
Merge branch 'ring_quot' of github.com:leanprover-community/mathlib i…
semorrison 740914e
Merge remote-tracking branch 'origin/master' into ring_quot
semorrison 4928281
fixes
semorrison 6c96a88
use 'case' tactic
semorrison File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -231,6 +231,9 @@ lemma to_fun_eq_coe (f : α →+* β) : f.to_fun = f := rfl | |
|
||
variables (f : α →+* β) {x y : α} {rα rβ} | ||
|
||
theorem congr_fun {f g : α →+* β} (h : f = g) (x : α) : f x = g x := | ||
congr_arg (λ h : α →+* β, h x) h | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
|
||
theorem coe_inj ⦃f g : α →+* β⦄ (h : (f : α → β) = g) : f = g := | ||
by cases f; cases g; cases h; refl | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,274 @@ | ||
/- | ||
Copyright (c) 2020 Scott Morrison. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Scott Morrison | ||
-/ | ||
import ring_theory.ideal.basic | ||
import ring_theory.algebra | ||
|
||
/-! | ||
# Quotients of non-commutative rings | ||
|
||
Unfortunately, ideals have only been developed in the commutative case, | ||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
|
||
and it's not immediately clear how one should formalise ideals in the non-commutative case. | ||
|
||
In this file, we directly define the quotient of a semiring by any relation, | ||
by building a bigger relation that represents the ideal generated by that relation. | ||
|
||
We prove the universal properties of the quotient, | ||
and recommend avoiding relying on the actual definition! | ||
|
||
Since everything runs in parallel for quotients of `R`-algebras, we do that case at the same time. | ||
-/ | ||
|
||
universes u₁ u₂ u₃ u₄ | ||
|
||
variables {R : Type u₁} [semiring R] | ||
variables (S : Type u₂) [comm_semiring S] | ||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
|
||
variables {A : Type u₃} [semiring A] [algebra S A] | ||
|
||
namespace ring_quot | ||
|
||
/-- | ||
The quotient by the transitive closure of this relation is the quotient | ||
by the ideal generated by `r`. | ||
-/ | ||
inductive rel (r : R → R → Prop) : R → R → Prop | ||
| of {x y : R} (h : r x y) : rel x y | ||
| add {a b c} : rel a b → rel (a + c) (b + c) | ||
| mul_left {a b c} : rel a b → rel (a * c) (b * c) | ||
| mul_right {a b c} : rel a b → rel (c * a) (c * b) | ||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
eric-wieser marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end ring_quot | ||
|
||
/-- The quotient of a ring by an arbitrary relation. -/ | ||
def ring_quot (r : R → R → Prop) := quot (ring_quot.rel r) | ||
|
||
namespace ring_quot | ||
|
||
instance (r : R → R → Prop) : semiring (ring_quot r) := | ||
{ add := quot.map₂ (+) | ||
(λ c a b h, by { rw [add_comm c a, add_comm c b], exact rel.add h, }) | ||
(λ _ _ _, rel.add), | ||
add_assoc := by { rintros ⟨⟩ ⟨⟩ ⟨⟩, change quot.mk _ _ = _, rw add_assoc, refl, }, | ||
zero := quot.mk _ 0, | ||
zero_add := by { rintros ⟨⟩, change quot.mk _ _ = _, rw zero_add, }, | ||
add_zero := by { rintros ⟨⟩, change quot.mk _ _ = _, rw add_zero, }, | ||
zero_mul := by { rintros ⟨⟩, change quot.mk _ _ = _, rw zero_mul, }, | ||
mul_zero := by { rintros ⟨⟩, change quot.mk _ _ = _, rw mul_zero, }, | ||
add_comm := by { rintros ⟨⟩ ⟨⟩, change quot.mk _ _ = _, rw add_comm, refl, }, | ||
mul := quot.map₂ (*) (λ _ _ _, rel.mul_right) (λ _ _ _, rel.mul_left), | ||
mul_assoc := by { rintros ⟨⟩ ⟨⟩ ⟨⟩, change quot.mk _ _ = _, rw mul_assoc, refl, }, | ||
one := quot.mk _ 1, | ||
one_mul := by { rintros ⟨⟩, change quot.mk _ _ = _, rw one_mul, }, | ||
mul_one := by { rintros ⟨⟩, change quot.mk _ _ = _, rw mul_one, }, | ||
left_distrib := by { rintros ⟨⟩ ⟨⟩ ⟨⟩, change quot.mk _ _ = _, rw left_distrib, refl, }, | ||
right_distrib := by { rintros ⟨⟩ ⟨⟩ ⟨⟩, change quot.mk _ _ = _, rw right_distrib, refl, }, } | ||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
instance {R : Type u₁} [ring R] (r : R → R → Prop) : ring (ring_quot r) := | ||
{ neg := quot.map (λ a, -a) | ||
(λ a b h, by simp only [neg_eq_neg_one_mul a, neg_eq_neg_one_mul b, rel.mul_right h]), | ||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
|
||
add_left_neg := by { rintros ⟨⟩, change quot.mk _ _ = _, rw add_left_neg, refl, }, | ||
.. (ring_quot.semiring r) } | ||
|
||
instance {R : Type u₁} [comm_semiring R] (r : R → R → Prop) : comm_semiring (ring_quot r) := | ||
{ mul_comm := by { rintros ⟨⟩ ⟨⟩, change quot.mk _ _ = _, rw mul_comm, refl, } | ||
.. (ring_quot.semiring r) } | ||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
instance {R : Type u₁} [comm_ring R] (r : R → R → Prop) : comm_ring (ring_quot r) := | ||
{ .. (ring_quot.comm_semiring r), | ||
.. (ring_quot.ring r) } | ||
|
||
instance (s : A → A → Prop) : algebra S (ring_quot s) := | ||
{ smul := λ r a, (quot.mk _ (r • 1)) * a, | ||
to_fun := λ r, quot.mk _ (r • 1), | ||
map_one' := by { rw one_smul, refl, }, | ||
map_mul' := λ r s, by { change _ = quot.mk _ _, simp [mul_smul], }, | ||
map_zero' := by { rw zero_smul, refl, }, | ||
map_add' := λ r s, by { change _ = quot.mk _ _, rw add_smul, }, | ||
commutes' := λ r, by { rintros ⟨a⟩, change quot.mk _ _ = quot.mk _ _, simp, }, | ||
smul_def' := λ r u, rfl, } | ||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
instance (r : R → R → Prop) : inhabited (ring_quot r) := ⟨0⟩ | ||
|
||
/-- | ||
The quotient map from a ring to its quotient, as a homomorphism of rings. | ||
-/ | ||
def mk_ring_hom (r : R → R → Prop) : R →+* ring_quot r := | ||
{ to_fun := quot.mk _, | ||
map_one' := rfl, | ||
map_mul' := λ a b, rfl, | ||
map_zero' := rfl, | ||
map_add' := λ a b, rfl, } | ||
|
||
lemma mk_ring_hom_rel {r : R → R → Prop} {x y : R} (w : r x y) : | ||
mk_ring_hom r x = mk_ring_hom r y := | ||
quot.sound (rel.of w) | ||
|
||
lemma mk_ring_hom_surjective (r : R → R → Prop) : function.surjective (mk_ring_hom r) := | ||
by { dsimp [mk_ring_hom], rintro ⟨⟩, simp, } | ||
|
||
@[ext] | ||
lemma ring_quot_ext {T : Type u₄} [semiring T] {r : R → R → Prop} (f g : ring_quot r →+* T) | ||
(w : f.comp (mk_ring_hom r) = g.comp (mk_ring_hom r)) : f = g := | ||
begin | ||
ext, | ||
rcases mk_ring_hom_surjective r x with ⟨x, rfl⟩, | ||
exact (congr_arg (λ h : R →+* T, h x) w), -- TODO should we have `ring_hom.congr` for this? | ||
end | ||
|
||
variables {T : Type u₄} [semiring T] | ||
|
||
/-- | ||
Any ring homomorphism `f : R →+* T` which respects a relation `r : R → R → Prop` | ||
factors through a morphism `ring_quot r →+* T`. | ||
-/ | ||
def lift (f : R →+* T) {r : R → R → Prop} (w : ∀ {x y}, r x y → f x = f y) : | ||
ring_quot r →+* T := | ||
{ to_fun := quot.lift f | ||
begin | ||
rintros _ _ r, | ||
induction r with a b r a b c r r' a b c r r' a b c r r', | ||
{ exact w r, }, | ||
{ simp [r'], }, | ||
{ simp [r'], }, | ||
{ simp [r'], }, | ||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end, | ||
map_zero' := f.map_zero, | ||
map_add' := by { rintros ⟨x⟩ ⟨y⟩, exact f.map_add x y, }, | ||
map_one' := f.map_one, | ||
map_mul' := by { rintros ⟨x⟩ ⟨y⟩, exact f.map_mul x y, }, } | ||
|
||
@[simp] | ||
lemma lift_mk_ring_hom (f : R →+* T) {r : R → R → Prop} (w : ∀ {x y}, r x y → f x = f y) : | ||
(lift f @w).comp (mk_ring_hom r) = f := | ||
by { ext, simp, refl, } | ||
|
||
lemma lift_unique (f : R →+* T) {r : R → R → Prop} (w : ∀ {x y}, r x y → f x = f y) | ||
(g : ring_quot r →+* T) (h : g.comp (mk_ring_hom r) = f) : g = lift f @w := | ||
by { ext, simp [h], } | ||
|
||
lemma eq_lift_comp_mk_ring_hom {r : R → R → Prop} (f : ring_quot r →+* T) : | ||
f = lift (f.comp (mk_ring_hom r)) (λ x y h, by { dsimp, rw mk_ring_hom_rel h, }) := | ||
by { ext, simp, } | ||
|
||
section comm_ring | ||
/-! | ||
We now verify that in the case of a commutative ring, the `ring_quot` construction | ||
agrees with the quotient by the appropriate ideal. | ||
-/ | ||
|
||
variables {B : Type u₁} [comm_ring B] | ||
|
||
/-- The universal ring homomorphism from `ring_quot r` to `(ideal.of_rel r).quotient`. -/ | ||
def ring_quot_to_ideal_quotient (r : B → B → Prop) : | ||
ring_quot r →+* (ideal.of_rel r).quotient := | ||
lift | ||
(ideal.quotient.mk (ideal.of_rel r)) | ||
(λ x y h, quot.sound (submodule.mem_Inf.mpr (λ p w, w ⟨x, y, h, rfl⟩))) | ||
|
||
@[simp] lemma ring_quot_to_ideal_quotient_apply (r : B → B → Prop) (x : B) : | ||
ring_quot_to_ideal_quotient r (mk_ring_hom r x) = ideal.quotient.mk _ x := rfl | ||
|
||
/-- The universal ring homomorphism from `(ideal.of_rel r).quotient` to `ring_quot r`. -/ | ||
def ideal_quotient_to_ring_quot (r : B → B → Prop) : | ||
(ideal.of_rel r).quotient →+* ring_quot r := | ||
ideal.quotient.lift (ideal.of_rel r) (mk_ring_hom r) | ||
begin | ||
intros x h, | ||
apply submodule.span_induction h, | ||
{ rintros - ⟨a,b,h,rfl⟩, | ||
rw [ring_hom.map_sub, mk_ring_hom_rel h, sub_self], }, | ||
{ simp, }, | ||
{ intros a b ha hb, simp [ha, hb], }, | ||
{ intros a x hx, simp [hx], }, | ||
end | ||
|
||
@[simp] lemma ideal_quotient_to_ring_quot_apply (r : B → B → Prop) (x : B) : | ||
ideal_quotient_to_ring_quot r (ideal.quotient.mk _ x) = mk_ring_hom r x := rfl | ||
|
||
/-- | ||
The ring equivalence between `ring_quot r` and `(ideal.of_rel r).quotient` | ||
-/ | ||
def ring_quot_equiv_ideal_quotient (r : B → B → Prop) : | ||
ring_quot r ≃+* (ideal.of_rel r).quotient := | ||
ring_equiv.of_hom_inv (ring_quot_to_ideal_quotient r) (ideal_quotient_to_ring_quot r) | ||
(by { ext, simp, }) (by { ext ⟨x⟩, simp, }) | ||
|
||
end comm_ring | ||
|
||
section algebra | ||
|
||
/-- | ||
The quotient map from an `S`-algebra to its quotient, as a homomorphism of `S`-algebras. | ||
-/ | ||
def mk_alg_hom (s : A → A → Prop) : A →ₐ[S] ring_quot s := | ||
{ commutes' := λ r, show quot.mk _ _ = quot.mk _ _, by rw [algebra.smul_def'', mul_one], | ||
..mk_ring_hom s } | ||
|
||
@[simp] | ||
lemma mk_alg_hom_coe (s : A → A → Prop) : (mk_alg_hom S s : A →+* ring_quot s) = mk_ring_hom s := | ||
rfl | ||
|
||
lemma mk_alg_hom_rel {s : A → A → Prop} {x y : A} (w : s x y) : | ||
mk_alg_hom S s x = mk_alg_hom S s y := | ||
quot.sound (rel.of w) | ||
|
||
lemma mk_alg_hom_surjective (s : A → A → Prop) : function.surjective (mk_alg_hom S s) := | ||
by { dsimp [mk_alg_hom], rintro ⟨a⟩, use a, refl, } | ||
|
||
variables {B : Type u₄} [semiring B] [algebra S B] | ||
|
||
@[ext] | ||
lemma ring_quot_ext' {s : A → A → Prop} | ||
(f g : ring_quot s →ₐ[S] B) (w : f.comp (mk_alg_hom S s) = g.comp (mk_alg_hom S s)) : f = g := | ||
begin | ||
ext, | ||
rcases mk_alg_hom_surjective S s x with ⟨x, rfl⟩, | ||
exact (congr_arg (λ h : A →ₐ[S] B, h x) w), -- TODO should we have `alg_hom.congr` for this? | ||
end | ||
|
||
/-- | ||
Any `S`-algebra homomorphism `f : A →ₐ[S] B` which respects a relation `s : A → A → Prop` | ||
factors through a morphism `ring_quot s →ₐ[S] B`. | ||
-/ | ||
def lift_alg_hom (f : A →ₐ[S] B) {s : A → A → Prop} (w : ∀ {x y}, s x y → f x = f y) : | ||
ring_quot s →ₐ[S] B := | ||
{ to_fun := quot.lift f | ||
begin | ||
rintros _ _ r, | ||
induction r with a b r a b c r r' a b c r r' a b c r r', | ||
semorrison marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ exact w r, }, | ||
{ simp [r'], }, | ||
{ simp [r'], }, | ||
{ simp [r'], }, | ||
end, | ||
map_zero' := f.map_zero, | ||
map_add' := by { rintros ⟨x⟩ ⟨y⟩, exact f.map_add x y, }, | ||
map_one' := f.map_one, | ||
map_mul' := by { rintros ⟨x⟩ ⟨y⟩, exact f.map_mul x y, }, | ||
commutes' := | ||
begin | ||
rintros x, | ||
conv_rhs { rw [algebra.algebra_map_eq_smul_one, ←f.map_one, ←f.map_smul], }, | ||
exact quot.lift_beta f @w (x • 1), | ||
end, } | ||
|
||
@[simp] | ||
lemma lift_alg_hom_mk_alg_hom (f : A →ₐ[S] B) {s : A → A → Prop} (w : ∀ {x y}, s x y → f x = f y) : | ||
(lift_alg_hom S f @w).comp (mk_alg_hom S s) = f := | ||
by { ext, simp, refl, } | ||
|
||
lemma lift_alg_hom_unique (f : A →ₐ[S] B) {s : A → A → Prop} (w : ∀ {x y}, s x y → f x = f y) | ||
(g : ring_quot s →ₐ[S] B) (h : g.comp (mk_alg_hom S s) = f) : g = lift_alg_hom S f @w := | ||
by { ext, simp [h], } | ||
|
||
lemma eq_lift_alg_hom_comp_mk_alg_hom {s : A → A → Prop} (f : ring_quot s →ₐ[S] B) : | ||
f = lift_alg_hom S (f.comp (mk_alg_hom S s)) (λ x y h, by { dsimp, erw mk_alg_hom_rel S h, }) := | ||
by { ext, simp, } | ||
|
||
end algebra | ||
|
||
attribute [irreducible] ring_quot mk_ring_hom mk_alg_hom lift lift_alg_hom | ||
|
||
end ring_quot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't oppose this, but I would just like to point out that this is
ext_iff.1
.