l3lab/ntp-mathlib huggingface dataset:
set_option linter.deprecated false in
theorem nodup_permutations (s : List α) (hs : Nodup s) : Nodup s.permutations := by
  rw [(permutations_perm_permutations' s).nodup_iff]
  induction' hs with x l h h' IH
  · simp
  · rw [permutations']
    rw [nodup_bind]
    constructor
    · intro ys hy
      rw [mem_permutations'] at hy
      rw [nodup_permutations'Aux_iff, hy.mem_iff]
      exact fun H => h x H rfl
    · refine' IH.pairwise_of_forall_ne fun as ha bs hb H => _
      rw [disjoint_iff_ne]
      rintro a ha' b hb' rfl
      obtain ⟨⟨n, hn⟩, hn'⟩ := get_of_mem ha'
      obtain ⟨⟨m, hm⟩, hm'⟩ := get_of_mem hb'
      rw [mem_permutations'] at ha hb
      have hl : as.length = bs.length := (ha.trans hb.symm).length_eq
      simp only [Nat.lt_succ_iff, length_permutations'Aux] at hn hm
      rw [← nthLe, nthLe_permutations'Aux] at hn' hm'
      have hx :
        nthLe (insertNth n x as) m (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff, hl]) = x :=
        by simp [hn', ← hm', hm]
      have hx' :
        nthLe (insertNth m x bs) n (by rwa [length_insertNth _ _ hm, Nat.lt_succ_iff, ← hl]) =
          x :=
        by simp [hm', ← hn', hn]
      rcases lt_trichotomy n m with (ht | ht | ht)
      · suffices x ∈ bs by exact h x (hb.subset this) rfl
        rw [← hx', nthLe_insertNth_of_lt _ _ _ _ ht (ht.trans_le hm)]
        exact nthLe_mem _ _ _
      · simp only [ht] at hm' hn'
        rw [← hm'] at hn'
        exact H (insertNth_injective _ _ hn')
      · suffices x ∈ as by 

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
s : List α
x : α
l : List α
h : ∀ a' ∈ l, x ≠ a'
h' : Pairwise (fun x x_1 => x ≠ x_1) l
IH : Nodup (permutations' l)
as : List α
ha : as ~ l
bs : List α
hb : bs ~ l
H : as ≠ bs
a : List α
ha' : a ∈ permutations'Aux x as
hb' : a ∈ permutations'Aux x bs
n : ℕ
hn✝ : n < length (permutations'Aux x as)
hn' : insertNth n x as = a
m : ℕ
hm✝ : m < length (permutations'Aux x bs)
hm' : insertNth m x bs = a
hl : length as = length bs
hn : n ≤ length as
hm : m ≤ length bs
hx : nthLe (insertNth n x as) m (_ : m < length (insertNth n x as)) = x
hx' : nthLe (insertNth m x bs) n (_ : n < length (insertNth m x bs)) = x
ht : m < n
this : x ∈ as
⊢ False

Next tactic:
exact h x (ha.subset this) rfl
set_option linter.deprecated false in
theorem nodup_permutations (s : List α) (hs : Nodup s) : Nodup s.permutations := by
  rw [(permutations_perm_permutations' s).nodup_iff]
  induction' hs with x l h h' IH
  · simp
  · rw [permutations']
    rw [nodup_bind]
    constructor
    · intro ys hy
      rw [mem_permutations'] at hy
      rw [nodup_permutations'Aux_iff, hy.mem_iff]
      exact fun H => h x H rfl
    · refine' IH.pairwise_of_forall_ne fun as ha bs hb H => _
      rw [disjoint_iff_ne]
      rintro a ha' b hb' rfl
      obtain ⟨⟨n, hn⟩, hn'⟩ := get_of_mem ha'
      obtain ⟨⟨m, hm⟩, hm'⟩ := get_of_mem hb'
      rw [mem_permutations'] at ha hb
      have hl : as.length = bs.length := (ha.trans hb.symm).length_eq
      simp only [Nat.lt_succ_iff, length_permutations'Aux] at hn hm
      rw [← nthLe, nthLe_permutations'Aux] at hn' hm'
      have hx :
        nthLe (insertNth n x as) m (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff, hl]) = x :=
        by simp [hn', ← hm', hm]
      have hx' :
        nthLe (insertNth m x bs) n (by rwa [length_insertNth _ _ hm, Nat.lt_succ_iff, ← hl]) =
          x :=
        by simp [hm', ← hn', hn]
      rcases lt_trichotomy n m with (ht | ht | ht)
      · suffices x ∈ bs by exact h x (hb.subset this) rfl
        rw [← hx', nthLe_insertNth_of_lt _ _ _ _ ht (ht.trans_le hm)]
        exact nthLe_mem _ _ _
      · simp only [ht] at hm' hn'
        rw [← hm'] at hn'
        exact H (insertNth_injective _ _ hn')
      · suffices x ∈ as by exact h x (ha.subset this) rfl
        

Proof state:
case cons.right.intro.mk.intro.mk.inr.inr
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
s : List α
x : α
l : List α
h : ∀ a' ∈ l, x ≠ a'
h' : Pairwise (fun x x_1 => x ≠ x_1) l
IH : Nodup (permutations' l)
as : List α
ha : as ~ l
bs : List α
hb : bs ~ l
H : as ≠ bs
a : List α
ha' : a ∈ permutations'Aux x as
hb' : a ∈ permutations'Aux x bs
n : ℕ
hn✝ : n < length (permutations'Aux x as)
hn' : insertNth n x as = a
m : ℕ
hm✝ : m < length (permutations'Aux x bs)
hm' : insertNth m x bs = a
hl : length as = length bs
hn : n ≤ length as
hm : m ≤ length bs
hx : nthLe (insertNth n x as) m (_ : m < length (insertNth n x as)) = x
hx' : nthLe (insertNth m x bs) n (_ : n < length (insertNth m x bs)) = x
ht : m < n
⊢ x ∈ as

Next tactic:
rw [← hx, nthLe_insertNth_of_lt _ _ _ _ ht (ht.trans_le hn)]
set_option linter.deprecated false in
theorem nodup_permutations (s : List α) (hs : Nodup s) : Nodup s.permutations := by
  rw [(permutations_perm_permutations' s).nodup_iff]
  induction' hs with x l h h' IH
  · simp
  · rw [permutations']
    rw [nodup_bind]
    constructor
    · intro ys hy
      rw [mem_permutations'] at hy
      rw [nodup_permutations'Aux_iff, hy.mem_iff]
      exact fun H => h x H rfl
    · refine' IH.pairwise_of_forall_ne fun as ha bs hb H => _
      rw [disjoint_iff_ne]
      rintro a ha' b hb' rfl
      obtain ⟨⟨n, hn⟩, hn'⟩ := get_of_mem ha'
      obtain ⟨⟨m, hm⟩, hm'⟩ := get_of_mem hb'
      rw [mem_permutations'] at ha hb
      have hl : as.length = bs.length := (ha.trans hb.symm).length_eq
      simp only [Nat.lt_succ_iff, length_permutations'Aux] at hn hm
      rw [← nthLe, nthLe_permutations'Aux] at hn' hm'
      have hx :
        nthLe (insertNth n x as) m (by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff, hl]) = x :=
        by simp [hn', ← hm', hm]
      have hx' :
        nthLe (insertNth m x bs) n (by rwa [length_insertNth _ _ hm, Nat.lt_succ_iff, ← hl]) =
          x :=
        by simp [hm', ← hn', hn]
      rcases lt_trichotomy n m with (ht | ht | ht)
      · suffices x ∈ bs by exact h x (hb.subset this) rfl
        rw [← hx', nthLe_insertNth_of_lt _ _ _ _ ht (ht.trans_le hm)]
        exact nthLe_mem _ _ _
      · simp only [ht] at hm' hn'
        rw [← hm'] at hn'
        exact H (insertNth_injective _ _ hn')
      · suffices x ∈ as by exact h x (ha.subset this) rfl
        rw [← hx, nthLe_insertNth_of_lt _ _ _ _ ht (ht.trans_le hn)]
        

Proof state:
case cons.right.intro.mk.intro.mk.inr.inr
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a✝ : α
s : List α
x : α
l : List α
h : ∀ a' ∈ l, x ≠ a'
h' : Pairwise (fun x x_1 => x ≠ x_1) l
IH : Nodup (permutations' l)
as : List α
ha : as ~ l
bs : List α
hb : bs ~ l
H : as ≠ bs
a : List α
ha' : a ∈ permutations'Aux x as
hb' : a ∈ permutations'Aux x bs
n : ℕ
hn✝ : n < length (permutations'Aux x as)
hn' : insertNth n x as = a
m : ℕ
hm✝ : m < length (permutations'Aux x bs)
hm' : insertNth m x bs = a
hl : length as = length bs
hn : n ≤ length as
hm : m ≤ length bs
hx : nthLe (insertNth n x as) m (_ : m < length (insertNth n x as)) = x
hx' : nthLe (insertNth m x bs) n (_ : n < length (insertNth m x bs)) = x
ht : m < n
⊢ nthLe as m (_ : m < length as) ∈ as

Next tactic:
exact nthLe_mem _ _ _
instance : IsReflexivePair (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X) := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
⊢ IsReflexivePair (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)

Next tactic:
apply IsReflexivePair.mk' _ _ _
instance : IsReflexivePair (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X) := by
  apply IsReflexivePair.mk' _ _ _
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
⊢ (free T).obj X.A ⟶ (free T).obj (T.obj X.A)
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
⊢ ?m.2493 ≫ FreeCoequalizer.topMap X = 𝟙 ((free T).obj X.A)
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
⊢ ?m.2493 ≫ FreeCoequalizer.bottomMap X = 𝟙 ((free T).obj X.A)

Next tactic:
apply (free T).map (T.η.app X.A)
instance : IsReflexivePair (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X) := by
  apply IsReflexivePair.mk' _ _ _
  apply (free T).map (T.η.app X.A)
  · 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
⊢ (free T).map ((η T).app X.A) ≫ FreeCoequalizer.topMap X = 𝟙 ((free T).obj X.A)

Next tactic:
ext
instance : IsReflexivePair (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X) := by
  apply IsReflexivePair.mk' _ _ _
  apply (free T).map (T.η.app X.A)
  · ext
    

Proof state:
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
⊢ ((free T).map ((η T).app X.A) ≫ FreeCoequalizer.topMap X).f = (𝟙 ((free T).obj X.A)).f

Next tactic:
dsimp
instance : IsReflexivePair (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X) := by
  apply IsReflexivePair.mk' _ _ _
  apply (free T).map (T.η.app X.A)
  · ext
    dsimp
    

Proof state:
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
⊢ T.map ((η T).app X.A) ≫ T.map X.a = 𝟙 (T.obj X.A)

Next tactic:
rw [← Functor.map_comp, X.unit, Functor.map_id]
instance : IsReflexivePair (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X) := by
  apply IsReflexivePair.mk' _ _ _
  apply (free T).map (T.η.app X.A)
  · ext
    dsimp
    rw [← Functor.map_comp, X.unit, Functor.map_id]
  · 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
⊢ (free T).map ((η T).app X.A) ≫ FreeCoequalizer.bottomMap X = 𝟙 ((free T).obj X.A)

Next tactic:
ext
instance : IsReflexivePair (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X) := by
  apply IsReflexivePair.mk' _ _ _
  apply (free T).map (T.η.app X.A)
  · ext
    dsimp
    rw [← Functor.map_comp, X.unit, Functor.map_id]
  · ext
    

Proof state:
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
⊢ ((free T).map ((η T).app X.A) ≫ FreeCoequalizer.bottomMap X).f = (𝟙 ((free T).obj X.A)).f

Next tactic:
apply Monad.right_unit
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
⊢ { l //
    Cofork.π (beckAlgebraCofork X) ≫ l = Cofork.π s ∧
      ∀
        {m :
          ((Functor.const WalkingParallelPair).obj (beckAlgebraCofork X).pt).obj WalkingParallelPair.one ⟶
            ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.one},
        Cofork.π (beckAlgebraCofork X) ≫ m = Cofork.π s → m = l }

Next tactic:
have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
⊢ { l //
    Cofork.π (beckAlgebraCofork X) ≫ l = Cofork.π s ∧
      ∀
        {m :
          ((Functor.const WalkingParallelPair).obj (beckAlgebraCofork X).pt).obj WalkingParallelPair.one ⟶
            ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.one},
        Cofork.π (beckAlgebraCofork X) ≫ m = Cofork.π s → m = l }

Next tactic:
have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
⊢ { l //
    Cofork.π (beckAlgebraCofork X) ≫ l = Cofork.π s ∧
      ∀
        {m :
          ((Functor.const WalkingParallelPair).obj (beckAlgebraCofork X).pt).obj WalkingParallelPair.one ⟶
            ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.one},
        Cofork.π (beckAlgebraCofork X) ≫ m = Cofork.π s → m = l }

Next tactic:
refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
    · 

Proof state:
case refine'_1
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
⊢ T.map ((η T).app (beckAlgebraCofork X).pt.1 ≫ (Cofork.π s).f) ≫ s.pt.a =
    (beckAlgebraCofork X).pt.a ≫ (η T).app (beckAlgebraCofork X).pt.1 ≫ (Cofork.π s).f

Next tactic:
dsimp
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
    · dsimp
      

Proof state:
case refine'_1
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
⊢ T.map ((η T).app X.1 ≫ (Cofork.π s).f) ≫ s.pt.a = X.a ≫ (η T).app X.1 ≫ (Cofork.π s).f

Next tactic:
rw [Functor.map_comp, Category.assoc, h₂, Monad.right_unit_assoc,
        show X.a ≫ _ ≫ _ = _ from T.η.naturality_assoc _ _, h₁, Monad.left_unit_assoc]
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
    · dsimp
      rw [Functor.map_comp, Category.assoc, h₂, Monad.right_unit_assoc,
        show X.a ≫ _ ≫ _ = _ from T.η.naturality_assoc _ _, h₁, Monad.left_unit_assoc]
    · 

Proof state:
case refine'_2
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
⊢ Cofork.π (beckAlgebraCofork X) ≫ Algebra.Hom.mk ((η T).app (beckAlgebraCofork X).pt.1 ≫ (Cofork.π s).f) = Cofork.π s

Next tactic:
ext
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
    · dsimp
      rw [Functor.map_comp, Category.assoc, h₂, Monad.right_unit_assoc,
        show X.a ≫ _ ≫ _ = _ from T.η.naturality_assoc _ _, h₁, Monad.left_unit_assoc]
    · ext
      

Proof state:
case refine'_2.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
⊢ (Cofork.π (beckAlgebraCofork X) ≫ Algebra.Hom.mk ((η T).app (beckAlgebraCofork X).pt.1 ≫ (Cofork.π s).f)).f =
    (Cofork.π s).f

Next tactic:
simpa [← T.η.naturality_assoc, T.left_unit_assoc] using T.η.app ((T : C ⥤ C).obj X.A) ≫= h₁
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
    · dsimp
      rw [Functor.map_comp, Category.assoc, h₂, Monad.right_unit_assoc,
        show X.a ≫ _ ≫ _ = _ from T.η.naturality_assoc _ _, h₁, Monad.left_unit_assoc]
    · ext
      simpa [← T.η.naturality_assoc, T.left_unit_assoc] using T.η.app ((T : C ⥤ C).obj X.A) ≫= h₁
    · 

Proof state:
case refine'_3
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
⊢ ∀
    {m :
      ((Functor.const WalkingParallelPair).obj (beckAlgebraCofork X).pt).obj WalkingParallelPair.one ⟶
        ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.one},
    Cofork.π (beckAlgebraCofork X) ≫ m = Cofork.π s →
      m = Algebra.Hom.mk ((η T).app (beckAlgebraCofork X).pt.1 ≫ (Cofork.π s).f)

Next tactic:
intro m hm
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
    · dsimp
      rw [Functor.map_comp, Category.assoc, h₂, Monad.right_unit_assoc,
        show X.a ≫ _ ≫ _ = _ from T.η.naturality_assoc _ _, h₁, Monad.left_unit_assoc]
    · ext
      simpa [← T.η.naturality_assoc, T.left_unit_assoc] using T.η.app ((T : C ⥤ C).obj X.A) ≫= h₁
    · intro m hm
      

Proof state:
case refine'_3
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
m :
  ((Functor.const WalkingParallelPair).obj (beckAlgebraCofork X).pt).obj WalkingParallelPair.one ⟶
    ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.one
hm : Cofork.π (beckAlgebraCofork X) ≫ m = Cofork.π s
⊢ m = Algebra.Hom.mk ((η T).app (beckAlgebraCofork X).pt.1 ≫ (Cofork.π s).f)

Next tactic:
ext
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
    · dsimp
      rw [Functor.map_comp, Category.assoc, h₂, Monad.right_unit_assoc,
        show X.a ≫ _ ≫ _ = _ from T.η.naturality_assoc _ _, h₁, Monad.left_unit_assoc]
    · ext
      simpa [← T.η.naturality_assoc, T.left_unit_assoc] using T.η.app ((T : C ⥤ C).obj X.A) ≫= h₁
    · intro m hm
      ext
      

Proof state:
case refine'_3.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
m :
  ((Functor.const WalkingParallelPair).obj (beckAlgebraCofork X).pt).obj WalkingParallelPair.one ⟶
    ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.one
hm : Cofork.π (beckAlgebraCofork X) ≫ m = Cofork.π s
⊢ m.f = (Algebra.Hom.mk ((η T).app (beckAlgebraCofork X).pt.1 ≫ (Cofork.π s).f)).f

Next tactic:
dsimp only
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
    · dsimp
      rw [Functor.map_comp, Category.assoc, h₂, Monad.right_unit_assoc,
        show X.a ≫ _ ≫ _ = _ from T.η.naturality_assoc _ _, h₁, Monad.left_unit_assoc]
    · ext
      simpa [← T.η.naturality_assoc, T.left_unit_assoc] using T.η.app ((T : C ⥤ C).obj X.A) ≫= h₁
    · intro m hm
      ext
      dsimp only
      

Proof state:
case refine'_3.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
m :
  ((Functor.const WalkingParallelPair).obj (beckAlgebraCofork X).pt).obj WalkingParallelPair.one ⟶
    ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.one
hm : Cofork.π (beckAlgebraCofork X) ≫ m = Cofork.π s
⊢ m.f = (η T).app (beckAlgebraCofork X).pt.1 ≫ (Cofork.π s).f

Next tactic:
rw [← hm]
/-- The cofork constructed is a colimit. This shows that any algebra is a (reflexive) coequalizer of
free algebras.
-/
def beckAlgebraCoequalizer : IsColimit (beckAlgebraCofork X) :=
  Cofork.IsColimit.mk' _ fun s => by
    have h₁ : (T : C ⥤ C).map X.a ≫ s.π.f = T.μ.app X.A ≫ s.π.f :=
      congr_arg Monad.Algebra.Hom.f s.condition
    have h₂ : (T : C ⥤ C).map s.π.f ≫ s.pt.a = T.μ.app X.A ≫ s.π.f := s.π.h
    refine' ⟨⟨T.η.app _ ≫ s.π.f, _⟩, _, _⟩
    · dsimp
      rw [Functor.map_comp, Category.assoc, h₂, Monad.right_unit_assoc,
        show X.a ≫ _ ≫ _ = _ from T.η.naturality_assoc _ _, h₁, Monad.left_unit_assoc]
    · ext
      simpa [← T.η.naturality_assoc, T.left_unit_assoc] using T.η.app ((T : C ⥤ C).obj X.A) ≫= h₁
    · intro m hm
      ext
      dsimp only
      rw [← hm]
      

Proof state:
case refine'_3.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
T : Monad C
X : Algebra T
s : Cofork (FreeCoequalizer.topMap X) (FreeCoequalizer.bottomMap X)
h₁ : T.map X.a ≫ (Cofork.π s).f = (μ T).app X.A ≫ (Cofork.π s).f
h₂ : T.map (Cofork.π s).f ≫ s.pt.a = (μ T).app X.A ≫ (Cofork.π s).f
m :
  ((Functor.const WalkingParallelPair).obj (beckAlgebraCofork X).pt).obj WalkingParallelPair.one ⟶
    ((Functor.const WalkingParallelPair).obj s.pt).obj WalkingParallelPair.one
hm : Cofork.π (beckAlgebraCofork X) ≫ m = Cofork.π s
⊢ m.f = (η T).app (beckAlgebraCofork X).pt.1 ≫ (Cofork.π (beckAlgebraCofork X) ≫ m).f

Next tactic:
apply (X.unit_assoc _).symm
@[ext]
lemma hom_ext {X Y : FintypeCat} (f g : X ⟶ Y) (h : ∀ x, f x = g x) : f = g := by
  

Proof state:
X Y : FintypeCat
f g : X ⟶ Y
h : ∀ (x : ↑X), f x = g x
⊢ f = g

Next tactic:
funext
@[ext]
lemma hom_ext {X Y : FintypeCat} (f g : X ⟶ Y) (h : ∀ x, f x = g x) : f = g := by
  funext
  

Proof state:
case h
X Y : FintypeCat
f g : X ⟶ Y
h : ∀ (x : ↑X), f x = g x
x✝ : ↑X
⊢ f x✝ = g x✝

Next tactic:
apply h