l3lab/ntp-mathlib huggingface dataset:
/-- `Set α` is a division monoid under pointwise operations if `α` is. -/
@[to_additive subtractionMonoid
    "`Set α` is a subtraction monoid under pointwise operations if `α` is."]
protected noncomputable def divisionMonoid : DivisionMonoid (Set α) :=
  { Set.monoid, Set.involutiveInv, Set.div, @Set.ZPow α _ _ _ with
    mul_inv_rev := fun s t => by
      simp_rw [← image_inv]
      

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
s✝ t✝ : Set α
src✝³ : Monoid (Set α) := Set.monoid
src✝² : InvolutiveInv (Set α) := involutiveInv
src✝¹ : Div (Set α) := Set.div
src✝ : Pow (Set α) ℤ := Set.ZPow
s t : Set α
⊢ Inv.inv '' (s * t) = Inv.inv '' t * Inv.inv '' s

Next tactic:
exact image_image2_antidistrib mul_inv_rev
/-- `Set α` is a division monoid under pointwise operations if `α` is. -/
@[to_additive subtractionMonoid
    "`Set α` is a subtraction monoid under pointwise operations if `α` is."]
protected noncomputable def divisionMonoid : DivisionMonoid (Set α) :=
  { Set.monoid, Set.involutiveInv, Set.div, @Set.ZPow α _ _ _ with
    mul_inv_rev := fun s t => by
      simp_rw [← image_inv]
      exact image_image2_antidistrib mul_inv_rev
    inv_eq_of_mul := fun s t h => by
      

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
s✝ t✝ : Set α
src✝³ : Monoid (Set α) := Set.monoid
src✝² : InvolutiveInv (Set α) := involutiveInv
src✝¹ : Div (Set α) := Set.div
src✝ : Pow (Set α) ℤ := Set.ZPow
s t : Set α
h : s * t = 1
⊢ s⁻¹ = t

Next tactic:
obtain ⟨a, b, rfl, rfl, hab⟩ := Set.mul_eq_one_iff.1 h
/-- `Set α` is a division monoid under pointwise operations if `α` is. -/
@[to_additive subtractionMonoid
    "`Set α` is a subtraction monoid under pointwise operations if `α` is."]
protected noncomputable def divisionMonoid : DivisionMonoid (Set α) :=
  { Set.monoid, Set.involutiveInv, Set.div, @Set.ZPow α _ _ _ with
    mul_inv_rev := fun s t => by
      simp_rw [← image_inv]
      exact image_image2_antidistrib mul_inv_rev
    inv_eq_of_mul := fun s t h => by
      obtain ⟨a, b, rfl, rfl, hab⟩ := Set.mul_eq_one_iff.1 h
      

Proof state:
case intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
s t : Set α
src✝³ : Monoid (Set α) := Set.monoid
src✝² : InvolutiveInv (Set α) := involutiveInv
src✝¹ : Div (Set α) := Set.div
src✝ : Pow (Set α) ℤ := Set.ZPow
a b : α
hab : a * b = 1
h : {a} * {b} = 1
⊢ {a}⁻¹ = {b}

Next tactic:
rw [inv_singleton, inv_eq_of_mul_eq_one_right hab]
@[to_additive (attr := simp 500)]
theorem isUnit_iff : IsUnit s ↔ ∃ a, s = {a} ∧ IsUnit a := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
s t : Set α
⊢ IsUnit s ↔ ∃ a, s = {a} ∧ IsUnit a

Next tactic:
constructor
@[to_additive (attr := simp 500)]
theorem isUnit_iff : IsUnit s ↔ ∃ a, s = {a} ∧ IsUnit a := by
  constructor
  · 

Proof state:
case mp
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
s t : Set α
⊢ IsUnit s → ∃ a, s = {a} ∧ IsUnit a

Next tactic:
rintro ⟨u, rfl⟩
@[to_additive (attr := simp 500)]
theorem isUnit_iff : IsUnit s ↔ ∃ a, s = {a} ∧ IsUnit a := by
  constructor
  · rintro ⟨u, rfl⟩
    

Proof state:
case mp.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
t : Set α
u : (Set α)ˣ
⊢ ∃ a, ↑u = {a} ∧ IsUnit a

Next tactic:
obtain ⟨a, b, ha, hb, h⟩ := Set.mul_eq_one_iff.1 u.mul_inv
@[to_additive (attr := simp 500)]
theorem isUnit_iff : IsUnit s ↔ ∃ a, s = {a} ∧ IsUnit a := by
  constructor
  · rintro ⟨u, rfl⟩
    obtain ⟨a, b, ha, hb, h⟩ := Set.mul_eq_one_iff.1 u.mul_inv
    

Proof state:
case mp.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
t : Set α
u : (Set α)ˣ
a b : α
ha : ↑u = {a}
hb : ↑u⁻¹ = {b}
h : a * b = 1
⊢ ∃ a, ↑u = {a} ∧ IsUnit a

Next tactic:
refine' ⟨a, ha, ⟨a, b, h, singleton_injective _⟩, rfl⟩
@[to_additive (attr := simp 500)]
theorem isUnit_iff : IsUnit s ↔ ∃ a, s = {a} ∧ IsUnit a := by
  constructor
  · rintro ⟨u, rfl⟩
    obtain ⟨a, b, ha, hb, h⟩ := Set.mul_eq_one_iff.1 u.mul_inv
    refine' ⟨a, ha, ⟨a, b, h, singleton_injective _⟩, rfl⟩
    

Proof state:
case mp.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
t : Set α
u : (Set α)ˣ
a b : α
ha : ↑u = {a}
hb : ↑u⁻¹ = {b}
h : a * b = 1
⊢ {b * a} = {1}

Next tactic:
rw [← singleton_mul_singleton, ← ha, ← hb]
@[to_additive (attr := simp 500)]
theorem isUnit_iff : IsUnit s ↔ ∃ a, s = {a} ∧ IsUnit a := by
  constructor
  · rintro ⟨u, rfl⟩
    obtain ⟨a, b, ha, hb, h⟩ := Set.mul_eq_one_iff.1 u.mul_inv
    refine' ⟨a, ha, ⟨a, b, h, singleton_injective _⟩, rfl⟩
    rw [← singleton_mul_singleton, ← ha, ← hb]
    

Proof state:
case mp.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
t : Set α
u : (Set α)ˣ
a b : α
ha : ↑u = {a}
hb : ↑u⁻¹ = {b}
h : a * b = 1
⊢ ↑u⁻¹ * ↑u = {1}

Next tactic:
exact u.inv_mul
@[to_additive (attr := simp 500)]
theorem isUnit_iff : IsUnit s ↔ ∃ a, s = {a} ∧ IsUnit a := by
  constructor
  · rintro ⟨u, rfl⟩
    obtain ⟨a, b, ha, hb, h⟩ := Set.mul_eq_one_iff.1 u.mul_inv
    refine' ⟨a, ha, ⟨a, b, h, singleton_injective _⟩, rfl⟩
    rw [← singleton_mul_singleton, ← ha, ← hb]
    exact u.inv_mul
  · 

Proof state:
case mpr
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
s t : Set α
⊢ (∃ a, s = {a} ∧ IsUnit a) → IsUnit s

Next tactic:
rintro ⟨a, rfl, ha⟩
@[to_additive (attr := simp 500)]
theorem isUnit_iff : IsUnit s ↔ ∃ a, s = {a} ∧ IsUnit a := by
  constructor
  · rintro ⟨u, rfl⟩
    obtain ⟨a, b, ha, hb, h⟩ := Set.mul_eq_one_iff.1 u.mul_inv
    refine' ⟨a, ha, ⟨a, b, h, singleton_injective _⟩, rfl⟩
    rw [← singleton_mul_singleton, ← ha, ← hb]
    exact u.inv_mul
  · rintro ⟨a, rfl, ha⟩
    

Proof state:
case mpr.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : DivisionMonoid α
t : Set α
a : α
ha : IsUnit a
⊢ IsUnit {a}

Next tactic:
exact ha.set
/-- `Set α` has distributive negation if `α` has. -/
protected noncomputable def hasDistribNeg [Mul α] [HasDistribNeg α] : HasDistribNeg (Set α) :=
  { Set.involutiveNeg with
    neg_mul := fun _ _ => by
      

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : Mul α
inst✝ : HasDistribNeg α
src✝ : InvolutiveNeg (Set α) := involutiveNeg
x✝¹ x✝ : Set α
⊢ -x✝¹ * x✝ = -(x✝¹ * x✝)

Next tactic:
simp_rw [← image_neg]
/-- `Set α` has distributive negation if `α` has. -/
protected noncomputable def hasDistribNeg [Mul α] [HasDistribNeg α] : HasDistribNeg (Set α) :=
  { Set.involutiveNeg with
    neg_mul := fun _ _ => by
      simp_rw [← image_neg]
      

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : Mul α
inst✝ : HasDistribNeg α
src✝ : InvolutiveNeg (Set α) := involutiveNeg
x✝¹ x✝ : Set α
⊢ Neg.neg '' x✝¹ * x✝ = Neg.neg '' (x✝¹ * x✝)

Next tactic:
exact image2_image_left_comm neg_mul
/-- `Set α` has distributive negation if `α` has. -/
protected noncomputable def hasDistribNeg [Mul α] [HasDistribNeg α] : HasDistribNeg (Set α) :=
  { Set.involutiveNeg with
    neg_mul := fun _ _ => by
      simp_rw [← image_neg]
      exact image2_image_left_comm neg_mul
    mul_neg := fun _ _ => by
      

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : Mul α
inst✝ : HasDistribNeg α
src✝ : InvolutiveNeg (Set α) := involutiveNeg
x✝¹ x✝ : Set α
⊢ x✝¹ * -x✝ = -(x✝¹ * x✝)

Next tactic:
simp_rw [← image_neg]
/-- `Set α` has distributive negation if `α` has. -/
protected noncomputable def hasDistribNeg [Mul α] [HasDistribNeg α] : HasDistribNeg (Set α) :=
  { Set.involutiveNeg with
    neg_mul := fun _ _ => by
      simp_rw [← image_neg]
      exact image2_image_left_comm neg_mul
    mul_neg := fun _ _ => by
      simp_rw [← image_neg]
      

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : Mul α
inst✝ : HasDistribNeg α
src✝ : InvolutiveNeg (Set α) := involutiveNeg
x✝¹ x✝ : Set α
⊢ x✝¹ * Neg.neg '' x✝ = Neg.neg '' (x✝¹ * x✝)

Next tactic:
exact image_image2_right_comm mul_neg
theorem mul_zero_subset (s : Set α) : s * 0 ⊆ 0 := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : MulZeroClass α
s✝ t s : Set α
⊢ s * 0 ⊆ 0

Next tactic:
simp [subset_def, mem_mul]
theorem zero_mul_subset (s : Set α) : 0 * s ⊆ 0 := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : MulZeroClass α
s✝ t s : Set α
⊢ 0 * s ⊆ 0

Next tactic:
simp [subset_def, mem_mul]
theorem Nonempty.mul_zero (hs : s.Nonempty) : s * 0 = 0 :=
  s.mul_zero_subset.antisymm <| by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : MulZeroClass α
s t : Set α
hs : Set.Nonempty s
⊢ 0 ⊆ s * 0

Next tactic:
simpa [mem_mul] using hs
theorem Nonempty.zero_mul (hs : s.Nonempty) : 0 * s = 0 :=
  s.zero_mul_subset.antisymm <| by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : MulZeroClass α
s t : Set α
hs : Set.Nonempty s
⊢ 0 ⊆ 0 * s

Next tactic:
simpa [mem_mul] using hs
@[to_additive (attr := simp)]
theorem one_mem_div_iff : (1 : α) ∈ s / t ↔ ¬Disjoint s t := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ 1 ∈ s / t ↔ ¬Disjoint s t

Next tactic:
simp [not_disjoint_iff_nonempty_inter, mem_div, div_eq_one, Set.Nonempty]
@[to_additive (attr := simp)]
theorem isUnit_iff_singleton : IsUnit s ↔ ∃ a, s = {a} := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ IsUnit s ↔ ∃ a, s = {a}

Next tactic:
simp only [isUnit_iff, Group.isUnit, and_true_iff]
@[to_additive (attr := simp)]
theorem image_mul_left : (a * ·) '' t = (a⁻¹ * ·) ⁻¹' t := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => a * x) '' t = (fun x => a⁻¹ * x) ⁻¹' t

Next tactic:
rw [image_eq_preimage_of_inverse]
@[to_additive (attr := simp)]
theorem image_mul_left : (a * ·) '' t = (a⁻¹ * ·) ⁻¹' t := by
  rw [image_eq_preimage_of_inverse] <;> 

Proof state:
case h₁
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ LeftInverse (fun x => a⁻¹ * x) fun x => a * x

Next tactic:
intro c
@[to_additive (attr := simp)]
theorem image_mul_left : (a * ·) '' t = (a⁻¹ * ·) ⁻¹' t := by
  rw [image_eq_preimage_of_inverse] <;> 

Proof state:
case h₂
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ Function.RightInverse (fun x => a⁻¹ * x) fun x => a * x

Next tactic:
intro c
@[to_additive (attr := simp)]
theorem image_mul_left : (a * ·) '' t = (a⁻¹ * ·) ⁻¹' t := by
  rw [image_eq_preimage_of_inverse] <;> intro c <;> 

Proof state:
case h₁
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b c : α
⊢ (fun x => a⁻¹ * x) ((fun x => a * x) c) = c

Next tactic:
simp
@[to_additive (attr := simp)]
theorem image_mul_left : (a * ·) '' t = (a⁻¹ * ·) ⁻¹' t := by
  rw [image_eq_preimage_of_inverse] <;> intro c <;> 

Proof state:
case h₂
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b c : α
⊢ (fun x => a * x) ((fun x => a⁻¹ * x) c) = c

Next tactic:
simp
@[to_additive (attr := simp)]
theorem image_mul_right : (· * b) '' t = (· * b⁻¹) ⁻¹' t := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => x * b) '' t = (fun x => x * b⁻¹) ⁻¹' t

Next tactic:
rw [image_eq_preimage_of_inverse]
@[to_additive (attr := simp)]
theorem image_mul_right : (· * b) '' t = (· * b⁻¹) ⁻¹' t := by
  rw [image_eq_preimage_of_inverse] <;> 

Proof state:
case h₁
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ LeftInverse (fun x => x * b⁻¹) fun x => x * b

Next tactic:
intro c
@[to_additive (attr := simp)]
theorem image_mul_right : (· * b) '' t = (· * b⁻¹) ⁻¹' t := by
  rw [image_eq_preimage_of_inverse] <;> 

Proof state:
case h₂
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ Function.RightInverse (fun x => x * b⁻¹) fun x => x * b

Next tactic:
intro c
@[to_additive (attr := simp)]
theorem image_mul_right : (· * b) '' t = (· * b⁻¹) ⁻¹' t := by
  rw [image_eq_preimage_of_inverse] <;> intro c <;> 

Proof state:
case h₁
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b c : α
⊢ (fun x => x * b⁻¹) ((fun x => x * b) c) = c

Next tactic:
simp
@[to_additive (attr := simp)]
theorem image_mul_right : (· * b) '' t = (· * b⁻¹) ⁻¹' t := by
  rw [image_eq_preimage_of_inverse] <;> intro c <;> 

Proof state:
case h₂
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b c : α
⊢ (fun x => x * b) ((fun x => x * b⁻¹) c) = c

Next tactic:
simp
@[to_additive]
theorem image_mul_left' : (a⁻¹ * ·) '' t = (a * ·) ⁻¹' t := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => a⁻¹ * x) '' t = (fun x => a * x) ⁻¹' t

Next tactic:
simp
@[to_additive]
theorem image_mul_right' : (· * b⁻¹) '' t = (· * b) ⁻¹' t := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => x * b⁻¹) '' t = (fun x => x * b) ⁻¹' t

Next tactic:
simp
@[to_additive (attr := simp)]
theorem preimage_mul_left_singleton : (a * ·) ⁻¹' {b} = {a⁻¹ * b} := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => a * x) ⁻¹' {b} = {a⁻¹ * b}

Next tactic:
rw [← image_mul_left', image_singleton]
@[to_additive (attr := simp)]
theorem preimage_mul_right_singleton : (· * a) ⁻¹' {b} = {b * a⁻¹} := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => x * a) ⁻¹' {b} = {b * a⁻¹}

Next tactic:
rw [← image_mul_right', image_singleton]
@[to_additive (attr := simp)]
theorem preimage_mul_left_one : (a * ·) ⁻¹' 1 = {a⁻¹} := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => a * x) ⁻¹' 1 = {a⁻¹}

Next tactic:
rw [← image_mul_left', image_one, mul_one]
@[to_additive (attr := simp)]
theorem preimage_mul_right_one : (· * b) ⁻¹' 1 = {b⁻¹} := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => x * b) ⁻¹' 1 = {b⁻¹}

Next tactic:
rw [← image_mul_right', image_one, one_mul]
@[to_additive]
theorem preimage_mul_left_one' : (a⁻¹ * ·) ⁻¹' 1 = {a} := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => a⁻¹ * x) ⁻¹' 1 = {a}

Next tactic:
simp
@[to_additive]
theorem preimage_mul_right_one' : (· * b⁻¹) ⁻¹' 1 = {b} := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : Group α
s t : Set α
a b : α
⊢ (fun x => x * b⁻¹) ⁻¹' 1 = {b}

Next tactic:
simp
theorem div_zero_subset (s : Set α) : s / 0 ⊆ 0 := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : GroupWithZero α
s✝ t s : Set α
⊢ s / 0 ⊆ 0

Next tactic:
simp [subset_def, mem_div]
theorem zero_div_subset (s : Set α) : 0 / s ⊆ 0 := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : GroupWithZero α
s✝ t s : Set α
⊢ 0 / s ⊆ 0

Next tactic:
simp [subset_def, mem_div]
theorem Nonempty.div_zero (hs : s.Nonempty) : s / 0 = 0 :=
  s.div_zero_subset.antisymm <| by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : GroupWithZero α
s t : Set α
hs : Set.Nonempty s
⊢ 0 ⊆ s / 0

Next tactic:
simpa [mem_div] using hs
theorem Nonempty.zero_div (hs : s.Nonempty) : 0 / s = 0 :=
  s.zero_div_subset.antisymm <| by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : GroupWithZero α
s t : Set α
hs : Set.Nonempty s
⊢ 0 ⊆ 0 / s

Next tactic:
simpa [mem_div] using hs
@[to_additive]
lemma mul_subset_range {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) : s * t ⊆ range m := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
⊢ s * t ⊆ range ⇑m

Next tactic:
rintro _ ⟨a, b, ha, hb, rfl⟩
@[to_additive]
lemma mul_subset_range {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) : s * t ⊆ range m := by
  rintro _ ⟨a, b, ha, hb, rfl⟩;
  

Proof state:
case intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
a b : β
ha : a ∈ s
hb : b ∈ t
⊢ (fun x x_1 => x * x_1) a b ∈ range ⇑m

Next tactic:
obtain ⟨a, rfl⟩ := hs ha
@[to_additive]
lemma mul_subset_range {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) : s * t ⊆ range m := by
  rintro _ ⟨a, b, ha, hb, rfl⟩;
  obtain ⟨a, rfl⟩ := hs ha
  

Proof state:
case intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
b : β
hb : b ∈ t
a : α
ha : m a ∈ s
⊢ (fun x x_1 => x * x_1) (m a) b ∈ range ⇑m

Next tactic:
obtain ⟨b, rfl⟩ := ht hb
@[to_additive]
lemma mul_subset_range {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) : s * t ⊆ range m := by
  rintro _ ⟨a, b, ha, hb, rfl⟩;
  obtain ⟨a, rfl⟩ := hs ha
  obtain ⟨b, rfl⟩ := ht hb
  

Proof state:
case intro.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
a : α
ha : m a ∈ s
b : α
hb : m b ∈ t
⊢ (fun x x_1 => x * x_1) (m a) (m b) ∈ range ⇑m

Next tactic:
exact ⟨a * b, map_mul _ _ _⟩
@[to_additive]
theorem preimage_mul_preimage_subset {s t : Set β} : m ⁻¹' s * m ⁻¹' t ⊆ m ⁻¹' (s * t) := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
⊢ ⇑m ⁻¹' s * ⇑m ⁻¹' t ⊆ ⇑m ⁻¹' (s * t)

Next tactic:
rintro _ ⟨_, _, _, _, rfl⟩
@[to_additive]
theorem preimage_mul_preimage_subset {s t : Set β} : m ⁻¹' s * m ⁻¹' t ⊆ m ⁻¹' (s * t) := by
  rintro _ ⟨_, _, _, _, rfl⟩
  

Proof state:
case intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
w✝¹ w✝ : α
left✝¹ : w✝¹ ∈ ⇑m ⁻¹' s
left✝ : w✝ ∈ ⇑m ⁻¹' t
⊢ (fun x x_1 => x * x_1) w✝¹ w✝ ∈ ⇑m ⁻¹' (s * t)

Next tactic:
exact ⟨_, _, ‹_›, ‹_›, (map_mul m _ _).symm⟩
@[to_additive]
lemma preimage_mul (hm : Injective m) {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) :
    m ⁻¹' (s * t) = m ⁻¹' s * m ⁻¹' t := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
hm : Injective ⇑m
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
⊢ ⇑m ⁻¹' (s * t) = ⇑m ⁻¹' s * ⇑m ⁻¹' t

Next tactic:
refine subset_antisymm ?_ (preimage_mul_preimage_subset m)
@[to_additive]
lemma preimage_mul (hm : Injective m) {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) :
    m ⁻¹' (s * t) = m ⁻¹' s * m ⁻¹' t := by
  refine subset_antisymm ?_ (preimage_mul_preimage_subset m)
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
hm : Injective ⇑m
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
⊢ ⇑m ⁻¹' (s * t) ⊆ ⇑m ⁻¹' s * ⇑m ⁻¹' t

Next tactic:
rintro a ⟨b, c, hb, hc, ha⟩
@[to_additive]
lemma preimage_mul (hm : Injective m) {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) :
    m ⁻¹' (s * t) = m ⁻¹' s * m ⁻¹' t := by
  refine subset_antisymm ?_ (preimage_mul_preimage_subset m)
  rintro a ⟨b, c, hb, hc, ha⟩
  

Proof state:
case intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
hm : Injective ⇑m
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
a : α
b c : β
hb : b ∈ s
hc : c ∈ t
ha : (fun x x_1 => x * x_1) b c = m a
⊢ a ∈ ⇑m ⁻¹' s * ⇑m ⁻¹' t

Next tactic:
obtain ⟨b, rfl⟩ := hs hb
@[to_additive]
lemma preimage_mul (hm : Injective m) {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) :
    m ⁻¹' (s * t) = m ⁻¹' s * m ⁻¹' t := by
  refine subset_antisymm ?_ (preimage_mul_preimage_subset m)
  rintro a ⟨b, c, hb, hc, ha⟩
  obtain ⟨b, rfl⟩ := hs hb
  

Proof state:
case intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
hm : Injective ⇑m
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
a : α
c : β
hc : c ∈ t
b : α
hb : m b ∈ s
ha : (fun x x_1 => x * x_1) (m b) c = m a
⊢ a ∈ ⇑m ⁻¹' s * ⇑m ⁻¹' t

Next tactic:
obtain ⟨c, rfl⟩ := ht hc
@[to_additive]
lemma preimage_mul (hm : Injective m) {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) :
    m ⁻¹' (s * t) = m ⁻¹' s * m ⁻¹' t := by
  refine subset_antisymm ?_ (preimage_mul_preimage_subset m)
  rintro a ⟨b, c, hb, hc, ha⟩
  obtain ⟨b, rfl⟩ := hs hb
  obtain ⟨c, rfl⟩ := ht hc
  

Proof state:
case intro.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
hm : Injective ⇑m
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
a b : α
hb : m b ∈ s
c : α
hc : m c ∈ t
ha : (fun x x_1 => x * x_1) (m b) (m c) = m a
⊢ a ∈ ⇑m ⁻¹' s * ⇑m ⁻¹' t

Next tactic:
simp only [← map_mul, hm.eq_iff] at ha
@[to_additive]
lemma preimage_mul (hm : Injective m) {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) :
    m ⁻¹' (s * t) = m ⁻¹' s * m ⁻¹' t := by
  refine subset_antisymm ?_ (preimage_mul_preimage_subset m)
  rintro a ⟨b, c, hb, hc, ha⟩
  obtain ⟨b, rfl⟩ := hs hb
  obtain ⟨c, rfl⟩ := ht hc
  simp only [← map_mul, hm.eq_iff] at ha
  

Proof state:
case intro.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Mul α
inst✝¹ : Mul β
inst✝ : MulHomClass F α β
m : F
s✝ t✝ : Set α
hm : Injective ⇑m
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
a b : α
hb : m b ∈ s
c : α
hc : m c ∈ t
ha : b * c = a
⊢ a ∈ ⇑m ⁻¹' s * ⇑m ⁻¹' t

Next tactic:
exact ⟨b, c, hb, hc, ha⟩
@[to_additive]
lemma div_subset_range {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) : s / t ⊆ range m := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Group α
inst✝¹ : DivisionMonoid β
inst✝ : MonoidHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
⊢ s / t ⊆ range ⇑m

Next tactic:
rintro _ ⟨a, b, ha, hb, rfl⟩
@[to_additive]
lemma div_subset_range {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) : s / t ⊆ range m := by
  rintro _ ⟨a, b, ha, hb, rfl⟩;
  

Proof state:
case intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Group α
inst✝¹ : DivisionMonoid β
inst✝ : MonoidHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
a b : β
ha : a ∈ s
hb : b ∈ t
⊢ (fun x x_1 => x / x_1) a b ∈ range ⇑m

Next tactic:
obtain ⟨a, rfl⟩ := hs ha
@[to_additive]
lemma div_subset_range {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) : s / t ⊆ range m := by
  rintro _ ⟨a, b, ha, hb, rfl⟩;
  obtain ⟨a, rfl⟩ := hs ha
  

Proof state:
case intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Group α
inst✝¹ : DivisionMonoid β
inst✝ : MonoidHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
b : β
hb : b ∈ t
a : α
ha : m a ∈ s
⊢ (fun x x_1 => x / x_1) (m a) b ∈ range ⇑m

Next tactic:
obtain ⟨b, rfl⟩ := ht hb
@[to_additive]
lemma div_subset_range {s t : Set β} (hs : s ⊆ range m) (ht : t ⊆ range m) : s / t ⊆ range m := by
  rintro _ ⟨a, b, ha, hb, rfl⟩;
  obtain ⟨a, rfl⟩ := hs ha
  obtain ⟨b, rfl⟩ := ht hb
  

Proof state:
case intro.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Group α
inst✝¹ : DivisionMonoid β
inst✝ : MonoidHomClass F α β
m : F
s✝ t✝ : Set α
s t : Set β
hs : s ⊆ range ⇑m
ht : t ⊆ range ⇑m
a : α
ha : m a ∈ s
b : α
hb : m b ∈ t
⊢ (fun x x_1 => x / x_1) (m a) (m b) ∈ range ⇑m

Next tactic:
exact ⟨a / b, map_div _ _ _⟩