Theory CZH_UCAT_Representable

(* Copyright 2021 (C) Mihails Milehins *)

section‹Representable and corepresentable functors›
theory CZH_UCAT_Representable
  imports
    CZH_Elementary_Categories.CZH_ECAT_Yoneda
    CZH_UCAT_Pointed
    CZH_UCAT_Limit
begin



subsection‹Representable and corepresentable functors›


subsubsection‹Definitions and elementary properties›


text‹
See Chapter III-2 in cite"mac_lane_categories_2010" 
or Section 2.1 in cite"riehl_category_2016".
›

definition cat_representation :: "V  V  V  V  bool"
  where "cat_representation α 𝔉 c ψ 
    c  𝔉HomDomObj 
    ψ : HomO.Cα𝔉HomDom(c,-) CF.iso 𝔉 : 𝔉HomDom ↦↦Cαcat_Set α"

definition cat_corepresentation :: "V  V  V  V  bool"
  where "cat_corepresentation α 𝔉 c ψ 
    c  𝔉HomDomObj 
    ψ : HomO.Cαop_cat (𝔉HomDom)(-,c) CF.iso 𝔉 : 𝔉HomDom ↦↦Cαcat_Set α"


text‹Rules.›

context
  fixes α  𝔉
  assumes 𝔉: "𝔉 :  ↦↦Cαcat_Set α"
begin

interpretation 𝔉: is_functor α  cat_Set α 𝔉 by (rule 𝔉)

mk_ide rf cat_representation_def[where α=α and 𝔉=𝔉, unfolded cat_cs_simps]
  |intro cat_representationI|
  |dest cat_representationD'|
  |elim cat_representationE'|

end

lemmas cat_representationD[dest] = cat_representationD'[rotated]
  and  cat_representationE[elim] = cat_representationE'[rotated]

lemma cat_corepresentationI:
  assumes "category α "
    and "𝔉 : op_cat  ↦↦Cαcat_Set α"
    and "c  Obj"
    and "ψ : HomO.Cα(-,c) CF.iso 𝔉 : op_cat  ↦↦Cαcat_Set α"
  shows "cat_corepresentation α 𝔉 c ψ"
proof-
  interpret category α  by (rule assms(1)) 
  interpret 𝔉: is_functor α op_cat  cat_Set α 𝔉 by (rule assms(2))
  note [cat_op_simps] = 𝔉.HomDom.cat_op_cat_cf_Hom_snd[
      symmetric, unfolded cat_op_simps, OF assms(3)
      ]
  show ?thesis
    unfolding cat_corepresentation_def
    by (intro conjI, unfold cat_cs_simps cat_op_simps; intro assms)
qed

lemma cat_corepresentationD:
  assumes "cat_corepresentation α 𝔉 c ψ"
    and "category α "
    and "𝔉 : op_cat  ↦↦Cαcat_Set α"
  shows "c  Obj"
    and "ψ : HomO.Cα(-,c) CF.iso 𝔉 : op_cat  ↦↦Cαcat_Set α"
proof-
  interpret category α  by (rule assms(2)) 
  interpret 𝔉: is_functor α op_cat  cat_Set α 𝔉 by (rule assms(3))
  note  = cat_corepresentation_def[
      THEN iffD1, OF assms(1), unfolded cat_cs_simps cat_op_simps
      ]
  from (1) show c: "c  Obj" by auto
  note [cat_op_simps] = 𝔉.HomDom.cat_op_cat_cf_Hom_snd[
      symmetric, unfolded cat_op_simps, OF c
      ]
  show "ψ : HomO.Cα(-,c) CF.iso 𝔉 : op_cat  ↦↦Cαcat_Set α"
    by (rule conjunct2[OF , unfolded cat_op_simps])
qed

lemma cat_corepresentationE:
  assumes "cat_corepresentation α 𝔉 c ψ"
    and "category α "
    and "𝔉 : op_cat  ↦↦Cαcat_Set α"
  obtains "c  Obj"
    and "ψ : HomO.Cα(-,c) CF.iso 𝔉 : op_cat  ↦↦Cαcat_Set α"
  by (simp add: cat_corepresentationD[OF assms])


subsubsection‹Representable functors and universal arrows›

