Zulip Chat Archive
Stream: Is there code for X?
Topic: class/lemmas for smul distributing over smul
Edward van de Meent (Apr 28 2024 at 16:50):
i have three instances of SMul, and i'd like to use the fact that these are related via one distributing over another:
variable {K I:Type*} [Field K]
#synth MulAction Kˣ (I -> K) -- u • v = fun i => ↑u * (v i)
#synth MulAction (RingAut K) (I -> K) -- f • v := fun i => f (v i)
#synth MulAction (RingAut K) Kˣ -- f • u := ↑(f ↑u)
lemma ringaut_smul_unit_distrib (f : RingAut K) (d:Kˣ) (v:ι → K) :
f • (d • v) = (f • d) • (f • v) := by
ext i
simp only [Pi.smul_apply, RingAut.smul_def]
calc
f (d • v i)
= f (d * v i) := by rfl
_ = f d * f (v i) := by rw [f.map_mul]
i'd like to know if there is some class i can use to lift this fact to functions d: I -> Kˣ
Edward van de Meent (Apr 28 2024 at 17:26):
i can imagine some kind of SMulDistribSMulClass
would be used:
class SMulDistribSMulClass (A B C:Type*) [SMul A B] [SMul A C] [SMul B C] : Prop where
smul_distrib (a:A) (b:B) (c:C) : a • (b • c) = (a • b) • (a • c)
instance Pi.instSMulDistribSMulClass (I A B : Type*) (C:I → Type*) [SMul A B]
[∀ i, SMul A (C i)] [∀ i, SMul B (C i)] [∀ i,SMulDistribSMulClass A B (C i)]:
SMulDistribSMulClass A B ((i:I) → C i) where
smul_distrib a b c := by
ext i
simp only [Pi.smul_apply]
rw [SMulDistribSMulClass.smul_distrib]
instance Pi.instSMulDistribSMulClass' (I A : Type*) (B C: I → Type*)
[∀ i, SMul A (B i)] [∀ i, SMul A (C i)] [∀ i, SMul (B i) (C i)]
[∀ i, SMulDistribSMulClass A (B i) (C i)] :
SMulDistribSMulClass A ((i:I) → B i) ((i:I) → C i) where
smul_distrib a b c := by
ext i
simp only [Pi.smul_apply, Pi.smul_apply']
rw [SMulDistribSMulClass.smul_distrib]
instance Pi.instSMulDistribSMulClass'' (I : Type*) (A B C: I → Type*)
[∀ i, SMul (A i) (B i)] [∀ i, SMul (A i) (C i)] [∀ i, SMul (B i) (C i)]
[∀ i, SMulDistribSMulClass (A i) (B i) (C i)] :
SMulDistribSMulClass ((i:I) → A i) ((i:I) → B i) ((i:I) → C i) where
smul_distrib a b c := by
ext i
simp only [Pi.smul_apply']
rw [SMulDistribSMulClass.smul_distrib]
Edward van de Meent (Apr 28 2024 at 17:58):
can someone point out what's going on here?
section
variable {G M K:Type*} [Semiring K]
-- #synth IsScalarTower (RingAut K) K K
-- #synth SMulCommClass (RingAut K) K K
instance [Monoid G] [Monoid M] [MulDistribMulAction G M] : MulDistribMulAction G Mˣ where
smul g u := ⟨g • u, g • u⁻¹,
by rw [← smul_mul', Units.mul_inv, smul_one],
by rw [← smul_mul', Units.inv_mul, smul_one]⟩
one_smul u := Units.ext <| one_smul _ _
mul_smul g₁ g₂ u := Units.ext <| mul_smul _ _ _
smul_mul g u₁ u₂ := Units.ext <| smul_mul' _ _ _
smul_one g := Units.ext <| smul_one _
end
section
class SMulDistribSMulClass (A B C:Type*) [SMul A B] [SMul A C] [SMul B C] : Prop where
smul_distrib (a:A) (b:B) (c:C) : a • (b • c) = (a • b) • (a • c)
instance MulDistribMulAction.instSMulDistribSmulClass (A B : Type*)
[Monoid A] [Monoid B] [MulDistribMulAction A B] :
SMulDistribSMulClass A B B where
smul_distrib a b₁ b₂ := by
simp only [smul_eq_mul, smul_mul']
variable {K:Type*} [Field K]
#synth MulDistribMulAction (RingAut K) Kˣ
#synth SMulDistribSMulClass (RingAut K) Kˣ Kˣ -- fails
example : SMulDistribSMulClass (RingAut K) Kˣ Kˣ := by
apply MulDistribMulAction.instSMulDistribSmulClass (RingAut K) Kˣ
-- failed to unify
-- SMulDistribSMulClass (RingAut K) Kˣ Kˣ
-- with
-- SMulDistribSMulClass (RingAut K) Kˣ Kˣ
def foo := by
apply MulDistribMulAction.instSMulDistribSmulClass (RingAut K) Kˣ
#check foo -- foo.{u_1} {K : Type u_1} [inst✝ : Field K] : SMulDistribSMulClass (RingAut K) Kˣ Kˣ
#synth SMulDistribSMulClass (RingAut K) K K -- succeeds
Eric Wieser (Apr 28 2024 at 20:33):
I think there is a bug in the error message generation there; I thought it was supposed to automatically add @
s to make the differing arguments visible
Eric Wieser (Apr 28 2024 at 20:34):
Either way, if you click on the terms in the infoview you should be able to track down the issue
Edward van de Meent (Apr 28 2024 at 20:49):
it seems to be having problems with the fact that K
has commutative multiplication...
it fails with CommMonoid K
, but succeeds with Monoid K
...
Kevin Buzzard (Apr 28 2024 at 20:51):
Can you post a #mwe ?
Eric Wieser (Apr 28 2024 at 20:52):
I am happy to look at this further tomorrow morning if someone doesn't beat me to it, but am not at lean right now: this is very likely either a problem I've seen before, or one of my own creation
Edward van de Meent (Apr 28 2024 at 20:57):
import Mathlib.Algebra.Module.Equiv
-- import Mathlib
import Init.Tactics
section
instance Units.instMulDistribMulAction' {G M :Type*}
[Monoid G] [Monoid M] [MulDistribMulAction G M] : MulDistribMulAction G Mˣ where
smul g u := ⟨g • u, g • u⁻¹,
by rw [← smul_mul', Units.mul_inv, smul_one],
by rw [← smul_mul', Units.inv_mul, smul_one]⟩
one_smul u := Units.ext <| one_smul _ _
mul_smul g₁ g₂ u := Units.ext <| mul_smul _ _ _
smul_mul g u₁ u₂ := Units.ext <| smul_mul' _ _ _
smul_one g := Units.ext <| smul_one _
end
section
class SMulDistribSMulClass (A B C:Type*) [SMul A B] [SMul A C] [SMul B C] : Prop where
smul_distrib (a:A) (b:B) (c:C) : a • (b • c) = (a • b) • (a • c)
instance MulDistribMulAction.instSMulDistribSmulClass (A B : Type*)
[Monoid A] [Monoid B] [MulDistribMulAction A B] :
SMulDistribSMulClass A B B where
smul_distrib a b₁ b₂ := by
simp only [smul_eq_mul, smul_mul']
end
variable {K:Type*}
section
variable [Monoid K]
#synth MulDistribMulAction (MulAut K) Kˣ -- succeeds
#synth SMulDistribSMulClass (MulAut K) Kˣ Kˣ -- succeeds
end
section
variable [CommMonoid K]
#synth MulDistribMulAction (MulAut K) Kˣ -- succeeds
#synth SMulDistribSMulClass (MulAut K) Kˣ Kˣ -- fails
end
Eric Wieser (Apr 28 2024 at 21:08):
This is the issue:
example {K} [CommMonoid K] : (Monoid.toMulAction _ : MulAction Kˣ Kˣ) = Units.mulAction' :=
-- fails
rfl
example {K} [CommMonoid K] : (Monoid.toMulAction _ : MulAction Kˣ Kˣ) = Units.mulAction' := by
-- ok
ext
rfl
Eric Wieser (Apr 28 2024 at 21:09):
I think this is what was being discussed in the other thread I linked to before
Edward van de Meent (Apr 28 2024 at 21:13):
ah yes, that seems right...
Edward van de Meent (Apr 28 2024 at 21:34):
so, for posterity, the issue is with the following definitional difference:
example {K} [CommMonoid K] (u₁ u₂:Kˣ):
u₁ • u₂ = ⟨(u₁:K) * u₂,((u₁⁻¹:Kˣ):K) * u₂⁻¹,by sorry,by sorry⟩ := by rfl
example {K} [Monoid K] (u₁ u₂:Kˣ):
u₁ • u₂ = ⟨u₁ * u₂, u₂⁻¹ * u₁⁻¹,by sorry,by sorry⟩ := by rfl
Eric Wieser (Apr 28 2024 at 21:52):
Here's the old thread
Last updated: May 02 2025 at 03:31 UTC