l3lab/ntp-mathlib huggingface dataset:
instance addGroup : AddGroup (Completion α) :=
  { (inferInstance : SubNegMonoid $ Completion α) with
    add_left_neg := fun a ↦
      Completion.induction_on a
        (isClosed_eq (continuous_map₂ Completion.continuous_map continuous_id) continuous_const)
        fun a ↦
        show -(a : Completion α) + a = 0 by
          

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝² : UniformSpace α
inst✝¹ : AddGroup α
inst✝ : UniformAddGroup α
src✝ : SubNegMonoid (Completion α) := inferInstance
a✝ : Completion α
a : α
⊢ -↑α a + ↑α a = 0

Next tactic:
rw_mod_cast [add_left_neg]
instance addGroup : AddGroup (Completion α) :=
  { (inferInstance : SubNegMonoid $ Completion α) with
    add_left_neg := fun a ↦
      Completion.induction_on a
        (isClosed_eq (continuous_map₂ Completion.continuous_map continuous_id) continuous_const)
        fun a ↦
        show -(a : Completion α) + a = 0 by
          rw_mod_cast [add_left_neg]
          

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝² : UniformSpace α
inst✝¹ : AddGroup α
inst✝ : UniformAddGroup α
src✝ : SubNegMonoid (Completion α) := inferInstance
a✝ : Completion α
a : α
⊢ ↑α 0 = 0

Next tactic:
rfl
instance {M} [Monoid M] [DistribMulAction M α] [UniformContinuousConstSMul M α] :
    DistribMulAction M (Completion α) :=
  { (inferInstance : MulAction M $ Completion α) with
    smul_add := fun r x y ↦
      induction_on₂ x y
        (isClosed_eq ((continuous_fst.add continuous_snd).const_smul _)
          ((continuous_fst.const_smul _).add (continuous_snd.const_smul _)))
        fun a b ↦ by simp only [← coe_add, ← coe_smul, smul_add]
    smul_zero := fun r ↦ by 

Proof state:
M✝ : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁵ : UniformSpace α
inst✝⁴ : AddGroup α
inst✝³ : UniformAddGroup α
M : Type ?u.32677
inst✝² : Monoid M
inst✝¹ : DistribMulAction M α
inst✝ : UniformContinuousConstSMul M α
src✝ : MulAction M (Completion α) := inferInstance
r : M
⊢ r • 0 = 0

Next tactic:
rw [← coe_zero, ← coe_smul, smul_zero r]
instance {M} [Monoid M] [DistribMulAction M α] [UniformContinuousConstSMul M α] :
    DistribMulAction M (Completion α) :=
  { (inferInstance : MulAction M $ Completion α) with
    smul_add := fun r x y ↦
      induction_on₂ x y
        (isClosed_eq ((continuous_fst.add continuous_snd).const_smul _)
          ((continuous_fst.const_smul _).add (continuous_snd.const_smul _)))
        fun a b ↦ by 

Proof state:
M✝ : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁵ : UniformSpace α
inst✝⁴ : AddGroup α
inst✝³ : UniformAddGroup α
M : Type ?u.32677
inst✝² : Monoid M
inst✝¹ : DistribMulAction M α
inst✝ : UniformContinuousConstSMul M α
src✝ : MulAction M (Completion α) := inferInstance
r : M
x y : Completion α
a b : α
⊢ r • (↑α a + ↑α b) = r • ↑α a + r • ↑α b

Next tactic:
simp only [← coe_add, ← coe_smul, smul_add]
instance : AddCommGroup (Completion α) :=
  { (inferInstance : AddGroup $ Completion α) with
    add_comm := fun a b ↦
      Completion.induction_on₂ a b
        (isClosed_eq (continuous_map₂ continuous_fst continuous_snd)
          (continuous_map₂ continuous_snd continuous_fst))
        fun x y ↦ by
        

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝² : UniformSpace α
inst✝¹ : AddCommGroup α
inst✝ : UniformAddGroup α
src✝ : AddGroup (Completion α) := inferInstance
a b : Completion α
x y : α
⊢ ↑α x + ↑α y = ↑α y + ↑α x

Next tactic:
change (x : Completion α) + ↑y = ↑y + ↑x
instance : AddCommGroup (Completion α) :=
  { (inferInstance : AddGroup $ Completion α) with
    add_comm := fun a b ↦
      Completion.induction_on₂ a b
        (isClosed_eq (continuous_map₂ continuous_fst continuous_snd)
          (continuous_map₂ continuous_snd continuous_fst))
        fun x y ↦ by
        change (x : Completion α) + ↑y = ↑y + ↑x
        

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝² : UniformSpace α
inst✝¹ : AddCommGroup α
inst✝ : UniformAddGroup α
src✝ : AddGroup (Completion α) := inferInstance
a b : Completion α
x y : α
⊢ ↑α x + ↑α y = ↑α y + ↑α x

Next tactic:
rw [← coe_add, ← coe_add, add_comm]
instance instModule [Semiring R] [Module R α] [UniformContinuousConstSMul R α] :
    Module R (Completion α) :=
  { (inferInstance : DistribMulAction R $ Completion α),
    (inferInstance : MulActionWithZero R $ Completion α) with
    add_smul := fun a b ↦
      ext' (continuous_const_smul _) ((continuous_const_smul _).add (continuous_const_smul _))
        fun x ↦ by
          

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁵ : UniformSpace α
inst✝⁴ : AddCommGroup α
inst✝³ : UniformAddGroup α
inst✝² : Semiring R
inst✝¹ : Module R α
inst✝ : UniformContinuousConstSMul R α
src✝¹ : DistribMulAction R (Completion α) := inferInstance
src✝ : MulActionWithZero R (Completion α) := inferInstance
a b : R
x : α
⊢ (a + b) • ↑α x = a • ↑α x + b • ↑α x

Next tactic:
rw [← coe_smul, add_smul, coe_add, coe_smul, coe_smul]
/-- Extension to the completion of a continuous group hom. -/
def AddMonoidHom.extension [CompleteSpace β] [SeparatedSpace β] (f : α →+ β) (hf : Continuous f) :
    Completion α →+ β :=
  have hf : UniformContinuous f := uniformContinuous_addMonoidHom_of_continuous hf
  { toFun := Completion.extension f
    map_zero' := by 

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁷ : UniformSpace α
inst✝⁶ : AddGroup α
inst✝⁵ : UniformAddGroup α
inst✝⁴ : UniformSpace β
inst✝³ : AddGroup β
inst✝² : UniformAddGroup β
inst✝¹ : CompleteSpace β
inst✝ : SeparatedSpace β
f : α →+ β
hf✝ : Continuous ⇑f
hf : UniformContinuous ⇑f
⊢ Completion.extension (⇑f) 0 = 0

Next tactic:
rw [← coe_zero, extension_coe hf, f.map_zero]
/-- Extension to the completion of a continuous group hom. -/
def AddMonoidHom.extension [CompleteSpace β] [SeparatedSpace β] (f : α →+ β) (hf : Continuous f) :
    Completion α →+ β :=
  have hf : UniformContinuous f := uniformContinuous_addMonoidHom_of_continuous hf
  { toFun := Completion.extension f
    map_zero' := by rw [← coe_zero, extension_coe hf, f.map_zero]
    map_add' := fun a b ↦
      Completion.induction_on₂ a b
        (isClosed_eq (continuous_extension.comp continuous_add)
          ((continuous_extension.comp continuous_fst).add
            (continuous_extension.comp continuous_snd)))
        fun a b ↦
        show Completion.extension f _ = Completion.extension f _ + Completion.extension f _ by
        

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁷ : UniformSpace α
inst✝⁶ : AddGroup α
inst✝⁵ : UniformAddGroup α
inst✝⁴ : UniformSpace β
inst✝³ : AddGroup β
inst✝² : UniformAddGroup β
inst✝¹ : CompleteSpace β
inst✝ : SeparatedSpace β
f : α →+ β
hf✝ : Continuous ⇑f
hf : UniformContinuous ⇑f
a✝ b✝ : Completion α
a b : α
⊢ Completion.extension (⇑f) (↑α a + ↑α b) = Completion.extension (⇑f) (↑α a) + Completion.extension (⇑f) (↑α b)

Next tactic:
rw_mod_cast [extension_coe hf, extension_coe hf, extension_coe hf, f.map_add]
theorem AddMonoidHom.completion_zero :
    AddMonoidHom.completion (0 : α →+ β) continuous_const = 0 := by
  

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁵ : UniformSpace α
inst✝⁴ : AddGroup α
inst✝³ : UniformAddGroup α
inst✝² : UniformSpace β
inst✝¹ : AddGroup β
inst✝ : UniformAddGroup β
⊢ completion 0 (_ : Continuous fun x => AddZeroClass.toZero.1) = 0

Next tactic:
ext x
theorem AddMonoidHom.completion_zero :
    AddMonoidHom.completion (0 : α →+ β) continuous_const = 0 := by
  ext x
  

Proof state:
case h
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁵ : UniformSpace α
inst✝⁴ : AddGroup α
inst✝³ : UniformAddGroup α
inst✝² : UniformSpace β
inst✝¹ : AddGroup β
inst✝ : UniformAddGroup β
x : Completion α
⊢ (completion 0 (_ : Continuous fun x => AddZeroClass.toZero.1)) x = 0 x

Next tactic:
refine Completion.induction_on x ?_ ?_
theorem AddMonoidHom.completion_zero :
    AddMonoidHom.completion (0 : α →+ β) continuous_const = 0 := by
  ext x
  refine Completion.induction_on x ?_ ?_
  · 

Proof state:
case h.refine_1
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁵ : UniformSpace α
inst✝⁴ : AddGroup α
inst✝³ : UniformAddGroup α
inst✝² : UniformSpace β
inst✝¹ : AddGroup β
inst✝ : UniformAddGroup β
x : Completion α
⊢ IsClosed {a | (completion 0 (_ : Continuous fun x => AddZeroClass.toZero.1)) a = 0 a}

Next tactic:
apply isClosed_eq (AddMonoidHom.continuous_completion (0 : α →+ β) continuous_const)
theorem AddMonoidHom.completion_zero :
    AddMonoidHom.completion (0 : α →+ β) continuous_const = 0 := by
  ext x
  refine Completion.induction_on x ?_ ?_
  · apply isClosed_eq (AddMonoidHom.continuous_completion (0 : α →+ β) continuous_const)
    

Proof state:
case h.refine_1
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁵ : UniformSpace α
inst✝⁴ : AddGroup α
inst✝³ : UniformAddGroup α
inst✝² : UniformSpace β
inst✝¹ : AddGroup β
inst✝ : UniformAddGroup β
x : Completion α
⊢ Continuous fun y => 0 y

Next tactic:
simp [continuous_const]
theorem AddMonoidHom.completion_zero :
    AddMonoidHom.completion (0 : α →+ β) continuous_const = 0 := by
  ext x
  refine Completion.induction_on x ?_ ?_
  · apply isClosed_eq (AddMonoidHom.continuous_completion (0 : α →+ β) continuous_const)
    simp [continuous_const]
  · 

Proof state:
case h.refine_2
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁵ : UniformSpace α
inst✝⁴ : AddGroup α
inst✝³ : UniformAddGroup α
inst✝² : UniformSpace β
inst✝¹ : AddGroup β
inst✝ : UniformAddGroup β
x : Completion α
⊢ ∀ (a : α), (completion 0 (_ : Continuous fun x => AddZeroClass.toZero.1)) (↑α a) = 0 (↑α a)

Next tactic:
intro a
theorem AddMonoidHom.completion_zero :
    AddMonoidHom.completion (0 : α →+ β) continuous_const = 0 := by
  ext x
  refine Completion.induction_on x ?_ ?_
  · apply isClosed_eq (AddMonoidHom.continuous_completion (0 : α →+ β) continuous_const)
    simp [continuous_const]
  · intro a
    

Proof state:
case h.refine_2
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁵ : UniformSpace α
inst✝⁴ : AddGroup α
inst✝³ : UniformAddGroup α
inst✝² : UniformSpace β
inst✝¹ : AddGroup β
inst✝ : UniformAddGroup β
x : Completion α
a : α
⊢ (completion 0 (_ : Continuous fun x => AddZeroClass.toZero.1)) (↑α a) = 0 (↑α a)

Next tactic:
simp [(0 : α →+ β).completion_coe continuous_const, coe_zero]
theorem AddMonoidHom.completion_add {γ : Type*} [AddCommGroup γ] [UniformSpace γ]
    [UniformAddGroup γ] (f g : α →+ γ) (hf : Continuous f) (hg : Continuous g) :
    AddMonoidHom.completion (f + g) (hf.add hg) =
    AddMonoidHom.completion f hf + AddMonoidHom.completion g hg := by
  

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁸ : UniformSpace α
inst✝⁷ : AddGroup α
inst✝⁶ : UniformAddGroup α
inst✝⁵ : UniformSpace β
inst✝⁴ : AddGroup β
inst✝³ : UniformAddGroup β
γ : Type u_5
inst✝² : AddCommGroup γ
inst✝¹ : UniformSpace γ
inst✝ : UniformAddGroup γ
f g : α →+ γ
hf : Continuous ⇑f
hg : Continuous ⇑g
⊢ completion (f + g) (_ : Continuous fun x => f x + g x) = completion f hf + completion g hg

Next tactic:
have hfg := hf.add hg
theorem AddMonoidHom.completion_add {γ : Type*} [AddCommGroup γ] [UniformSpace γ]
    [UniformAddGroup γ] (f g : α →+ γ) (hf : Continuous f) (hg : Continuous g) :
    AddMonoidHom.completion (f + g) (hf.add hg) =
    AddMonoidHom.completion f hf + AddMonoidHom.completion g hg := by
  have hfg := hf.add hg
  

Proof state:
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁸ : UniformSpace α
inst✝⁷ : AddGroup α
inst✝⁶ : UniformAddGroup α
inst✝⁵ : UniformSpace β
inst✝⁴ : AddGroup β
inst✝³ : UniformAddGroup β
γ : Type u_5
inst✝² : AddCommGroup γ
inst✝¹ : UniformSpace γ
inst✝ : UniformAddGroup γ
f g : α →+ γ
hf : Continuous ⇑f
hg : Continuous ⇑g
hfg : Continuous fun x => f x + g x
⊢ completion (f + g) (_ : Continuous fun x => f x + g x) = completion f hf + completion g hg

Next tactic:
ext x
theorem AddMonoidHom.completion_add {γ : Type*} [AddCommGroup γ] [UniformSpace γ]
    [UniformAddGroup γ] (f g : α →+ γ) (hf : Continuous f) (hg : Continuous g) :
    AddMonoidHom.completion (f + g) (hf.add hg) =
    AddMonoidHom.completion f hf + AddMonoidHom.completion g hg := by
  have hfg := hf.add hg
  ext x
  

Proof state:
case h
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁸ : UniformSpace α
inst✝⁷ : AddGroup α
inst✝⁶ : UniformAddGroup α
inst✝⁵ : UniformSpace β
inst✝⁴ : AddGroup β
inst✝³ : UniformAddGroup β
γ : Type u_5
inst✝² : AddCommGroup γ
inst✝¹ : UniformSpace γ
inst✝ : UniformAddGroup γ
f g : α →+ γ
hf : Continuous ⇑f
hg : Continuous ⇑g
hfg : Continuous fun x => f x + g x
x : Completion α
⊢ (completion (f + g) (_ : Continuous fun x => f x + g x)) x = (completion f hf + completion g hg) x

Next tactic:
refine Completion.induction_on x ?_ ?_
theorem AddMonoidHom.completion_add {γ : Type*} [AddCommGroup γ] [UniformSpace γ]
    [UniformAddGroup γ] (f g : α →+ γ) (hf : Continuous f) (hg : Continuous g) :
    AddMonoidHom.completion (f + g) (hf.add hg) =
    AddMonoidHom.completion f hf + AddMonoidHom.completion g hg := by
  have hfg := hf.add hg
  ext x
  refine Completion.induction_on x ?_ ?_
  · 

Proof state:
case h.refine_1
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁸ : UniformSpace α
inst✝⁷ : AddGroup α
inst✝⁶ : UniformAddGroup α
inst✝⁵ : UniformSpace β
inst✝⁴ : AddGroup β
inst✝³ : UniformAddGroup β
γ : Type u_5
inst✝² : AddCommGroup γ
inst✝¹ : UniformSpace γ
inst✝ : UniformAddGroup γ
f g : α →+ γ
hf : Continuous ⇑f
hg : Continuous ⇑g
hfg : Continuous fun x => f x + g x
x : Completion α
⊢ IsClosed {a | (completion (f + g) (_ : Continuous fun x => f x + g x)) a = (completion f hf + completion g hg) a}

Next tactic:
exact isClosed_eq ((f + g).continuous_completion hfg)
      ((f.continuous_completion hf).add (g.continuous_completion hg))
theorem AddMonoidHom.completion_add {γ : Type*} [AddCommGroup γ] [UniformSpace γ]
    [UniformAddGroup γ] (f g : α →+ γ) (hf : Continuous f) (hg : Continuous g) :
    AddMonoidHom.completion (f + g) (hf.add hg) =
    AddMonoidHom.completion f hf + AddMonoidHom.completion g hg := by
  have hfg := hf.add hg
  ext x
  refine Completion.induction_on x ?_ ?_
  · exact isClosed_eq ((f + g).continuous_completion hfg)
      ((f.continuous_completion hf).add (g.continuous_completion hg))
  · 

Proof state:
case h.refine_2
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁸ : UniformSpace α
inst✝⁷ : AddGroup α
inst✝⁶ : UniformAddGroup α
inst✝⁵ : UniformSpace β
inst✝⁴ : AddGroup β
inst✝³ : UniformAddGroup β
γ : Type u_5
inst✝² : AddCommGroup γ
inst✝¹ : UniformSpace γ
inst✝ : UniformAddGroup γ
f g : α →+ γ
hf : Continuous ⇑f
hg : Continuous ⇑g
hfg : Continuous fun x => f x + g x
x : Completion α
⊢ ∀ (a : α),
    (completion (f + g) (_ : Continuous fun x => f x + g x)) (↑α a) = (completion f hf + completion g hg) (↑α a)

Next tactic:
intro a
theorem AddMonoidHom.completion_add {γ : Type*} [AddCommGroup γ] [UniformSpace γ]
    [UniformAddGroup γ] (f g : α →+ γ) (hf : Continuous f) (hg : Continuous g) :
    AddMonoidHom.completion (f + g) (hf.add hg) =
    AddMonoidHom.completion f hf + AddMonoidHom.completion g hg := by
  have hfg := hf.add hg
  ext x
  refine Completion.induction_on x ?_ ?_
  · exact isClosed_eq ((f + g).continuous_completion hfg)
      ((f.continuous_completion hf).add (g.continuous_completion hg))
  · intro a
    

Proof state:
case h.refine_2
M : Type u_1
R : Type u_2
α : Type u_3
β : Type u_4
inst✝⁸ : UniformSpace α
inst✝⁷ : AddGroup α
inst✝⁶ : UniformAddGroup α
inst✝⁵ : UniformSpace β
inst✝⁴ : AddGroup β
inst✝³ : UniformAddGroup β
γ : Type u_5
inst✝² : AddCommGroup γ
inst✝¹ : UniformSpace γ
inst✝ : UniformAddGroup γ
f g : α →+ γ
hf : Continuous ⇑f
hg : Continuous ⇑g
hfg : Continuous fun x => f x + g x
x : Completion α
a : α
⊢ (completion (f + g) (_ : Continuous fun x => f x + g x)) (↑α a) = (completion f hf + completion g hg) (↑α a)

Next tactic:
simp [(f + g).completion_coe hfg, coe_add, f.completion_coe hf, g.completion_coe hg]
theorem inv_as_inv [Group α] {x y : SingleObj α} (f : x ⟶ y) : inv f = f⁻¹ := by
  

Proof state:
α : Type u
inst✝ : Group α
x y : SingleObj α
f : x ⟶ y
⊢ inv f = f⁻¹

Next tactic:
apply IsIso.inv_eq_of_hom_inv_id
theorem inv_as_inv [Group α] {x y : SingleObj α} (f : x ⟶ y) : inv f = f⁻¹ := by
  apply IsIso.inv_eq_of_hom_inv_id
  

Proof state:
case hom_inv_id
α : Type u
inst✝ : Group α
x y : SingleObj α
f : x ⟶ y
⊢ f ≫ f⁻¹ = 𝟙 x

Next tactic:
rw [comp_as_mul, inv_mul_self, id_as_one]
/-- There is a 1-1 correspondence between monoid homomorphisms `α → β` and functors between the
    corresponding single-object categories. It means that `SingleObj` is a fully faithful
    functor.

See <https://stacks.math.columbia.edu/tag/001F> --
although we do not characterize when the functor is full or faithful.
-/
def mapHom (α : Type u) (β : Type v) [Monoid α] [Monoid β] :
    (α →* β) ≃ SingleObj α ⥤ SingleObj β where
  toFun f :=
    { obj := id
      map := ⇑f
      map_id := fun _ => f.map_one
      map_comp := fun x y => f.map_mul y x }
  invFun f :=
    { toFun := fun x => f.map ((toEnd α) x)
      map_one' := f.map_id _
      map_mul' := fun x y => f.map_comp y x }
  left_inv := by 

Proof state:
α✝ α : Type u
β : Type v
inst✝¹ : Monoid α
inst✝ : Monoid β
⊢ Function.LeftInverse
    (fun f =>
      {
        toOneHom :=
          { toFun := fun x => f.map ((toEnd α) x), map_one' := (_ : f.map (𝟙 (star α)) = 𝟙 (f.obj (star α))) },
        map_mul' := (_ : ∀ (x y : α), f.map (y ≫ x) = f.map y ≫ f.map x) })
    fun f => Functor.mk { obj := id, map := fun {X Y} => ⇑f }

Next tactic:
aesop_cat
/-- There is a 1-1 correspondence between monoid homomorphisms `α → β` and functors between the
    corresponding single-object categories. It means that `SingleObj` is a fully faithful
    functor.

See <https://stacks.math.columbia.edu/tag/001F> --
although we do not characterize when the functor is full or faithful.
-/
def mapHom (α : Type u) (β : Type v) [Monoid α] [Monoid β] :
    (α →* β) ≃ SingleObj α ⥤ SingleObj β where
  toFun f :=
    { obj := id
      map := ⇑f
      map_id := fun _ => f.map_one
      map_comp := fun x y => f.map_mul y x }
  invFun f :=
    { toFun := fun x => f.map ((toEnd α) x)
      map_one' := f.map_id _
      map_mul' := fun x y => f.map_comp y x }
  left_inv := by aesop_cat
  right_inv := by 

Proof state:
α✝ α : Type u
β : Type v
inst✝¹ : Monoid α
inst✝ : Monoid β
⊢ Function.RightInverse
    (fun f =>
      {
        toOneHom :=
          { toFun := fun x => f.map ((toEnd α) x), map_one' := (_ : f.map (𝟙 (star α)) = 𝟙 (f.obj (star α))) },
        map_mul' := (_ : ∀ (x y : α), f.map (y ≫ x) = f.map y ≫ f.map x) })
    fun f => Functor.mk { obj := id, map := fun {X Y} => ⇑f }

Next tactic:
aesop_cat
/-- Given a function `f : C → G` from a category to a group, we get a functor
    `C ⥤ G` sending any morphism `x ⟶ y` to `f y * (f x)⁻¹`. -/
@[simps]
def differenceFunctor {C G} [Category C] [Group G] (f : C → G) : C ⥤ SingleObj G
    where
  obj _ := ()
  map {x y} _ := f y * (f x)⁻¹
  map_id := by
    

Proof state:
α : Type u
C : Type ?u.19810
G : Type ?u.19814
inst✝¹ : Category.{?u.19811, ?u.19810} C
inst✝ : Group G
f : C → G
⊢ ∀ (X : C),
    { obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.map (𝟙 X) =
      𝟙 ({ obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.obj X)

Next tactic:
intro
/-- Given a function `f : C → G` from a category to a group, we get a functor
    `C ⥤ G` sending any morphism `x ⟶ y` to `f y * (f x)⁻¹`. -/
@[simps]
def differenceFunctor {C G} [Category C] [Group G] (f : C → G) : C ⥤ SingleObj G
    where
  obj _ := ()
  map {x y} _ := f y * (f x)⁻¹
  map_id := by
    intro
    

Proof state:
α : Type u
C : Type ?u.19810
G : Type ?u.19814
inst✝¹ : Category.{?u.19811, ?u.19810} C
inst✝ : Group G
f : C → G
X✝ : C
⊢ { obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.map (𝟙 X✝) =
    𝟙 ({ obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.obj X✝)

Next tactic:
simp only [SingleObj.id_as_one, mul_right_inv]
/-- Given a function `f : C → G` from a category to a group, we get a functor
    `C ⥤ G` sending any morphism `x ⟶ y` to `f y * (f x)⁻¹`. -/
@[simps]
def differenceFunctor {C G} [Category C] [Group G] (f : C → G) : C ⥤ SingleObj G
    where
  obj _ := ()
  map {x y} _ := f y * (f x)⁻¹
  map_id := by
    intro
    simp only [SingleObj.id_as_one, mul_right_inv]
  map_comp := by
    

Proof state:
α : Type u
C : Type ?u.19810
G : Type ?u.19814
inst✝¹ : Category.{?u.19811, ?u.19810} C
inst✝ : Group G
f : C → G
⊢ ∀ {X Y Z : C} (f_1 : X ⟶ Y) (g : Y ⟶ Z),
    { obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.map (f_1 ≫ g) =
      { obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.map f_1 ≫
        { obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.map g

Next tactic:
intros
/-- Given a function `f : C → G` from a category to a group, we get a functor
    `C ⥤ G` sending any morphism `x ⟶ y` to `f y * (f x)⁻¹`. -/
@[simps]
def differenceFunctor {C G} [Category C] [Group G] (f : C → G) : C ⥤ SingleObj G
    where
  obj _ := ()
  map {x y} _ := f y * (f x)⁻¹
  map_id := by
    intro
    simp only [SingleObj.id_as_one, mul_right_inv]
  map_comp := by
    intros
    

Proof state:
α : Type u
C : Type ?u.19810
G : Type ?u.19814
inst✝¹ : Category.{?u.19811, ?u.19810} C
inst✝ : Group G
f : C → G
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
⊢ { obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.map (f✝ ≫ g✝) =
    { obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.map f✝ ≫
      { obj := fun x => (), map := fun {x y} x_1 => f y * (f x)⁻¹ }.map g✝

Next tactic:
dsimp
/-- Given a function `f : C → G` from a category to a group, we get a functor
    `C ⥤ G` sending any morphism `x ⟶ y` to `f y * (f x)⁻¹`. -/
@[simps]
def differenceFunctor {C G} [Category C] [Group G] (f : C → G) : C ⥤ SingleObj G
    where
  obj _ := ()
  map {x y} _ := f y * (f x)⁻¹
  map_id := by
    intro
    simp only [SingleObj.id_as_one, mul_right_inv]
  map_comp := by
    intros
    dsimp
    

Proof state:
α : Type u
C : Type ?u.19810
G : Type ?u.19814
inst✝¹ : Category.{?u.19811, ?u.19810} C
inst✝ : Group G
f : C → G
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
⊢ f Z✝ * (f X✝)⁻¹ = (f Y✝ * (f X✝)⁻¹) ≫ (f Z✝ * (f Y✝)⁻¹)

Next tactic:
rw [SingleObj.comp_as_mul, ← mul_assoc, mul_left_inj, mul_assoc, inv_mul_self, mul_one]
/-- The units in a monoid are (multiplicatively) equivalent to
the automorphisms of `star` when we think of the monoid as a single-object category. -/
def toAut : αˣ ≃* Aut (SingleObj.star α) :=
  MulEquiv.trans (Units.mapEquiv (by 

Proof state:
α : Type u
inst✝ : Monoid α
⊢ α ≃* End (SingleObj.star α)

Next tactic:
exact SingleObj.toEnd α
instance toCat_faithful : Faithful toCat where
  map_injective h := by 

Proof state:
X✝ Y✝ : MonCat
a₁✝ a₂✝ : X✝ ⟶ Y✝
h : toCat.map a₁✝ = toCat.map a₂✝
⊢ a₁✝ = a₂✝

Next tactic:
rwa [toCat, (SingleObj.mapHom _ _).apply_eq_iff_eq] at h
theorem congr (hf : AEStronglyMeasurable' m f μ) (hfg : f =ᵐ[μ] g) : AEStronglyMeasurable' m g μ :=
  by 

Proof state:
α : Type u_1
β : Type u_2
𝕜 : Type u_3
m m0 : MeasurableSpace α
μ : Measure α
inst✝ : TopologicalSpace β
f g : α → β
hf : AEStronglyMeasurable' m f μ
hfg : f =ᵐ[μ] g
⊢ AEStronglyMeasurable' m g μ

Next tactic:
obtain ⟨f', hf'_meas, hff'⟩ := hf
theorem congr (hf : AEStronglyMeasurable' m f μ) (hfg : f =ᵐ[μ] g) : AEStronglyMeasurable' m g μ :=
  by obtain ⟨f', hf'_meas, hff'⟩ := hf; 

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
𝕜 : Type u_3
m m0 : MeasurableSpace α
μ : Measure α
inst✝ : TopologicalSpace β
f g : α → β
hfg : f =ᵐ[μ] g
f' : α → β
hf'_meas : StronglyMeasurable f'
hff' : f =ᵐ[μ] f'
⊢ AEStronglyMeasurable' m g μ

Next tactic:
exact ⟨f', hf'_meas, hfg.symm.trans hff'⟩
set_option autoImplicit true in
theorem mono (hf : AEStronglyMeasurable' m f μ) (hm : m ≤ m') : AEStronglyMeasurable' m' f μ := by
  

Proof state:
α : Type u_1
β : Type u_2
𝕜 : Type u_3
m m0 : MeasurableSpace α
μ : Measure α
inst✝ : TopologicalSpace β
f g : α → β
m' : MeasurableSpace α
hf : AEStronglyMeasurable' m f μ
hm : m ≤ m'
⊢ AEStronglyMeasurable' m' f μ

Next tactic:
obtain ⟨f', hf'_meas, hff'⟩ := hf