lemma universal_arrow_of_if_cat_representation:
  ―‹See Proposition 2 in Chapter III-2 in \cite{mac_lane_categories_2010}.›
  assumes "𝔎 :  ↦↦Cαcat_Set α"
    and "cat_representation α 𝔎 r ψ"
    and "𝔞  cat_Set αObj"
  shows "universal_arrow_of
    𝔎 (set {𝔞}) r (ntcf_paa 𝔞 (𝔎ObjMapr) (ψNTMaprArrValCIdr))"
proof-
  note  = cat_representationD[OF assms(2,1)]
  interpret 𝔎: is_functor α  cat_Set α 𝔎 by (rule assms(1))
  interpret ψ: is_iso_ntcf α  cat_Set α HomO.Cα(r,-) 𝔎 ψ 
    by (rule (2))
  from assms(3) have set_𝔞: "set {𝔞}  cat_Set αObj"
    by (simp add: Limit_vsingleton_in_VsetI cat_Set_components(1))
  from
    ntcf_cf_comp_is_iso_ntcf[
      OF 𝔎.ntcf_pointed_inv_is_iso_ntcf[OF assms(3)] assms(1)
      ]
  have 𝔞𝔎: "ntcf_pointed_inv α 𝔞 NTCF-CF 𝔎 :
    𝔎 CF.iso HomO.Cαcat_Set α (set {𝔞},-) CF 𝔎 :  ↦↦Cαcat_Set α"
    by (cs_prems cs_simp: cat_cs_simps)
  from iso_ntcf_is_iso_arr(1)[OF 𝔞𝔎]  assms(3) have [cat_cs_simps]:
    "((ntcf_pointed_inv α 𝔞 NTCF-CF 𝔎 NTCF ψ)NTMaprArrValCIdr) =
      ntcf_paa 𝔞 (𝔎ObjMapr) (ψNTMaprArrValCIdr)"
    by
      (
        cs_concl
          cs_simp: cat_cs_simps
          cs_intro: cat_Set_cs_intros cat_cs_intros cat_op_intros
      )
  show "universal_arrow_of
    𝔎 (set {𝔞}) r (ntcf_paa 𝔞 (𝔎ObjMapr) (ψNTMaprArrValCIdr))"
    by
      (
        rule 𝔎.cf_universal_arrow_of_if_is_iso_ntcf
          [
            OF (1) set_𝔞 ntcf_vcomp_is_iso_ntcf[OF 𝔞𝔎 (2)], 
            unfolded cat_cs_simps
          ]
      )
qed

lemma universal_arrow_of_if_cat_corepresentation:
  ―‹See Proposition 2 in Chapter III-2 in \cite{mac_lane_categories_2010}.›
  assumes "category α "
    and "𝔎 : op_cat  ↦↦Cαcat_Set α"
    and "cat_corepresentation α 𝔎 r ψ"
    and "𝔞  cat_Set αObj"
  shows "universal_arrow_of
    𝔎 (set {𝔞}) r (ntcf_paa 𝔞 (𝔎ObjMapr) (ψNTMaprArrValCIdr))"
proof-
  interpret: category α  by (rule assms(1))
  note  = cat_corepresentationD[OF assms(3,1,2)]
  note [cat_op_simps] = ℭ.cat_op_cat_cf_Hom_snd[OF (1)]
  have rep: "cat_representation α 𝔎 r ψ"
    by (intro cat_representationI, rule assms(2), unfold cat_op_simps; rule )
  show ?thesis
    by 
      (
        rule universal_arrow_of_if_cat_representation[
          OF assms(2) rep assms(4), unfolded cat_op_simps
          ]
      )
qed

lemma cat_representation_if_universal_arrow_of:
  ―‹See Proposition 2 in Chapter III-2 in \cite{mac_lane_categories_2010}.›
  assumes "𝔎 :  ↦↦Cαcat_Set α"
    and "𝔞  cat_Set αObj"
    and "universal_arrow_of 𝔎 (set {𝔞}) r u"
  shows "cat_representation α 𝔎 r (Yoneda_arrow α 𝔎 r (uArrVal𝔞))"
