l3lab/ntp-mathlib huggingface dataset:
theorem volume_of_add_preimage_eq (s I : Set <| AddCircle T) (u x : AddCircle T)
    (hu : IsOfFinAddOrder u) (hs : (u +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s)
    (hI : I =ᵐ[volume] ball x (T / (2 * addOrderOf u))) :
    volume s = addOrderOf u • volume (s ∩ I) := by
  let G := AddSubgroup.zmultiples u
  

Proof state:
T : ℝ
hT : Fact (0 < T)
s I : Set (AddCircle T)
u x : AddCircle T
hu : IsOfFinAddOrder u
hs : u +ᵥ s =ᶠ[ae volume] s
hI : I =ᶠ[ae volume] ball x (T / (2 * ↑(addOrderOf u)))
G : AddSubgroup (AddCircle T) := AddSubgroup.zmultiples u
⊢ ↑↑volume s = addOrderOf u • ↑↑volume (s ∩ I)

Next tactic:
haveI : Fintype G := @Fintype.ofFinite _ hu.finite_zmultiples.to_subtype
theorem volume_of_add_preimage_eq (s I : Set <| AddCircle T) (u x : AddCircle T)
    (hu : IsOfFinAddOrder u) (hs : (u +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s)
    (hI : I =ᵐ[volume] ball x (T / (2 * addOrderOf u))) :
    volume s = addOrderOf u • volume (s ∩ I) := by
  let G := AddSubgroup.zmultiples u
  haveI : Fintype G := @Fintype.ofFinite _ hu.finite_zmultiples.to_subtype
  

Proof state:
T : ℝ
hT : Fact (0 < T)
s I : Set (AddCircle T)
u x : AddCircle T
hu : IsOfFinAddOrder u
hs : u +ᵥ s =ᶠ[ae volume] s
hI : I =ᶠ[ae volume] ball x (T / (2 * ↑(addOrderOf u)))
G : AddSubgroup (AddCircle T) := AddSubgroup.zmultiples u
this : Fintype ↥G
⊢ ↑↑volume s = addOrderOf u • ↑↑volume (s ∩ I)

Next tactic:
have hsG : ∀ g : G, (g +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s := by
    rintro ⟨y, hy⟩; exact (vadd_ae_eq_self_of_mem_zmultiples hs hy : _)
theorem volume_of_add_preimage_eq (s I : Set <| AddCircle T) (u x : AddCircle T)
    (hu : IsOfFinAddOrder u) (hs : (u +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s)
    (hI : I =ᵐ[volume] ball x (T / (2 * addOrderOf u))) :
    volume s = addOrderOf u • volume (s ∩ I) := by
  let G := AddSubgroup.zmultiples u
  haveI : Fintype G := @Fintype.ofFinite _ hu.finite_zmultiples.to_subtype
  have hsG : ∀ g : G, (g +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s := by
    

Proof state:
T : ℝ
hT : Fact (0 < T)
s I : Set (AddCircle T)
u x : AddCircle T
hu : IsOfFinAddOrder u
hs : u +ᵥ s =ᶠ[ae volume] s
hI : I =ᶠ[ae volume] ball x (T / (2 * ↑(addOrderOf u)))
G : AddSubgroup (AddCircle T) := AddSubgroup.zmultiples u
this : Fintype ↥G
⊢ ∀ (g : ↥G), g +ᵥ s =ᶠ[ae volume] s

Next tactic:
rintro ⟨y, hy⟩
theorem volume_of_add_preimage_eq (s I : Set <| AddCircle T) (u x : AddCircle T)
    (hu : IsOfFinAddOrder u) (hs : (u +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s)
    (hI : I =ᵐ[volume] ball x (T / (2 * addOrderOf u))) :
    volume s = addOrderOf u • volume (s ∩ I) := by
  let G := AddSubgroup.zmultiples u
  haveI : Fintype G := @Fintype.ofFinite _ hu.finite_zmultiples.to_subtype
  have hsG : ∀ g : G, (g +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s := by
    rintro ⟨y, hy⟩; 

Proof state:
case mk
T : ℝ
hT : Fact (0 < T)
s I : Set (AddCircle T)
u x : AddCircle T
hu : IsOfFinAddOrder u
hs : u +ᵥ s =ᶠ[ae volume] s
hI : I =ᶠ[ae volume] ball x (T / (2 * ↑(addOrderOf u)))
G : AddSubgroup (AddCircle T) := AddSubgroup.zmultiples u
this : Fintype ↥G
y : AddCircle T
hy : y ∈ G
⊢ { val := y, property := hy } +ᵥ s =ᶠ[ae volume] s

Next tactic:
exact (vadd_ae_eq_self_of_mem_zmultiples hs hy : _)
theorem volume_of_add_preimage_eq (s I : Set <| AddCircle T) (u x : AddCircle T)
    (hu : IsOfFinAddOrder u) (hs : (u +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s)
    (hI : I =ᵐ[volume] ball x (T / (2 * addOrderOf u))) :
    volume s = addOrderOf u • volume (s ∩ I) := by
  let G := AddSubgroup.zmultiples u
  haveI : Fintype G := @Fintype.ofFinite _ hu.finite_zmultiples.to_subtype
  have hsG : ∀ g : G, (g +ᵥ s : Set <| AddCircle T) =ᵐ[volume] s := by
    rintro ⟨y, hy⟩; exact (vadd_ae_eq_self_of_mem_zmultiples hs hy : _)
  

Proof state:
T : ℝ
hT : Fact (0 < T)
s I : Set (AddCircle T)
u x : AddCircle T
hu : IsOfFinAddOrder u
hs : u +ᵥ s =ᶠ[ae volume] s
hI : I =ᶠ[ae volume] ball x (T / (2 * ↑(addOrderOf u)))
G : AddSubgroup (AddCircle T) := AddSubgroup.zmultiples u
this : Fintype ↥G
hsG : ∀ (g : ↥G), g +ᵥ s =ᶠ[ae volume] s
⊢ ↑↑volume s = addOrderOf u • ↑↑volume (s ∩ I)

Next tactic:
rw [(isAddFundamentalDomain_of_ae_ball I u x hu hI).measure_eq_card_smul_of_vadd_ae_eq_self s hsG,
    ← Nat.card_zmultiples u, Nat.card_eq_fintype_card]
instance groupWithZero [GroupWithZero β] : GroupWithZero β* :=
  { Germ.divInvMonoid, Germ.monoidWithZero with
    mul_inv_cancel := fun f => inductionOn f fun f hf => coe_eq.2 <|
      (φ.em fun y => f y = 0).elim (fun H => (hf <| coe_eq.2 H).elim) fun H =>
        H.mono fun x => mul_inv_cancel
    inv_zero := coe_eq.2 <| by
       

Proof state:
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : GroupWithZero β
src✝¹ : DivInvMonoid (Germ (↑φ) β) := divInvMonoid
src✝ : MonoidWithZero (Germ (↑φ) β) := monoidWithZero
⊢ ((fun x => Inv.inv ∘ x) fun x => 0) =ᶠ[↑φ] fun x => 0

Next tactic:
simp only [Function.comp, inv_zero]
instance groupWithZero [GroupWithZero β] : GroupWithZero β* :=
  { Germ.divInvMonoid, Germ.monoidWithZero with
    mul_inv_cancel := fun f => inductionOn f fun f hf => coe_eq.2 <|
      (φ.em fun y => f y = 0).elim (fun H => (hf <| coe_eq.2 H).elim) fun H =>
        H.mono fun x => mul_inv_cancel
    inv_zero := coe_eq.2 <| by
       simp only [Function.comp, inv_zero]
       

Proof state:
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : GroupWithZero β
src✝¹ : DivInvMonoid (Germ (↑φ) β) := divInvMonoid
src✝ : MonoidWithZero (Germ (↑φ) β) := monoidWithZero
⊢ (fun x => 0) =ᶠ[↑φ] fun x => 0

Next tactic:
exact EventuallyEq.refl _ fun _ => 0
theorem coe_lt [Preorder β] {f g : α → β} : (f : β*) < g ↔ ∀* x, f x < g x := by
  

Proof state:
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : Preorder β
f g : α → β
⊢ ↑f < ↑g ↔ ∀* (x : α), f x < g x

Next tactic:
simp only [lt_iff_le_not_le, eventually_and, coe_le, eventually_not, EventuallyLE]
theorem lt_def [Preorder β] : ((· < ·) : β* → β* → Prop) = LiftRel (· < ·) := by
  

Proof state:
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : Preorder β
⊢ (fun x x_1 => x < x_1) = LiftRel fun x x_1 => x < x_1

Next tactic:
ext ⟨f⟩ ⟨g⟩
theorem lt_def [Preorder β] : ((· < ·) : β* → β* → Prop) = LiftRel (· < ·) := by
  ext ⟨f⟩ ⟨g⟩
  

Proof state:
case h.mk.h.mk.a
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : Preorder β
x✝¹ : Germ (↑φ) β
f : α → β
x✝ : Germ (↑φ) β
g : α → β
⊢ Quot.mk Setoid.r f < Quot.mk Setoid.r g ↔ LiftRel (fun x x_1 => x < x_1) (Quot.mk Setoid.r f) (Quot.mk Setoid.r g)

Next tactic:
exact coe_lt
theorem max_def [LinearOrder β] (x y : β*) : max x y = map₂ max x y :=
  inductionOn₂ x y fun a b => by
    

Proof state:
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
⊢ max ↑a ↑b = map₂ max ↑a ↑b

Next tactic:
rcases le_total (a : β*) b with h | h
theorem max_def [LinearOrder β] (x y : β*) : max x y = map₂ max x y :=
  inductionOn₂ x y fun a b => by
    rcases le_total (a : β*) b with h | h
    · 

Proof state:
case inl
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
h : ↑a ≤ ↑b
⊢ max ↑a ↑b = map₂ max ↑a ↑b

Next tactic:
rw [max_eq_right h, map₂_coe, coe_eq]
theorem max_def [LinearOrder β] (x y : β*) : max x y = map₂ max x y :=
  inductionOn₂ x y fun a b => by
    rcases le_total (a : β*) b with h | h
    · rw [max_eq_right h, map₂_coe, coe_eq]
      

Proof state:
case inl
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
h : ↑a ≤ ↑b
⊢ b =ᶠ[↑φ] fun x => max (a x) (b x)

Next tactic:
exact h.mono fun i hi => (max_eq_right hi).symm
theorem max_def [LinearOrder β] (x y : β*) : max x y = map₂ max x y :=
  inductionOn₂ x y fun a b => by
    rcases le_total (a : β*) b with h | h
    · rw [max_eq_right h, map₂_coe, coe_eq]
      exact h.mono fun i hi => (max_eq_right hi).symm
    · 

Proof state:
case inr
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
h : ↑b ≤ ↑a
⊢ max ↑a ↑b = map₂ max ↑a ↑b

Next tactic:
rw [max_eq_left h, map₂_coe, coe_eq]
theorem max_def [LinearOrder β] (x y : β*) : max x y = map₂ max x y :=
  inductionOn₂ x y fun a b => by
    rcases le_total (a : β*) b with h | h
    · rw [max_eq_right h, map₂_coe, coe_eq]
      exact h.mono fun i hi => (max_eq_right hi).symm
    · rw [max_eq_left h, map₂_coe, coe_eq]
      

Proof state:
case inr
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
h : ↑b ≤ ↑a
⊢ a =ᶠ[↑φ] fun x => max (a x) (b x)

Next tactic:
exact h.mono fun i hi => (max_eq_left hi).symm
theorem min_def [K : LinearOrder β] (x y : β*) : min x y = map₂ min x y :=
  inductionOn₂ x y fun a b => by
    

Proof state:
α : Type u
β : Type v
φ : Ultrafilter α
K : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
⊢ min ↑a ↑b = map₂ min ↑a ↑b

Next tactic:
rcases le_total (a : β*) b with h | h
theorem min_def [K : LinearOrder β] (x y : β*) : min x y = map₂ min x y :=
  inductionOn₂ x y fun a b => by
    rcases le_total (a : β*) b with h | h
    · 

Proof state:
case inl
α : Type u
β : Type v
φ : Ultrafilter α
K : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
h : ↑a ≤ ↑b
⊢ min ↑a ↑b = map₂ min ↑a ↑b

Next tactic:
rw [min_eq_left h, map₂_coe, coe_eq]
theorem min_def [K : LinearOrder β] (x y : β*) : min x y = map₂ min x y :=
  inductionOn₂ x y fun a b => by
    rcases le_total (a : β*) b with h | h
    · rw [min_eq_left h, map₂_coe, coe_eq]
      

Proof state:
case inl
α : Type u
β : Type v
φ : Ultrafilter α
K : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
h : ↑a ≤ ↑b
⊢ a =ᶠ[↑φ] fun x => min (a x) (b x)

Next tactic:
exact h.mono fun i hi => (min_eq_left hi).symm
theorem min_def [K : LinearOrder β] (x y : β*) : min x y = map₂ min x y :=
  inductionOn₂ x y fun a b => by
    rcases le_total (a : β*) b with h | h
    · rw [min_eq_left h, map₂_coe, coe_eq]
      exact h.mono fun i hi => (min_eq_left hi).symm
    · 

Proof state:
case inr
α : Type u
β : Type v
φ : Ultrafilter α
K : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
h : ↑b ≤ ↑a
⊢ min ↑a ↑b = map₂ min ↑a ↑b

Next tactic:
rw [min_eq_right h, map₂_coe, coe_eq]
theorem min_def [K : LinearOrder β] (x y : β*) : min x y = map₂ min x y :=
  inductionOn₂ x y fun a b => by
    rcases le_total (a : β*) b with h | h
    · rw [min_eq_left h, map₂_coe, coe_eq]
      exact h.mono fun i hi => (min_eq_left hi).symm
    · rw [min_eq_right h, map₂_coe, coe_eq]
      

Proof state:
case inr
α : Type u
β : Type v
φ : Ultrafilter α
K : LinearOrder β
x y : Germ (↑φ) β
a b : α → β
h : ↑b ≤ ↑a
⊢ b =ᶠ[↑φ] fun x => min (a x) (b x)

Next tactic:
exact h.mono fun i hi => (min_eq_right hi).symm
@[simp]
theorem const_max [LinearOrder β] (x y : β) : (↑(max x y : β) : β*) = max ↑x ↑y := by
  

Proof state:
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : LinearOrder β
x y : β
⊢ ↑(max x y) = max ↑x ↑y

Next tactic:
rw [max_def, map₂_const]
@[simp]
theorem const_min [LinearOrder β] (x y : β) : (↑(min x y : β) : β*) = min ↑x ↑y := by
  

Proof state:
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : LinearOrder β
x y : β
⊢ ↑(min x y) = min ↑x ↑y

Next tactic:
rw [min_def, map₂_const]
@[simp]
theorem const_abs [LinearOrderedAddCommGroup β] (x : β) : (↑|x| : β*) = |↑x| := by
  

Proof state:
α : Type u
β : Type v
φ : Ultrafilter α
inst✝ : LinearOrderedAddCommGroup β
x : β
⊢ ↑|x| = |↑x|

Next tactic:
rw [abs_def, map_const]
/-- Pull back a `MulZeroClass` instance along an injective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.mulZeroClass [Mul M₀'] [Zero M₀'] (f : M₀' → M₀) (hf : Injective f)
    (zero : f 0 = 0) (mul : ∀ a b, f (a * b) = f a * f b) : MulZeroClass M₀' where
  mul := (· * ·)
  zero := 0
  zero_mul a := hf <| by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝² : MulZeroClass M₀
a✝ b : M₀
inst✝¹ : Mul M₀'
inst✝ : Zero M₀'
f : M₀' → M₀
hf : Injective f
zero : f 0 = 0
mul : ∀ (a b : M₀'), f (a * b) = f a * f b
a : M₀'
⊢ f (0 * a) = f 0

Next tactic:
simp only [mul, zero, zero_mul]
/-- Pull back a `MulZeroClass` instance along an injective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.mulZeroClass [Mul M₀'] [Zero M₀'] (f : M₀' → M₀) (hf : Injective f)
    (zero : f 0 = 0) (mul : ∀ a b, f (a * b) = f a * f b) : MulZeroClass M₀' where
  mul := (· * ·)
  zero := 0
  zero_mul a := hf <| by simp only [mul, zero, zero_mul]
  mul_zero a := hf <| by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝² : MulZeroClass M₀
a✝ b : M₀
inst✝¹ : Mul M₀'
inst✝ : Zero M₀'
f : M₀' → M₀
hf : Injective f
zero : f 0 = 0
mul : ∀ (a b : M₀'), f (a * b) = f a * f b
a : M₀'
⊢ f (a * 0) = f 0

Next tactic:
simp only [mul, zero, mul_zero]
/-- Push forward a `MulZeroClass` instance along a surjective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.mulZeroClass [Mul M₀'] [Zero M₀'] (f : M₀ → M₀')
    (hf : Surjective f) (zero : f 0 = 0) (mul : ∀ a b, f (a * b) = f a * f b) :
    MulZeroClass M₀' where
  mul := (· * ·)
  zero := 0
  mul_zero := hf.forall.2 fun x => by simp only [← zero, ← mul, mul_zero]
  zero_mul := hf.forall.2 fun x => by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝² : MulZeroClass M₀
a b : M₀
inst✝¹ : Mul M₀'
inst✝ : Zero M₀'
f : M₀ → M₀'
hf : Surjective f
zero : f 0 = 0
mul : ∀ (a b : M₀), f (a * b) = f a * f b
x : M₀
⊢ 0 * f x = 0

Next tactic:
simp only [← zero, ← mul, zero_mul]
/-- Push forward a `MulZeroClass` instance along a surjective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.mulZeroClass [Mul M₀'] [Zero M₀'] (f : M₀ → M₀')
    (hf : Surjective f) (zero : f 0 = 0) (mul : ∀ a b, f (a * b) = f a * f b) :
    MulZeroClass M₀' where
  mul := (· * ·)
  zero := 0
  mul_zero := hf.forall.2 fun x => by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝² : MulZeroClass M₀
a b : M₀
inst✝¹ : Mul M₀'
inst✝ : Zero M₀'
f : M₀ → M₀'
hf : Surjective f
zero : f 0 = 0
mul : ∀ (a b : M₀), f (a * b) = f a * f b
x : M₀
⊢ f x * 0 = 0

Next tactic:
simp only [← zero, ← mul, mul_zero]
/-- Pull back a `NoZeroDivisors` instance along an injective function. -/
protected theorem Function.Injective.noZeroDivisors [NoZeroDivisors M₀'] : NoZeroDivisors M₀ :=
  { eq_zero_or_eq_zero_of_mul_eq_zero := fun H =>
      have : f _ * f _ = 0 := by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : NoZeroDivisors M₀'
a✝ b✝ : M₀
H : a✝ * b✝ = 0
⊢ f (?m.2223 H) * f (?m.2224 H) = 0

Next tactic:
rw [← mul, H, zero]
/-- Pull back a `NoZeroDivisors` instance along an injective function. -/
protected theorem Function.Injective.noZeroDivisors [NoZeroDivisors M₀'] : NoZeroDivisors M₀ :=
  { eq_zero_or_eq_zero_of_mul_eq_zero := fun H =>
      have : f _ * f _ = 0 := by rw [← mul, H, zero]
      (eq_zero_or_eq_zero_of_mul_eq_zero this).imp
        (fun H => hf <| by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : NoZeroDivisors M₀'
a✝ b✝ : M₀
H✝ : a✝ * b✝ = 0
this : f a✝ * f b✝ = 0
H : f a✝ = 0
⊢ f a✝ = f 0

Next tactic:
rwa [zero]
/-- Pull back a `NoZeroDivisors` instance along an injective function. -/
protected theorem Function.Injective.noZeroDivisors [NoZeroDivisors M₀'] : NoZeroDivisors M₀ :=
  { eq_zero_or_eq_zero_of_mul_eq_zero := fun H =>
      have : f _ * f _ = 0 := by rw [← mul, H, zero]
      (eq_zero_or_eq_zero_of_mul_eq_zero this).imp
        (fun H => hf <| by rwa [zero]) fun H => hf <| by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : NoZeroDivisors M₀'
a✝ b✝ : M₀
H✝ : a✝ * b✝ = 0
this : f a✝ * f b✝ = 0
H : f b✝ = 0
⊢ f b✝ = f 0

Next tactic:
rwa [zero]
protected theorem Function.Injective.isLeftCancelMulZero
    [IsLeftCancelMulZero M₀'] : IsLeftCancelMulZero M₀ :=
  { mul_left_cancel_of_ne_zero := fun Hne He => by
      

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : IsLeftCancelMulZero M₀'
a✝ b✝ c✝ : M₀
Hne : a✝ ≠ 0
He : a✝ * b✝ = a✝ * c✝
⊢ b✝ = c✝

Next tactic:
have := congr_arg f He
protected theorem Function.Injective.isLeftCancelMulZero
    [IsLeftCancelMulZero M₀'] : IsLeftCancelMulZero M₀ :=
  { mul_left_cancel_of_ne_zero := fun Hne He => by
      have := congr_arg f He
      

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : IsLeftCancelMulZero M₀'
a✝ b✝ c✝ : M₀
Hne : a✝ ≠ 0
He : a✝ * b✝ = a✝ * c✝
this : f (a✝ * b✝) = f (a✝ * c✝)
⊢ b✝ = c✝

Next tactic:
rw [mul, mul] at this
protected theorem Function.Injective.isLeftCancelMulZero
    [IsLeftCancelMulZero M₀'] : IsLeftCancelMulZero M₀ :=
  { mul_left_cancel_of_ne_zero := fun Hne He => by
      have := congr_arg f He
      rw [mul, mul] at this
      

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : IsLeftCancelMulZero M₀'
a✝ b✝ c✝ : M₀
Hne : a✝ ≠ 0
He : a✝ * b✝ = a✝ * c✝
this : f a✝ * f b✝ = f a✝ * f c✝
⊢ b✝ = c✝

Next tactic:
exact hf (mul_left_cancel₀ (fun Hfa => Hne <| hf <| by rw [Hfa, zero]) this)
protected theorem Function.Injective.isLeftCancelMulZero
    [IsLeftCancelMulZero M₀'] : IsLeftCancelMulZero M₀ :=
  { mul_left_cancel_of_ne_zero := fun Hne He => by
      have := congr_arg f He
      rw [mul, mul] at this
      exact hf (mul_left_cancel₀ (fun Hfa => Hne <| hf <| by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : IsLeftCancelMulZero M₀'
a✝ b✝ c✝ : M₀
Hne : a✝ ≠ 0
He : a✝ * b✝ = a✝ * c✝
this : f a✝ * f b✝ = f a✝ * f c✝
Hfa : f a✝ = 0
⊢ f a✝ = f 0

Next tactic:
rw [Hfa, zero]
protected theorem Function.Injective.isRightCancelMulZero
    [IsRightCancelMulZero M₀'] : IsRightCancelMulZero M₀ :=
  { mul_right_cancel_of_ne_zero := fun Hne He => by
      

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : IsRightCancelMulZero M₀'
a✝ b✝ c✝ : M₀
Hne : b✝ ≠ 0
He : a✝ * b✝ = c✝ * b✝
⊢ a✝ = c✝

Next tactic:
have := congr_arg f He
protected theorem Function.Injective.isRightCancelMulZero
    [IsRightCancelMulZero M₀'] : IsRightCancelMulZero M₀ :=
  { mul_right_cancel_of_ne_zero := fun Hne He => by
      have := congr_arg f He
      

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : IsRightCancelMulZero M₀'
a✝ b✝ c✝ : M₀
Hne : b✝ ≠ 0
He : a✝ * b✝ = c✝ * b✝
this : f (a✝ * b✝) = f (c✝ * b✝)
⊢ a✝ = c✝

Next tactic:
rw [mul, mul] at this
protected theorem Function.Injective.isRightCancelMulZero
    [IsRightCancelMulZero M₀'] : IsRightCancelMulZero M₀ :=
  { mul_right_cancel_of_ne_zero := fun Hne He => by
      have := congr_arg f He
      rw [mul, mul] at this
      

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : IsRightCancelMulZero M₀'
a✝ b✝ c✝ : M₀
Hne : b✝ ≠ 0
He : a✝ * b✝ = c✝ * b✝
this : f a✝ * f b✝ = f c✝ * f b✝
⊢ a✝ = c✝

Next tactic:
exact hf (mul_right_cancel₀ (fun Hfa => Hne <| hf <| by rw [Hfa, zero]) this)
protected theorem Function.Injective.isRightCancelMulZero
    [IsRightCancelMulZero M₀'] : IsRightCancelMulZero M₀ :=
  { mul_right_cancel_of_ne_zero := fun Hne He => by
      have := congr_arg f He
      rw [mul, mul] at this
      exact hf (mul_right_cancel₀ (fun Hfa => Hne <| hf <| by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : Mul M₀
inst✝³ : Zero M₀
inst✝² : Mul M₀'
inst✝¹ : Zero M₀'
f : M₀ → M₀'
hf : Injective f
zero : f 0 = 0
mul : ∀ (x y : M₀), f (x * y) = f x * f y
inst✝ : IsRightCancelMulZero M₀'
a✝ b✝ c✝ : M₀
Hne : b✝ ≠ 0
He : a✝ * b✝ = c✝ * b✝
this : f a✝ * f b✝ = f c✝ * f b✝
Hfa : f b✝ = 0
⊢ f b✝ = f 0

Next tactic:
rw [Hfa, zero]
/-- Pull back a `CancelMonoidWithZero` along an injective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.cancelMonoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ]
    (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1)
    (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) :
    CancelMonoidWithZero M₀' :=
  { hf.monoid f one mul npow, hf.mulZeroClass f zero mul with
    mul_left_cancel_of_ne_zero := fun hx H =>
      hf <| mul_left_cancel₀ ((hf.ne_iff' zero).2 hx) <| by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : CancelMonoidWithZero M₀
a b c : M₀
inst✝³ : Zero M₀'
inst✝² : Mul M₀'
inst✝¹ : One M₀'
inst✝ : Pow M₀' ℕ
f : M₀' → M₀
hf : Injective f
zero : f 0 = 0
one : f 1 = 1
mul : ∀ (x y : M₀'), f (x * y) = f x * f y
npow : ∀ (x : M₀') (n : ℕ), f (x ^ n) = f x ^ n
src✝¹ : Monoid M₀' := Injective.monoid f hf one mul npow
src✝ : MulZeroClass M₀' := Injective.mulZeroClass f hf zero mul
a✝ b✝ c✝ : M₀'
hx : a✝ ≠ 0
H : a✝ * b✝ = a✝ * c✝
⊢ f a✝ * f b✝ = f a✝ * f c✝

Next tactic:
erw [← mul, ← mul, H]
/-- Pull back a `CancelMonoidWithZero` along an injective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.cancelMonoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ]
    (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1)
    (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) :
    CancelMonoidWithZero M₀' :=
  { hf.monoid f one mul npow, hf.mulZeroClass f zero mul with
    mul_left_cancel_of_ne_zero := fun hx H =>
      hf <| mul_left_cancel₀ ((hf.ne_iff' zero).2 hx) <| by erw [← mul, ← mul, H],
    mul_right_cancel_of_ne_zero := fun hx H =>
      hf <| mul_right_cancel₀ ((hf.ne_iff' zero).2 hx) <| by 

Proof state:
M₀ : Type u_1
G₀ : Type u_2
M₀' : Type u_3
G₀' : Type u_4
inst✝⁴ : CancelMonoidWithZero M₀
a b c : M₀
inst✝³ : Zero M₀'
inst✝² : Mul M₀'
inst✝¹ : One M₀'
inst✝ : Pow M₀' ℕ
f : M₀' → M₀
hf : Injective f
zero : f 0 = 0
one : f 1 = 1
mul : ∀ (x y : M₀'), f (x * y) = f x * f y
npow : ∀ (x : M₀') (n : ℕ), f (x ^ n) = f x ^ n
src✝¹ : Monoid M₀' := Injective.monoid f hf one mul npow
src✝ : MulZeroClass M₀' := Injective.mulZeroClass f hf zero mul
a✝ b✝ c✝ : M₀'
hx : b✝ ≠ 0
H : a✝ * b✝ = c✝ * b✝
⊢ f a✝ * f b✝ = f c✝ * f b✝

Next tactic:
erw [← mul, ← mul, H]