Theorem: CategoryTheory.Limits.colimitCoconeOfUnique_isColimit_desc
File: Mathlib/CategoryTheory/Limits/Shapes/Products.lean

Proof steps:
state_before: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ (Discrete.functor f).obj { as := j } = ((Functor.const (Discrete β)).obj (f default)).obj { as := j }
state_after: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ f j = f default
tactic: dsimp
state_before: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ f j = f default
state_after: case e_a
β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ j = default
tactic: congr
state_before: case e_a
β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
x✝ : Discrete β
j : β
⊢ j = default
state_after: no goals
tactic: subsingleton
state_before: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
j : Discrete β
⊢ { pt := f default,
              ι :=
                Discrete.natTrans fun x =>
                  match x with
                  | { as := j } => eqToHom ⋯ }.ι.app
        j ≫
      (fun s => s.ι.app default) s =
    s.ι.app j
state_after: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
j : Discrete β
h : j = default
⊢ { pt := f default,
              ι :=
                Discrete.natTrans fun x =>
                  match x with
                  | { as := j } => eqToHom ⋯ }.ι.app
        j ≫
      (fun s => s.ι.app default) s =
    s.ι.app j
tactic: have h := Subsingleton.elim j default
state_before: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
j : Discrete β
h : j = default
⊢ { pt := f default,
              ι :=
                Discrete.natTrans fun x =>
                  match x with
                  | { as := j } => eqToHom ⋯ }.ι.app
        j ≫
      (fun s => s.ι.app default) s =
    s.ι.app j
state_after: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
⊢ { pt := f default,
              ι :=
                Discrete.natTrans fun x =>
                  match x with
                  | { as := j } => eqToHom ⋯ }.ι.app
        default ≫
      (fun s => s.ι.app default) s =
    s.ι.app default
tactic: subst h
state_before: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
⊢ { pt := f default,
              ι :=
                Discrete.natTrans fun x =>
                  match x with
                  | { as := j } => eqToHom ⋯ }.ι.app
        default ≫
      (fun s => s.ι.app default) s =
    s.ι.app default
state_after: no goals
tactic: apply Category.id_comp
state_before: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
m :
  { pt := f default,
        ι :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } => eqToHom ⋯ }.pt ⟶
    s.pt
w :
  ∀ (j : Discrete β),
    { pt := f default,
                ι :=
                  Discrete.natTrans fun x =>
                    match x with
                    | { as := j } => eqToHom ⋯ }.ι.app
          j ≫
        m =
      s.ι.app j
⊢ m = (fun s => s.ι.app default) s
state_after: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
m :
  { pt := f default,
        ι :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } => eqToHom ⋯ }.pt ⟶
    s.pt
w :
  { pt := f default,
              ι :=
                Discrete.natTrans fun x =>
                  match x with
                  | { as := j } => eqToHom ⋯ }.ι.app
        default ≫
      m =
    s.ι.app default
⊢ m = (fun s => s.ι.app default) s
tactic: specialize w default
state_before: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
m :
  { pt := f default,
        ι :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } => eqToHom ⋯ }.pt ⟶
    s.pt
w :
  { pt := f default,
              ι :=
                Discrete.natTrans fun x =>
                  match x with
                  | { as := j } => eqToHom ⋯ }.ι.app
        default ≫
      m =
    s.ι.app default
⊢ m = (fun s => s.ι.app default) s
state_after: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
m :
  { pt := f default,
        ι :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } => eqToHom ⋯ }.pt ⟶
    s.pt
w : m = s.ι.app default
⊢ m = (fun s => s.ι.app default) s
tactic: erw [Category.id_comp] at w
state_before: β : Type w
α : Type w₂
γ : Type w₃
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Unique β
f : β → C
s : Cocone (Discrete.functor f)
m :
  { pt := f default,
        ι :=
          Discrete.natTrans fun x =>
            match x with
            | { as := j } => eqToHom ⋯ }.pt ⟶
    s.pt
w : m = s.ι.app default
⊢ m = (fun s => s.ι.app default) s
state_after: no goals
tactic: exact w