Theorem: AddSubmonoid.closure_mul_closure
File: Mathlib/GroupTheory/Submonoid/Pointwise.lean

tactic: apply le_antisymm
state_before: α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
⊢ closure S * closure T = closure (S * T)

tactic: refine mul_le.2 fun a ha b hb => ?_
state_before: case a
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
⊢ closure S * closure T ≤ closure (S * T)

tactic: rw [← AddMonoidHom.mulRight_apply, ← AddSubmonoid.mem_comap]
state_before: case a
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
⊢ a * b ∈ closure (S * T)

tactic: refine (closure_le.2 fun a' ha' => ?_) ha
state_before: case a
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
⊢ a ∈ comap (AddMonoidHom.mulRight b) (closure (S * T))

tactic: change b ∈ (closure (S * T)).comap (AddMonoidHom.mulLeft a')
state_before: case a
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
a' : R
ha' : a' ∈ S
⊢ a' ∈ ↑(comap (AddMonoidHom.mulRight b) (closure (S * T)))

tactic: refine (closure_le.2 fun b' hb' => ?_) hb
state_before: case a
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
a' : R
ha' : a' ∈ S
⊢ b ∈ comap (AddMonoidHom.mulLeft a') (closure (S * T))

tactic: change a' * b' ∈ closure (S * T)
state_before: case a
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
a' : R
ha' : a' ∈ S
b' : R
hb' : b' ∈ T
⊢ b' ∈ ↑(comap (AddMonoidHom.mulLeft a') (closure (S * T)))

tactic: exact subset_closure (Set.mul_mem_mul ha' hb')
state_before: case a
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
a' : R
ha' : a' ∈ S
b' : R
hb' : b' ∈ T
⊢ a' * b' ∈ closure (S * T)

tactic: rw [closure_le]
state_before: case a
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
⊢ closure (S * T) ≤ closure S * closure T

tactic: rintro _ ⟨a, b, ha, hb, rfl⟩
state_before: case a
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
⊢ S * T ⊆ ↑(closure S * closure T)

tactic: exact mul_mem_mul (subset_closure ha) (subset_closure hb)
state_before: case a.intro.intro.intro.intro
α : Type ?u.244690
G : Type ?u.244693
M : Type ?u.244696
R : Type u_1
A : Type ?u.244702
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a b : R
ha : a ∈ S
hb : b ∈ T
⊢ (fun x x_1 => x * x_1) a b ∈ ↑(closure S * closure T)