proof-

  let ?Y = Yoneda_component 𝔎 r (uArrVal𝔞)

  interpret 𝔎: is_functor α  cat_Set α 𝔎 by (rule assms(1))

  note ua = 𝔎.universal_arrow_ofD[OF assms(3)]

  from ua(2) have u𝔞: "uArrVal𝔞  𝔎ObjMapr"
    by 
      (
        cs_concl cs_shallow 
          cs_intro: V_cs_intros cat_Set_cs_intros cat_cs_intros
      )

  have [cat_cs_simps]: "Yoneda_arrow α 𝔎 r (uArrVal𝔞)NTMapc = ?Y c"
    if "c  Obj" for c
    using that 
    by (cs_concl cs_shallow cs_simp: cat_cs_simps cs_intro: cat_cs_intros)
  from ua(1) have [cat_cs_simps]: "HomO.Cα(r,-)ObjMapc = Hom  r c"
    if "c  Obj" for c
    using that 
    by (cs_concl cs_shallow cs_simp: cat_cs_simps cs_intro: cat_op_intros)

  show ?thesis
  proof
    (
      intro cat_representationI is_iso_ntcfI, 
      rule assms(1), 
      rule ua(1), 
      rule 𝔎.HomDom.cat_Yoneda_arrow_is_ntcf[OF assms(1) ua(1) u𝔞],
      rule cat_Set_is_iso_arrI,
      simp_all only: cat_cs_simps 
    )

    fix c assume prems: "c  Obj"
    with ua(1,2) show Yc: "?Y c : Hom  r c cat_Set α𝔎ObjMapc"
      by 
        (
          cs_concl cs_shallow 
            cs_intro: V_cs_intros cat_Set_cs_intros cat_cs_intros
        )

    note YcD = cat_Set_is_arrD[OF Yc]

    interpret Yc: arr_Set α ?Y c by (rule YcD(1))

    show dom_Yc: "𝒟 (?Y cArrVal) = Hom  r c"
      by (simp add: 𝔎.Yoneda_component_ArrVal_vdomain)

    show "v11 (?Y cArrVal)"
    proof(intro Yc.ArrVal.vsv_valeq_v11I, unfold dom_Yc in_Hom_iff)

      fix g f assume prems': 
        "g : r c" "f : r c" "?Y cArrValg = ?Y cArrValf"

      from prems have c: "c  Obj" by auto

      from prems'(3,1,2) have 𝔎gu𝔞_𝔎fu𝔞:
        "𝔎ArrMapgArrValuArrVal𝔞 = 𝔎ArrMapfArrValuArrVal𝔞"
        by (cs_prems cs_shallow cs_simp: cat_cs_simps cs_intro: cat_cs_intros)

      from prems'(1,2) ua(1,2) have 𝔎g_u: 
        "𝔎ArrMapg Acat_Set αu : set {𝔞} cat_Set α𝔎ObjMapc"
        and 𝔎f_u: 
        "𝔎ArrMapf Acat_Set αu : set {𝔞} cat_Set α𝔎ObjMapc"
        by (cs_concl cs_shallow cs_simp: cat_cs_simps cs_intro: cat_cs_intros)+
      then have dom_lhs: "𝒟 ((𝔎ArrMapg Acat_Set αu)ArrVal) = set {𝔞}"
        and dom_rhs: "𝒟 ((𝔎ArrMapf Acat_Set αu)ArrVal) = set {𝔞}"
        by (cs_concl cs_shallow cs_simp: cat_cs_simps)+

      have 𝔎g_𝔎f: "𝔎ArrMapg Acat_Set αu = 𝔎ArrMapf Acat_Set αu"
      proof(rule arr_Set_eqI)
        from 𝔎g_u show arr_Set_𝔎g_u: "arr_Set α (𝔎ArrMapg Acat_Set αu)"
          by (auto dest: cat_Set_is_arrD)
        from 𝔎f_u show arr_Set_𝔎f_u: "arr_Set α (𝔎ArrMapf Acat_Set αu)"
          by (auto dest: cat_Set_is_arrD)
        show 
          "(𝔎ArrMapg Acat_Set αu)ArrVal =
            (𝔎ArrMapf Acat_Set αu)ArrVal"
        proof(rule vsv_eqI, unfold dom_lhs dom_rhs vsingleton_iff; (simp only:)?)
          from prems'(1,2) ua(2) show 
            "(𝔎ArrMapg Acat_Set αu)ArrVal𝔞 =
              (𝔎ArrMapf Acat_Set αu)ArrVal𝔞"
            by
              (
                cs_concl cs_shallow
                  cs_simp: cat_cs_simps 𝔎gu𝔞_𝔎fu𝔞 
                  cs_intro: V_cs_intros cat_cs_intros
              )
        qed (use arr_Set_𝔎g_u arr_Set_𝔎f_u in auto)
      qed (use 𝔎g_u 𝔎f_u in cs_concl cs_shallow cs_simp: cat_cs_simps)+
      from prems'(1) ua(2) have
        "𝔎ArrMapg Acat_Set αu : set {𝔞} cat_Set α𝔎ObjMapc"
        by (cs_concl cs_shallow cs_simp: cat_cs_simps cs_intro: cat_cs_intros)
      from ua(3)[OF c this] obtain h where h: "h : r c"
        and 𝔎g_u_def: 
          "𝔎ArrMapg Acat_Set αu = umap_of 𝔎 (set {𝔞}) r u cArrValh"
        and h_unique: "h'.
          
            h' : r c;
            𝔎ArrMapg Acat_Set αu = umap_of 𝔎 (set {𝔞}) r u cArrValh'
            h' = h"
        by metis
      from prems'(1,2) ua(2) have
        "𝔎ArrMapg Acat_Set αu = umap_of 𝔎 (set {𝔞}) r u cArrValg"
        "𝔎ArrMapg Acat_Set αu = umap_of 𝔎 (set {𝔞}) r u cArrValf"
        by 
          (
            cs_concl cs_shallow 
              cs_simp: cat_cs_simps 𝔎g_𝔎f cs_intro: cat_cs_intros
          )+
      from h_unique[OF prems'(1) this(1)] h_unique[OF prems'(2) this(2)] show 
        "g = f"
        by simp
    qed

    show " (?Y cArrVal) = 𝔎ObjMapc"
    proof
      (
        intro 
          vsubset_antisym Yc.arr_Par_ArrVal_vrange[unfolded YcD] 
          vsubsetI
      ) 
      fix y assume prems': "y  𝔎ObjMapc"
      from prems have 𝔎c: "𝔎ObjMapc  cat_Set αObj"
        by (cs_concl cs_shallow cs_intro: cat_cs_intros)
      from ua(3)[OF prems 𝔎.ntcf_paa_is_arr[OF assms(2) 𝔎c prems']] obtain f 
        where f: "f : r c"
          and ntcf_paa_y:
            "ntcf_paa 𝔞 (𝔎ObjMapc) y = umap_of 𝔎 (set {𝔞}) r u cArrValf"
          and f_unique: "f'.
            
              f' : r c;
              ntcf_paa 𝔞 (𝔎ObjMapc) y = umap_of 𝔎 (set {𝔞}) r u cArrValf'
              f' = f"
        by metis
      from ntcf_paa_y f ua(2) have 
        "ntcf_paa 𝔞 (𝔎ObjMapc) y = 𝔎ArrMapf Acat_Set αu"
        by (cs_prems cs_shallow cs_simp: cat_cs_simps cs_intro: cat_cs_intros)
      then have 
        "ntcf_paa 𝔞 (𝔎ObjMapc) yArrVal𝔞 =
          (𝔎ArrMapf Acat_Set αu)ArrVal𝔞"
        by simp
      from this f ua(2) have [symmetric, cat_cs_simps]: 
        "y = 𝔎ArrMapfArrValuArrVal𝔞"
        by 
          (
            cs_prems cs_shallow
              cs_simp: cat_cs_simps cs_intro: V_cs_intros cat_cs_intros
          )
      show "y   (?Y cArrVal)"
        by (intro Yc.ArrVal.vsv_vimageI2')
          (
            use f in 
              cs_concl cs_shallow
                  cs_simp: cat_cs_simps cs_intro: cat_cs_intros
          )+
    qed
  qed

qed

lemma cat_corepresentation_if_universal_arrow_of:
  ―‹See Proposition 2 in Chapter III-2 in \cite{mac_lane_categories_2010}.›
  assumes "category α "
    and "𝔎 : op_cat  ↦↦Cαcat_Set α"
    and "𝔞  cat_Set αObj"
    and "universal_arrow_of 𝔎 (set {𝔞}) r u"
  shows "cat_corepresentation α 𝔎 r (Yoneda_arrow α 𝔎 r (uArrVal𝔞))"
proof-
  interpret: category α  by (rule assms(1))
  interpret 𝔎: is_functor α op_cat  cat_Set α 𝔎 by (rule assms(2))
  note ua = 𝔎.universal_arrow_ofD[OF assms(4), unfolded cat_op_simps]
  note [cat_op_simps] = ℭ.cat_op_cat_cf_Hom_snd[OF ua(1)]
  show ?thesis
    by 
      (
        intro cat_corepresentationI,
        rule assms(1),
        rule assms(2),
        rule ua(1),
        rule cat_representationD(2)
          [
            OF
              cat_representation_if_universal_arrow_of[OF assms(2,3,4)] 
              assms(2),
            unfolded cat_op_simps
          ]
      )
qed



subsection‹Limits and colimits as universal cones›

lemma is_tm_cat_limit_if_cat_corepresentation:
  ―‹See Definition 3.1.5 in Section 3.1 in \cite{riehl_category_2016}.›
  assumes "𝔉 : 𝔍 ↦↦C.tmα" 
    and "cat_corepresentation α (tm_cf_Cone α 𝔉) r ψ"
    (is cat_corepresentation α ?Cone r ψ)
  shows "ntcf_of_ntcf_arrow 𝔍  (ψNTMaprArrValCIdr) :
    r <CF.tm.lim 𝔉 : 𝔍 ↦↦C.tmα"
    (is ntcf_of_ntcf_arrow 𝔍  ?ψr1r : r <CF.tm.lim 𝔉 : 𝔍 ↦↦C.tmα)
proof-

  let ?P = ntcf_paa 0 and ?Funct = cat_Funct α 𝔍 

  interpret 𝔉: is_tm_functor α 𝔍  𝔉 by (rule assms(1))
  interpret Funct: category α ?Funct
    by
      (
        cs_concl cs_shallow cs_intro: 
          cat_small_cs_intros cat_cs_intros cat_FUNCT_cs_intros
      )
  note  = cat_corepresentationD[
      OF assms(2) 𝔉.HomCod.category_axioms 𝔉.tm_cf_cf_Cone_is_functor
      ]
  interpret ψ: is_iso_ntcf α op_cat  cat_Set α HomO.Cα(-,r) ?Cone ψ
    by (rule (2))
  have 0: "0  cat_Set αObj" unfolding cat_Set_components by auto
  note ua = universal_arrow_of_if_cat_corepresentation[
      OF 𝔉.HomCod.category_axioms 𝔉.tm_cf_cf_Cone_is_functor assms(2) 0
      ]

  show ?thesis
  proof(rule is_tm_cat_limitI')
    
    from (1) have [cat_FUNCT_cs_simps]:
      "cf_of_cf_map 𝔍  (cf_map (cf_const 𝔍  r)) = cf_const 𝔍  r"
      by
        (
          cs_concl 
            cs_simp: cat_FUNCT_cs_simps
            cs_intro: cat_cs_intros cat_FUNCT_cs_intros
        )
    from ψ.ntcf_NTMap_is_arr[unfolded cat_op_simps, OF (1)] (1) have 
      "ψNTMapr :
        Hom  r r cat_Set αHom ?Funct (cf_map (cf_const 𝔍  r)) (cf_map 𝔉)"
      by
        (
          cs_prems 
            cs_simp: cat_small_cs_simps cat_cs_simps cat_op_simps
            cs_intro: cat_cs_intros
        )
    with (1) have ψr_r: 
      "?ψr1r : cf_map (cf_const 𝔍  r) ?Functcf_map 𝔉"
      by
        (
          cs_concl cs_shallow cs_intro:
            cat_Set_cs_intros cat_cs_intros in_Hom_iff[symmetric]
        )

    from (1) cat_Funct_is_arrD(1)[OF ψr_r, unfolded cat_FUNCT_cs_simps]
    show "ntcf_of_ntcf_arrow 𝔍  ?ψr1r : r <CF.tm.cone 𝔉 : 𝔍 ↦↦C.tmα"
      by (intro is_tm_cat_coneI) 
        (cs_concl cs_shallow cs_intro: cat_cs_intros cat_small_cs_intros)

    fix r' u' assume "u' : r' <CF.tm.cone 𝔉 : 𝔍 ↦↦C.tmα"
    then interpret u': is_tm_cat_cone α r' 𝔍  𝔉 u' .

    have Cone_r': "tm_cf_Cone α 𝔉ObjMapr'  cat_Set αObj"
      by (cs_concl cs_intro: cat_lim_cs_intros cat_cs_intros cat_op_intros)
    from (1) have Cone_r: "tm_cf_Cone α 𝔉ObjMapr  cat_Set αObj"
      by (cs_concl cs_shallow cs_intro: cat_cs_intros cat_op_intros)
    from (1) have ψr1r: 
      "ψNTMaprArrValCIdr  tm_cf_Cone α 𝔉ObjMapr"
      by
        (
          cs_concl cs_shallow
            cs_simp: cat_small_cs_simps cat_cs_simps cat_op_simps 
            cs_intro: cat_cs_intros
        )
    have u': "ntcf_arrow u'  ?ConeObjMapr'"
      by
        (
          cs_concl 
            cs_simp: cat_small_cs_simps
            cs_intro: cat_small_cs_intros cat_FUNCT_cs_intros cat_cs_intros
        )

    have [cat_cs_simps]: 
      "cf_of_cf_map 𝔍  (cf_map 𝔉) = 𝔉"
      "cf_of_cf_map 𝔍  (cf_map (cf_const 𝔍  r)) = cf_const 𝔍  r"
      by (cs_concl cs_simp: cat_FUNCT_cs_simps)+

    from Cone_r 0 ψr1r (1) have ψr1r_is_arr: "ψNTMaprArrValCIdr :
      cf_map (cf_const 𝔍  r) ?Functcf_map 𝔉"
      by
        (
          cs_concl cs_shallow
            cs_simp: cat_cs_simps cat_small_cs_simps 
            cs_intro: cat_cs_intros cat_op_intros
        )

    from (1) have [cat_cs_intros]:
      "Hom ?Funct (cf_map (cf_const 𝔍  r)) (cf_map 𝔉)  cat_Set αObj"
      unfolding cat_Set_components(1)
      by (intro Funct.cat_Hom_in_Vset)
        (
          cs_concl
            cs_simp: cat_FUNCT_cs_simps 
            cs_intro: cat_small_cs_intros cat_FUNCT_cs_intros cat_cs_intros
        )+

    note ψr1r_is_arrD = cat_Funct_is_arrD[OF ψr1r_is_arr, unfolded cat_cs_simps]

    from is_functor.universal_arrow_ofD(3)
      [
        OF 𝔉.tm_cf_cf_Cone_is_functor ua,
        unfolded cat_op_simps,
        OF u'.cat_cone_obj 𝔉.ntcf_paa_is_arr[OF 0 Cone_r' u'] 
      ]
    obtain f where f: "f : r' r"
      and Pf: "?P (?ConeObjMapr') (ntcf_arrow u') =
        umap_of ?Cone (set {0}) r (?P (?ConeObjMapr) ?ψr1r) r'ArrValf"
      and f_unique: "f'.
        
          f' : r' r;
          ?P (?ConeObjMapr') (ntcf_arrow u') =
            umap_of ?Cone (set {0}) r (?P (?ConeObjMapr) ?ψr1r) r'ArrValf'
          f' = f"
      by metis

    show "∃!f.
      f : r' r 
      u' = ntcf_of_ntcf_arrow 𝔍  ?ψr1r NTCF ntcf_const 𝔍  f"
    proof(intro ex1I conjI; (elim conjE)?)
      show "f : r' r" by (rule f)
      from Pf Cone_r 0 f ψr1r ψr1r_is_arr ψr1r_is_arrD(1) show
        "u' = ntcf_of_ntcf_arrow 𝔍  ?ψr1r NTCF ntcf_const 𝔍  f"
        by (subst (asm) ψr1r_is_arrD(2))
          (
            cs_prems
              cs_simp: cat_FUNCT_cs_simps cat_small_cs_simps cat_cs_simps
              cs_intro:
                cat_small_cs_intros
                cat_cs_intros
                cat_FUNCT_cs_intros
                cat_prod_cs_intros
                cat_op_intros
          )

      fix f' assume prems: 
        "f' : r' r"
        "u' = ntcf_of_ntcf_arrow 𝔍  ?ψr1r NTCF ntcf_const 𝔍  f'"
      from Pf Cone_r 0 f ψr1r ψr1r_is_arr ψr1r_is_arrD(1) prems(1) have
        "?P (?ConeObjMapr') (ntcf_arrow u') =
          umap_of ?Cone (set {0}) r (?P (?ConeObjMapr) ?ψr1r) r'ArrValf'"
        by (subst ψr1r_is_arrD(2))
          (
            cs_concl
              cs_simp: cat_FUNCT_cs_simps cat_small_cs_simps cat_cs_simps prems(2)
              cs_intro:
                cat_small_cs_intros
                cat_FUNCT_cs_intros
                cat_cs_intros
                cat_prod_cs_intros
                cat_op_intros
          )
      from f_unique[OF prems(1) this] show "f' = f" .
    qed

  qed

qed

lemma cat_corepresentation_if_is_tm_cat_limit:
  ―‹See Definition 3.1.5 in Section 3.1 in \cite{riehl_category_2016}.›
  assumes "ψ : r <CF.tm.lim 𝔉 : 𝔍 ↦↦C.tmα"
  shows "cat_corepresentation
    α (tm_cf_Cone α 𝔉) r (Yoneda_arrow α (tm_cf_Cone α 𝔉) r (ntcf_arrow ψ))"
    (is cat_corepresentation α ?Cone r ?Yψ)
proof-

  let ?Funct = cat_Funct α 𝔍 
    and ?P_ψ = ntcf_paa 0 (?ConeObjMapr) (ntcf_arrow ψ)
    and ?ntcf_of = ntcf_of_ntcf_arrow 𝔍 

  interpret ψ: is_tm_cat_limit α 𝔍  𝔉 r ψ by (rule assms(1))
  interpret Funct: category α ?Funct
    by
      (
        cs_concl cs_shallow cs_intro:
          cat_small_cs_intros cat_cs_intros cat_FUNCT_cs_intros
      )
  interpret Cone: is_functor α op_cat  cat_Set α ?Cone
    by (rule ψ.NTCod.tm_cf_cf_Cone_is_functor)

  have 0: "0  cat_Set αObj" unfolding cat_Set_components by auto
  have ntcf_arrow_ψ: 
    "ntcf_arrow ψ : cf_map (cf_const 𝔍  r) ?Functcf_map 𝔉"
    by (cs_concl cs_shallow cs_intro: cat_small_cs_intros cat_FUNCT_cs_intros)
  from ψ.cat_cone_obj 0 ntcf_arrow_ψ have P_ψ:
    "?P_ψ : set {0} cat_Set α?ConeObjMapr"
    by
      (
        cs_concl cs_shallow
          cs_intro: cat_cs_intros cat_op_intros 
          cs_simp: cat_small_cs_simps cat_FUNCT_cs_simps
      )

  have "universal_arrow_of ?Cone (set {0}) r ?P_ψ"
  proof(rule Cone.universal_arrow_ofI, unfold cat_op_simps, rule ψ.cat_cone_obj)

    from 0 ψ.cat_cone_obj show "?P_ψ : set {0} cat_Set α?ConeObjMapr"
      by
        (
          cs_concl
            cs_intro:
              cat_small_cs_intros
              cat_cs_intros
              cat_FUNCT_cs_intros
              cat_op_intros
            cs_simp: cat_small_cs_simps
        )

    fix r' u' assume prems:
      "r'  Obj" "u' : set {0} cat_Set α?ConeObjMapr'"

    let ?const_r' = cf_map (cf_const 𝔍  r')
    let ?Hom_r𝔉 = Hom ?Funct ?const_r' (cf_map 𝔉)

    from prems(2,1) have u': "u' : set {0} cat_Set α?Hom_r𝔉"
      by
        (
          cs_prems cs_shallow
            cs_simp: cat_small_cs_simps cat_cs_simps cs_intro: cat_cs_intros
        )
    from prems(1) have [cat_FUNCT_cs_simps]:
      "cf_of_cf_map 𝔍  ?const_r' = cf_const 𝔍  r'"
      by 
        (
          cs_concl 
            cs_simp: cat_cs_simps cat_FUNCT_cs_simps cs_intro: cat_cs_intros
        )

    from
      cat_Set_ArrVal_app_vrange[OF prems(2) vintersection_vsingleton] 
      prems(1)
    have "u'ArrVal0 : ?const_r' ?Functcf_map 𝔉"
      by (cs_prems cs_shallow cs_simp: cat_small_cs_simps cat_cs_simps)
    note u'0 = cat_Funct_is_arrD[OF this, unfolded cat_FUNCT_cs_simps]

    interpret u'0: is_tm_cat_cone α r' 𝔍  𝔉 ?ntcf_of (u'ArrVal0)
      by
        (
          rule is_tm_cat_coneI[
            OF is_tm_ntcfD(1)[OF u'0(1)] ψ.NTCod.is_tm_functor_axioms prems(1)
            ]
        )

    from ψ.tm_cat_lim_ua_fo[OF u'0.is_cat_cone_axioms] obtain f 
      where f: "f : r' r"
        and u'0_def: "?ntcf_of (u'ArrVal0) = ψ NTCF ntcf_const 𝔍  f"
        and f_unique: "f'.
          
            f' : r' r;
            ?ntcf_of (u'ArrVal0) = ψ NTCF ntcf_const 𝔍  f'
            f' = f"
      by metis

    note [cat_FUNCT_cs_simps] = 
      ψ.ntcf_paa_ArrVal u'0(2)[symmetric] u'0_def[symmetric]

    show "∃!f'.
      f' : r' r  u' = umap_of ?Cone (set {0}) r ?P_ψ r'ArrValf'"
    proof(intro ex1I conjI; (elim conjE)?; (rule f)?)

      from f 0 u' ntcf_arrow_ψ show 
        "u' = umap_of ?Cone (set {0}) r ?P_ψ r'ArrValf"
        by (*slow*)
          (
            cs_concl
              cs_simp: cat_cs_simps
              cs_intro:
                cat_small_cs_intros
                cat_FUNCT_cs_intros
                cat_prod_cs_intros
                cat_cs_intros
                cat_op_intros
              cs_simp: cat_FUNCT_cs_simps cat_small_cs_simps
          )

      fix f' assume prems':
        "f' : r' r"
        "u' = umap_of ?Cone (set {0}) r ?P_ψ r'ArrValf'"

      let ?f' = ntcf_const 𝔍  f'

      from prems'(2,1) 0 ntcf_arrow_ψ P_ψ have 
        "u' = ntcf_paa 0 ?Hom_r𝔉 (ntcf_arrow (ψ NTCF ?f'))"
        unfolding 
          Cone.umap_of_ArrVal_app[unfolded cat_op_simps, OF prems'(1) P_ψ]
        by (*very slow*)
          (
            cs_prems
              cs_simp: cat_FUNCT_cs_simps cat_small_cs_simps cat_cs_simps
              cs_intro:
                cat_small_cs_intros
                cat_FUNCT_cs_intros
                cat_prod_cs_intros
                cat_cs_intros
                cat_op_intros
          )
      then have
        "?ntcf_of (u'ArrVal0) =
          ?ntcf_of ((ntcf_paa 0 ?Hom_r𝔉 (ntcf_arrow (ψ NTCF ?f')))ArrVal0)"
        by simp
      from this prems'(1) have "?ntcf_of (u'ArrVal0) = ψ NTCF ?f'"
        by
          (
            cs_prems cs_shallow
              cs_simp: cat_cs_simps cat_FUNCT_cs_simps cs_intro: cat_cs_intros
          )
      from f_unique[OF prems'(1) this] show "f' = f" . 

    qed

  qed

  from 
    cat_corepresentation_if_universal_arrow_of[
      OF ψ.NTDom.HomCod.category_axioms Cone.is_functor_axioms 0 this
      ]
  show "cat_corepresentation α ?Cone r ?Yψ"
    by (cs_prems cs_shallow cs_simp: cat_cs_simps)

qed

text‹\newpage›

end