Skip to content

Commit a933b53

Browse files
eric-wieserkim-em
authored andcommitted
feat(Algebra/FreeAlgebra): support towers of algebras (#6072)
This provide `Algebra R (FreeAlgebra A X)` when `Algebra R A`; previously we only had `Algebra R (FreeAlgebra R X)`. This also fixes some diamonds that would arise as a result of this new instance by filling the `zsmul` and `intCast` fields of `Module.addCommMonoidToAddCommGroup`, `Algebra.semiringToRing`, and the `nsmul` and `natCast` fields of the `Semiring` instance.
1 parent c04c70e commit a933b53

3 files changed

Lines changed: 123 additions & 47 deletions

File tree

Mathlib/Algebra/Algebra/Basic.lean

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,10 @@ variable (R)
582582
See note [reducible non-instances]. -/
583583
@[reducible]
584584
def semiringToRing [Semiring A] [Algebra R A] : Ring A :=
585-
{ Module.addCommMonoidToAddCommGroup R, (inferInstance : Semiring A) with }
585+
{ Module.addCommMonoidToAddCommGroup R, (inferInstance : Semiring A) with
586+
intCast := fun z => algebraMap R A z
587+
intCast_ofNat := fun z => by simp only [Int.cast_ofNat, map_natCast]
588+
intCast_negSucc := fun z => by simp }
586589
#align algebra.semiring_to_ring Algebra.semiringToRing
587590

588591
end Ring

Mathlib/Algebra/FreeAlgebra.lean

Lines changed: 98 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Scott Morrison, Adam Topaz
55
-/
66
import Mathlib.Algebra.Algebra.Subalgebra.Basic
7+
import Mathlib.Algebra.Algebra.Tower
78
import Mathlib.Algebra.MonoidAlgebra.Basic
89
import Mathlib.Algebra.Free
910

@@ -159,23 +160,31 @@ namespace FreeAlgebra
159160
attribute [local instance] Pre.hasCoeGenerator Pre.hasCoeSemiring Pre.hasMul Pre.hasAdd
160161
Pre.hasZero Pre.hasOne Pre.hasSmul
161162

162-
instance : Semiring (FreeAlgebra R X) where
163-
add := Quot.map₂ (· + ·) (fun _ _ _ ↦ Rel.add_compat_right) fun _ _ _ ↦ Rel.add_compat_left
164-
add_assoc := by
165-
rintro ⟨⟩ ⟨⟩ ⟨⟩
166-
exact Quot.sound Rel.add_assoc
167-
zero := Quot.mk _ 0
168-
zero_add := by
169-
rintro ⟨⟩
170-
exact Quot.sound Rel.zero_add
171-
add_zero := by
172-
rintro ⟨⟩
173-
change Quot.mk _ _ = _
174-
rw [Quot.sound Rel.add_comm, Quot.sound Rel.zero_add]
175-
add_comm := by
176-
rintro ⟨⟩ ⟨⟩
177-
exact Quot.sound Rel.add_comm
178-
mul := Quot.map₂ (· * ·) (fun _ _ _ ↦ Rel.mul_compat_right) fun _ _ _ ↦ Rel.mul_compat_left
163+
/-! Define the basic operations-/
164+
165+
instance instSMul {A} [CommSemiring A] [Algebra R A] : SMul R (FreeAlgebra A X) where
166+
smul r := Quot.map (HMul.hMul (algebraMap R A r : Pre A X)) fun _ _ ↦ Rel.mul_compat_right
167+
168+
instance instZero : Zero (FreeAlgebra R X) where zero := Quot.mk _ 0
169+
170+
instance instOne : One (FreeAlgebra R X) where one := Quot.mk _ 1
171+
172+
instance instAdd : Add (FreeAlgebra R X) where
173+
add := Quot.map₂ HAdd.hAdd (fun _ _ _ ↦ Rel.add_compat_right) fun _ _ _ ↦ Rel.add_compat_left
174+
175+
instance instMul : Mul (FreeAlgebra R X) where
176+
mul := Quot.map₂ HMul.hMul (fun _ _ _ ↦ Rel.mul_compat_right) fun _ _ _ ↦ Rel.mul_compat_left
177+
178+
-- `Quot.mk` is an implementation detail of `FreeAlgebra`, so this lemma is private
179+
private theorem mk_mul (x y : Pre R X) :
180+
Quot.mk (Rel R X) (x * y) = (HMul.hMul (self := instHMul (α := FreeAlgebra R X))
181+
(Quot.mk (Rel R X) x) (Quot.mk (Rel R X) y)) :=
182+
rfl
183+
184+
/-! Build the semiring structure. We do this one piece at a time as this is convenient for proving
185+
the `nsmul` fields. -/
186+
187+
instance instMonoidWithZero : MonoidWithZero (FreeAlgebra R X) where
179188
mul_assoc := by
180189
rintro ⟨⟩ ⟨⟩ ⟨⟩
181190
exact Quot.sound Rel.mul_assoc
@@ -186,39 +195,98 @@ instance : Semiring (FreeAlgebra R X) where
186195
mul_one := by
187196
rintro ⟨⟩
188197
exact Quot.sound Rel.mul_one
198+
zero_mul := by
199+
rintro ⟨⟩
200+
exact Quot.sound Rel.MulZeroClass.zero_mul
201+
mul_zero := by
202+
rintro ⟨⟩
203+
exact Quot.sound Rel.MulZeroClass.mul_zero
204+
205+
instance instDistrib : Distrib (FreeAlgebra R X) where
189206
left_distrib := by
190207
rintro ⟨⟩ ⟨⟩ ⟨⟩
191208
exact Quot.sound Rel.left_distrib
192209
right_distrib := by
193210
rintro ⟨⟩ ⟨⟩ ⟨⟩
194211
exact Quot.sound Rel.right_distrib
195-
zero_mul := by
212+
213+
instance instAddCommMonoid : AddCommMonoid (FreeAlgebra R X) where
214+
add_assoc := by
215+
rintro ⟨⟩ ⟨⟩ ⟨⟩
216+
exact Quot.sound Rel.add_assoc
217+
zero_add := by
196218
rintro ⟨⟩
197-
exact Quot.sound Rel.MulZeroClass.zero_mul
198-
mul_zero := by
219+
exact Quot.sound Rel.zero_add
220+
add_zero := by
199221
rintro ⟨⟩
200-
exact Quot.sound Rel.MulZeroClass.mul_zero
222+
change Quot.mk _ _ = _
223+
rw [Quot.sound Rel.add_comm, Quot.sound Rel.zero_add]
224+
add_comm := by
225+
rintro ⟨⟩ ⟨⟩
226+
exact Quot.sound Rel.add_comm
227+
nsmul := (· • ·)
228+
nsmul_zero := by
229+
rintro ⟨⟩
230+
change Quot.mk _ (_ * _) = _
231+
rw [map_zero]
232+
exact Quot.sound Rel.MulZeroClass.zero_mul
233+
nsmul_succ n := by
234+
rintro ⟨a⟩
235+
dsimp only [HSMul.hSMul, instSMul, Quot.map]
236+
rw [map_add, map_one, add_comm, mk_mul, mk_mul, ←one_add_mul (_ : FreeAlgebra R X)]
237+
congr 1
238+
exact Quot.sound Rel.add_scalar
239+
240+
instance : Semiring (FreeAlgebra R X) where
241+
__ := instMonoidWithZero R X
242+
__ := instAddCommMonoid R X
243+
__ := instDistrib R X
244+
natCast n := Quot.mk _ (n : R)
245+
natCast_zero := by simp; rfl
246+
natCast_succ n := by simp; exact Quot.sound Rel.add_scalar
201247

202248
instance : Inhabited (FreeAlgebra R X) :=
203249
0
204250

205-
instance : SMul R (FreeAlgebra R X) where
206-
smul r := Quot.map ((· * ·) ↑r) fun _ _ ↦ Rel.mul_compat_right
207-
208-
instance : Algebra R (FreeAlgebra R X) where
209-
toFun r := Quot.mk _ r
210-
map_one' := rfl
211-
map_mul' _ _ := Quot.sound Rel.mul_scalar
212-
map_zero' := rfl
213-
map_add' _ _ := Quot.sound Rel.add_scalar
251+
instance instAlgebra {A} [CommSemiring A] [Algebra R A] : Algebra R (FreeAlgebra A X) where
252+
toRingHom := ({
253+
toFun := fun r => Quot.mk _ r
254+
map_one' := rfl
255+
map_mul' := fun _ _ => Quot.sound Rel.mul_scalar
256+
map_zero' := rfl
257+
map_add' := fun _ _ => Quot.sound Rel.add_scalar } : A →+* FreeAlgebra A X).comp
258+
(algebraMap R A)
214259
commutes' _ := by
215260
rintro ⟨⟩
216261
exact Quot.sound Rel.central_scalar
217262
smul_def' _ _ := rfl
218263

264+
-- verify there is no diamond
265+
variable (S : Type) [CommSemiring S] in
266+
example : (algebraNat : Algebra ℕ (FreeAlgebra S X)) = instAlgebra _ _ := rfl
267+
268+
instance {R S A} [CommSemiring R] [CommSemiring S] [CommSemiring A]
269+
[SMul R S] [Algebra R A] [Algebra S A] [IsScalarTower R S A] :
270+
IsScalarTower R S (FreeAlgebra A X) where
271+
smul_assoc r s x := by
272+
change algebraMap S A (r • s) • x = algebraMap R A _ • (algebraMap S A _ • x)
273+
rw [←smul_assoc]
274+
congr
275+
simp only [Algebra.algebraMap_eq_smul_one, smul_eq_mul]
276+
rw [smul_assoc, ←smul_one_mul]
277+
278+
instance {R S A} [CommSemiring R] [CommSemiring S] [CommSemiring A]
279+
[Algebra R A] [Algebra S A] [SMulCommClass R S A] :
280+
SMulCommClass R S (FreeAlgebra A X) where
281+
smul_comm r s x := smul_comm (algebraMap R A r) (algebraMap S A s) x
282+
219283
instance {S : Type _} [CommRing S] : Ring (FreeAlgebra S X) :=
220284
Algebra.semiringToRing S
221285

286+
-- verify there is no diamond
287+
variable (S : Type) [CommRing S] in
288+
example : (algebraInt _ : Algebra ℤ (FreeAlgebra S X)) = instAlgebra _ _ := rfl
289+
222290
variable {X}
223291

224292
/-- The canonical function `X → FreeAlgebra R X`.

Mathlib/Algebra/Module/Basic.lean

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -209,22 +209,6 @@ theorem smul_add_one_sub_smul {R : Type _} [Ring R] [Module R M] {r : R} {m : M}
209209

210210
end AddCommMonoid
211211

212-
variable (R)
213-
214-
/-- An `AddCommMonoid` that is a `Module` over a `Ring` carries a natural `AddCommGroup`
215-
structure.
216-
See note [reducible non-instances]. -/
217-
@[reducible]
218-
def Module.addCommMonoidToAddCommGroup [Ring R] [AddCommMonoid M] [Module R M] : AddCommGroup M :=
219-
{ (inferInstance : AddCommMonoid M) with
220-
neg := fun a => (-1 : R) • a
221-
add_left_neg := fun a =>
222-
show (-1 : R) • a + a = 0 by
223-
nth_rw 2 [← one_smul R a]
224-
rw [← add_smul, add_left_neg, zero_smul] }
225-
#align module.add_comm_monoid_to_add_comm_group Module.addCommMonoidToAddCommGroup
226-
227-
variable {R}
228212

229213
section AddCommGroup
230214

@@ -322,6 +306,27 @@ theorem sub_smul (r s : R) (y : M) : (r - s) • y = r • y - s • y := by
322306

323307
end Module
324308

309+
variable (R)
310+
311+
/-- An `AddCommMonoid` that is a `Module` over a `Ring` carries a natural `AddCommGroup`
312+
structure.
313+
See note [reducible non-instances]. -/
314+
@[reducible]
315+
def Module.addCommMonoidToAddCommGroup [Ring R] [AddCommMonoid M] [Module R M] : AddCommGroup M :=
316+
{ (inferInstance : AddCommMonoid M) with
317+
neg := fun a => (-1 : R) • a
318+
add_left_neg := fun a =>
319+
show (-1 : R) • a + a = 0 by
320+
nth_rw 2 [← one_smul R a]
321+
rw [← add_smul, add_left_neg, zero_smul]
322+
zsmul := fun z a => (z : R) • a
323+
zsmul_zero' := fun a => by simpa only [Int.cast_zero] using zero_smul R a
324+
zsmul_succ' := fun z a => by simp [add_comm, add_smul]
325+
zsmul_neg' := fun z a => by simp [←smul_assoc, neg_one_smul] }
326+
#align module.add_comm_monoid_to_add_comm_group Module.addCommMonoidToAddCommGroup
327+
328+
variable {R}
329+
325330
/-- A module over a `Subsingleton` semiring is a `Subsingleton`. We cannot register this
326331
as an instance because Lean has no way to guess `R`. -/
327332
protected theorem Module.subsingleton (R M : Type _) [Semiring R] [Subsingleton R] [AddCommMonoid M]

0 commit comments

Comments
 (0)