Theory Subbicategory

(*  Title:       Subbicategory
    Author:      Eugene W. Stark <stark@cs.stonybrook.edu>, 2019
    Maintainer:  Eugene W. Stark <stark@cs.stonybrook.edu>
*)

section "Sub-Bicategories"

text ‹
  In this section we give a construction of a sub-bicategory in terms of a predicate
  on the arrows of an ambient bicategory that has certain closure properties with respect
  to that bicategory.  While the construction given here is likely to be of general use,
  it is not the most general sub-bicategory construction that one could imagine,
  because it requires that the sub-bicategory actually contain the unit and associativity
  isomorphisms of the ambient bicategory.  Our main motivation for including this construction
  here is to apply it to exploit the fact that the sub-bicategory of endo-arrows of a fixed
  object is a monoidal category, which will enable us to transfer to bicategories a result
  about unit isomorphisms in monoidal categories.  
›

theory Subbicategory
imports Bicategory
begin

  subsection "Construction"

  locale subbicategory =
    B: bicategory V H 𝖺B 𝗂 srcB trgB +
    subcategory V Arr
  for V :: "'a comp"                 (infixr "B" 55)
  and H :: "'a comp"                 (infixr "B" 55)
  and 𝖺B :: "'a  'a  'a  'a"    ("𝖺B[_, _, _]")
  and 𝗂 :: "'a  'a"                 ("𝗂[_]")
  and srcB :: "'a  'a"
  and trgB :: "'a  'a"
  and Arr :: "'a  bool" +
  assumes src_closed: "Arr f  Arr (srcB f)"
  and trg_closed: "Arr f  Arr (trgB f)"
  and hcomp_closed: " Arr f; Arr g; trgB f = srcB g   Arr (g B f)"
  and assoc_closed: " Arr f  B.ide f; Arr g  B.ide g; Arr h  B.ide h;
                       srcB f = trgB g; srcB g = trgB h   Arr (𝖺B f g h)"
  and assoc'_closed: " Arr f  B.ide f; Arr g  B.ide g; Arr h  B.ide h;
                       srcB f = trgB g; srcB g = trgB h   Arr (B.inv (𝖺B f g h))"
  and lunit_closed: " Arr f; B.ide f   Arr (B.𝔩 f)"
  and lunit'_closed: " Arr f; B.ide f   Arr (B.inv (B.𝔩 f))"
  and runit_closed: " Arr f; B.ide f   Arr (B.𝔯 f)"
  and runit'_closed: " Arr f; B.ide f   Arr (B.inv (B.𝔯 f))"
  begin

    notation B.in_hom           ("«_ : _ B _»")

    notation comp               (infixr "" 55)

    definition hcomp            (infixr "" 53)
    where "g  f = (if arr f  arr g  trgB f = srcB g then g B f else null)"

    definition src
    where "src μ = (if arr μ then srcB μ else null)"

    definition trg
    where "trg μ = (if arr μ then trgB μ else null)"

    interpretation src: endofunctor (⋅) src
      using src_def null_char inclusion arr_charSbC src_closed trg_closed dom_closed cod_closed
            dom_simp cod_simp
      apply unfold_locales
          apply auto[4]
      by (metis B.src.as_nat_trans.preserves_comp_2 comp_char seq_charSbC)

    interpretation trg: endofunctor (⋅) trg
      using trg_def null_char inclusion arr_charSbC src_closed trg_closed dom_closed cod_closed
            dom_simp cod_simp
      apply unfold_locales
          apply auto[4]
      by (metis B.trg.as_nat_trans.preserves_comp_2 comp_char seq_charSbC)

    interpretation horizontal_homs (⋅) src trg
      using src_def trg_def src.preserves_arr trg.preserves_arr null_char ide_charSbC arr_charSbC
            inclusion
      by (unfold_locales, simp_all)

    interpretation "functor" VV.comp (⋅) λμν. fst μν  snd μν
      using hcomp_def VV.arr_charSbC src_def trg_def arr_charSbC hcomp_closed dom_charSbC cod_charSbC
            VV.dom_charSbC VV.cod_charSbC
      apply unfold_locales
          apply auto[2]
    proof -
      fix f
      assume f: "VV.arr f"
      show "dom (fst f  snd f) = fst (VV.dom f)  snd (VV.dom f)"
      proof -
        have "dom (fst f  snd f) = B.dom (fst f) B B.dom (snd f)"
        proof -
          have "dom (fst f  snd f) = B.dom (fst f  snd f)"
            using f dom_charSbC
            by (simp add: arr_charSbC hcomp_closed hcomp_def)
          also have "... = B.dom (fst f) B B.dom (snd f)"
            using f
            by (metis (no_types, lifting) B.hcomp_simps(3) B.hseqI' VV.arrE arrE hcomp_def
                inclusion src_def trg_def)
          finally show ?thesis by blast
        qed
        also have "... = fst (VV.dom f)  snd (VV.dom f)"
           using f VV.arr_charSbC VV.dom_charSbC arr_charSbC hcomp_def B.seq_if_composable dom_closed
           apply simp
           by (metis (no_types, lifting) dom_charSbC)
        finally show ?thesis by simp
      qed
      show "cod (fst f  snd f) = fst (VV.cod f)  snd (VV.cod f)"
      proof -
        have "cod (fst f  snd f) = B.cod (fst f) B B.cod (snd f)"
          using f VV.arr_charSbC arr_charSbC cod_charSbC hcomp_def src_def trg_def
                src_closed trg_closed hcomp_closed inclusion B.hseq_char arrE
          by auto
        also have "... = fst (VV.cod f)  snd (VV.cod f)"
           using f VV.arr_charSbC VV.cod_charSbC arr_charSbC hcomp_def B.seq_if_composable cod_closed
           apply simp
           by (metis (no_types, lifting) cod_charSbC)
        finally show ?thesis by simp
      qed
      next
      fix f g
      assume fg: "VV.seq g f"
      show "fst (VV.comp g f)  snd (VV.comp g f) = (fst g  snd g)  (fst f  snd f)"
      proof -
        have "fst (VV.comp g f)  snd (VV.comp g f) = fst g  fst f  snd g  snd f"
          using fg VV.seq_charSbC VV.comp_char VxV.comp_char VxV.not_Arr_Null
          by (metis (no_types, lifting) VxV.seqEPC prod.sel(1-2))
        also have "... = (fst g B fst f) B (snd g B snd f)"
          using fg comp_char hcomp_def VV.seq_charSbC inclusion arr_charSbC seq_charSbC B.hseq_char
          by (metis (no_types, lifting) B.hseq_char' VxV.seq_char null_char)
        also have 1: "... = (fst g B snd g) B (fst f B snd f)"
        proof -
          have "srcB (fst g) = trgB (snd g)"
            by (metis (no_types, lifting) VV.arrE VV.seq_charSbC fg src_def trg_def)
          thus ?thesis
            using fg VV.seq_charSbC VV.arr_charSbC arr_charSbC seq_charSbC inclusion B.interchange
            by (meson VxV.seqEPC)
        qed
        also have "... = (fst g  snd g)  (fst f  snd f)"
          using fg comp_char hcomp_def VV.seq_charSbC VV.arr_charSbC arr_charSbC seq_charSbC inclusion
                B.hseq_char' hcomp_closed src_def trg_def
          by (metis (no_types, lifting) 1)
        finally show ?thesis by auto
      qed
    qed

    interpretation horizontal_composition (⋅) (⋆) src trg
      using arr_charSbC src_def trg_def src_closed trg_closed
      apply (unfold_locales)
      using hcomp_def inclusion not_arr_null by auto

    abbreviation 𝖺
    where "𝖺 μ ν τ  if VVV.arr (μ, ν, τ) then 𝖺B μ ν τ else null"

    abbreviation (input) αSB
    where "αSB μντ  𝖺 (fst μντ) (fst (snd μντ)) (snd (snd μντ))"

    lemma assoc_closed':
    assumes "VVV.arr μντ"
    shows "Arr (αSB μντ)"
    proof -
      have 1: "B.VVV.arr μντ"
        using assms VVV.arr_charSbC VV.arr_charSbC B.VVV.arr_charSbC B.VV.arr_charSbC arr_charSbC
              src_def trg_def inclusion
        by auto
      show "Arr (αSB μντ)"
      proof -
        have "Arr (αSB μντ) =
              Arr ((fst μντ B fst (snd μντ) B snd (snd μντ)) B αSB (B.VVV.dom μντ))"
          using assms 1 B.α_def B.assoc_is_natural_1 [of "fst μντ" "fst (snd μντ)" "snd (snd μντ)"]
                VV.arr_charSbC VVV.arr_charSbC B.VVV.arr_charSbC B.VV.arr_charSbC B.VVV.dom_charSbC B.VV.dom_charSbC
          apply simp
          by (metis (no_types, lifting) arr_charSbC dom_charSbC dom_closed src.preserves_dom
              trg.preserves_dom)
        also have "..."
        proof (intro comp_closed)
          show "Arr (fst μντ B fst (snd μντ) B snd (snd μντ))"
            using assms 1 B.VVV.arr_charSbC B.VV.arr_charSbC hcomp_closed
            by (metis (no_types, lifting) B.H.preserves_reflects_arr B.trg_hcomp
                VV.arr_charSbC VVV.arrE arr_charSbC)
          show "B.cod (𝖺 (fst (B.VVV.dom μντ)) (fst (snd (B.VVV.dom μντ)))
                      (snd (snd (B.VVV.dom μντ)))) =
                B.dom (fst μντ B fst (snd μντ) B snd (snd μντ))"
            using assms 1 VVV.arr_charSbC VV.arr_charSbC B.VxVxV.dom_char
                  B.VVV.dom_simp B.VVV.cod_simp
            apply simp
            by (metis (no_types, lifting) B.VV.arr_charSbC B.VVV.arrE B.α.preserves_reflects_arr
                B.assoc_is_natural_1 B.seqE arr_dom dom_charSbC src_dom trg_dom)
          show "Arr (𝖺 (fst (B.VVV.dom μντ)) (fst (snd (B.VVV.dom μντ)))
                    (snd (snd (B.VVV.dom μντ))))"
          proof -
            have "VVV.arr (B.VVV.dom μντ)"
              using 1 B.VVV.dom_charSbC B.VVV.arr_charSbC B.VV.arr_charSbC VVV.arr_charSbC VV.arr_charSbC
              apply simp
              by (metis (no_types, lifting) VVV.arrE arr_dom assms dom_simp src_dom trg_dom)
            moreover have "Arr (𝖺B (B.dom (fst μντ)) (B.dom (fst (snd μντ)))
                               (B.dom (snd (snd μντ))))"
            proof -
              have "B.VVV.ide (B.VVV.dom μντ)"
                using 1 B.VVV.ide_dom by blast
              thus ?thesis
                using assms B.α_def B.VVV.arr_charSbC B.VV.arr_charSbC B.VVV.ide_char B.VV.ide_char
                      dom_closed assoc_closed
                by (metis (no_types, lifting) "1" B.ide_dom B.src_dom B.trg_dom VV.arr_charSbC
                    VVV.arrE arr_charSbC)
            qed
            ultimately show ?thesis
              using 1 B.VVV.ide_dom assoc_closed B.VVV.dom_charSbC
              apply simp
              by (metis (no_types, lifting) B.VV.arr_charSbC B.VVV.arrE B.VVV.inclusion
                  B.VxV.dom_char B.VxVxV.arrE B.VxVxV.dom_char prod.sel(1) prod.sel(2))
          qed
        qed
        finally show ?thesis by blast
      qed
    qed

    lemma lunit_closed':
    assumes "Arr f"
    shows "Arr (B.𝔩 f)"
    proof -
      have 1: "arr f  arr (B.𝔩 (B.dom f))"
        using assms arr_charSbC lunit_closed dom_closed B.ide_dom inclusion by simp
      moreover have "B.dom f = B.cod (B.𝔩 (B.dom f))"
        using 1 arr_charSbC B.𝔩.preserves_cod inclusion by simp
      moreover have "B.𝔩 f = f  B.𝔩 (B.dom f)"
        using assms 1 B.𝔩.is_natural_1 inclusion comp_char arr_charSbC by simp
      ultimately show ?thesis
        using arr_charSbC comp_closed cod_charSbC seqI dom_simp by auto
    qed
      
    lemma runit_closed':
    assumes "Arr f"
    shows "Arr (B.𝔯 f)"
    proof -
      have 1: "arr f  arr (B.𝔯 (B.dom f))"
        using assms arr_charSbC runit_closed dom_closed B.ide_dom inclusion
        by simp
      moreover have "B.dom f = B.cod (B.𝔯 (B.dom f))"
        using 1 arr_charSbC B.𝔩.preserves_cod inclusion by simp
      moreover have "B.𝔯 f = f  B.𝔯 (B.dom f)"
        using assms 1 B.𝔯.is_natural_1 inclusion comp_char arr_charSbC by simp
      ultimately show ?thesis
        using arr_charSbC comp_closed cod_charSbC seqI dom_simp by auto
    qed

    interpretation natural_isomorphism VVV.comp (⋅) HoHV HoVH αSB
    proof
      fix μντ
      show "¬ VVV.arr μντ  αSB μντ = null"
        by simp
      assume μντ: "VVV.arr μντ"
      have 1: "B.VVV.arr μντ"
        using μντ VVV.arr_charSbC VV.arr_charSbC B.VVV.arr_charSbC B.VV.arr_charSbC arr_charSbC
              src_def trg_def inclusion
        by auto
      show "dom (αSB μντ) = HoHV (VVV.dom μντ)"
      proof -
        have "dom (αSB μντ) = B.HoHV (B.VVV.dom μντ)"
          using μντ 1 arr_charSbC VVV.arr_charSbC VV.arr_charSbC B.VVV.arr_charSbC B.VV.arr_charSbC
                B.α_def assoc_closed' dom_simp
          by simp
        also have "... = HoHV (VVV.dom μντ)"
        proof -
          have "HoHV (VVV.dom μντ) = HoHV (VxVxV.dom μντ)"
            using μντ VVV.dom_charSbC VV.arr_charSbC src_def trg_def VVV.arr_charSbC by auto
          also have "... = B.HoHV (B.VVV.dom μντ)"
             using μντ VVV.dom_charSbC VVV.arr_charSbC VV.arr_charSbC src_def trg_def
                   HoHV_def B.HoHV_def arr_charSbC B.VVV.arr_charSbC B.VVV.dom_charSbC B.VV.arr_charSbC
                   dom_closed hcomp_closed hcomp_def inclusion dom_simp
             by auto
          finally show ?thesis by simp
        qed
        finally show ?thesis by simp
      qed
      show "cod (αSB μντ) = HoVH (VVV.cod μντ)"
      proof -
        have "cod (αSB μντ) = B.HoVH (B.VVV.cod μντ)"
          using μντ 1 arr_charSbC VVV.arr_charSbC VV.arr_charSbC B.VVV.arr_charSbC B.VV.arr_charSbC
                B.α_def assoc_closed' cod_simp
          by simp
        also have "... = HoVH (VVV.cod μντ)"
        proof -
          have "HoVH (VVV.cod μντ) = HoVH (VxVxV.cod μντ)"
            using μντ VVV.cod_charSbC VV.arr_charSbC src_def trg_def VVV.arr_charSbC by auto
          also have "... = B.HoVH (B.VVV.cod μντ)"
            using μντ VVV.cod_charSbC VV.arr_charSbC src_def trg_def VVV.arr_charSbC
                  HoVH_def B.HoVH_def arr_charSbC B.VVV.arr_charSbC B.VVV.cod_charSbC B.VV.arr_charSbC
                  cod_closed hcomp_closed hcomp_def inclusion cod_simp
            by simp
          finally show ?thesis by simp
        qed
        finally show ?thesis by simp
      qed
      have 3: "Arr (fst μντ)  Arr (fst (snd μντ))  Arr (snd (snd μντ)) 
               srcB (fst μντ) = trgB (fst (snd μντ)) 
               srcB (fst (snd μντ)) = trgB (snd (snd μντ))"
        using μντ VVV.arr_charSbC VV.arr_charSbC src_def trg_def arr_charSbC by auto
      show "HoVH μντ  αSB (VVV.dom μντ) = αSB μντ"
      proof -
        have "αSB μντ = (fst μντ B fst (snd μντ) B snd (snd μντ)) B
                           𝖺B (B.dom (fst μντ)) (B.dom (fst (snd μντ))) (B.dom (snd (snd μντ)))"
          using 3 inclusion B.assoc_is_natural_1 [of "fst μντ" "fst (snd μντ)" "snd (snd μντ)"]
          by (simp add: μντ)
        also have "... = (fst μντ  fst (snd μντ)  snd (snd μντ)) 
                           𝖺B (dom (fst μντ)) (dom (fst (snd μντ))) (dom (snd (snd μντ)))"
          using 1 3 μντ hcomp_closed assoc_closed dom_closed hcomp_def comp_def inclusion
            comp_char dom_charSbC VVV.arr_charSbC VV.arr_charSbC
          apply simp
          using B.hcomp_simps(2-3) arr_charSbC by presburger
        also have "... = HoVH μντ  αSB (VVV.dom μντ)"
          using μντ B.α_def HoVH_def VVV.dom_charSbC VV.dom_charSbC VxVxV.dom_char
          apply simp
          by (metis (no_types, lifting) VV.arr_charSbC VVV.arrE VVV.arr_dom VxV.dom_char
              dom_simp)
        finally show ?thesis by argo
      qed
      show "αSB (VVV.cod μντ)  HoHV μντ = αSB μντ"
      proof -
        have "αSB μντ =
              𝖺B (B.cod (fst μντ)) (B.cod (fst (snd μντ))) (B.cod (snd (snd μντ))) B
                (fst μντ B fst (snd μντ)) B snd (snd μντ)"
          using 3 inclusion B.assoc_is_natural_2 [of "fst μντ" "fst (snd μντ)" "snd (snd μντ)"]
          by (simp add: μντ)
        also have "... = 𝖺B (cod (fst μντ)) (cod (fst (snd μντ))) (cod (snd (snd μντ))) 
                           ((fst μντ  fst (snd μντ))  snd (snd μντ))"
          by (simp add: "3" arrISbC assoc_closed cod_charSbC cod_closed hcomp_closed hcomp_def
              inclusion comp_def)
        also have "... = αSB (VVV.cod μντ)  HoHV μντ"
          using μντ B.α_def HoHV_def VVV.cod_charSbC VV.cod_charSbC VxVxV.cod_char
                VVV.arr_charSbC VV.arr_charSbC arr_cod src_cod trg_cod
          by simp
        finally show ?thesis by argo
      qed
      next
      fix fgh
      assume fgh: "VVV.ide fgh"
      show "iso (αSB fgh)"
      proof -
        have 1: "B.arr (fst (snd fgh))  B.arr (snd (snd fgh)) 
                   srcB (fst (snd fgh)) = trgB (snd (snd fgh)) 
                   srcB (fst fgh) = trgB (fst (snd fgh))"
          using fgh VVV.ide_char VVV.arr_charSbC VV.arr_charSbC src_def trg_def
                arr_charSbC inclusion
          by auto
        have 2: "B.ide (fst fgh)  B.ide (fst (snd fgh))  B.ide (snd (snd fgh))"
          using fgh VVV.ide_charSbC ide_charSbC by blast
        have "αSB fgh = 𝖺B (fst fgh) (fst (snd fgh)) (snd (snd fgh))"
          using fgh B.α_def by simp
        moreover have "B.VVV.ide fgh"
          using fgh 1 2 VVV.ide_char B.VVV.ide_charSbC VVV.arr_charSbC B.VVV.arr_charSbC
                src_def trg_def inclusion arr_charSbC B.VV.arr_charSbC
          by simp
        moreover have "Arr (𝖺B (fst fgh) (fst (snd fgh)) (snd (snd fgh)))"
          using fgh 1 VVV.ide_char VVV.arr_charSbC VV.arr_charSbC src_def trg_def
                arr_charSbC assoc_closed' B.α_def
          by simp
        moreover have "Arr (B.inv (𝖺B (fst fgh) (fst (snd fgh)) (snd (snd fgh))))"
          using fgh 1 VVV.ide_char VVV.arr_charSbC VV.arr_charSbC src_def trg_def
                arr_charSbC assoc'_closed
          by (simp add: VVV.arr_charSbC "2" B.VVV.ide_char calculation(2))
        ultimately show ?thesis
          using fgh iso_charSbC B.α.components_are_iso by auto
      qed
    qed

    interpretation L: endofunctor (⋅) L
      using endofunctor_L by auto
    interpretation R: endofunctor (⋅) R
      using endofunctor_R by auto

    interpretation L: faithful_functor (⋅) (⋅) L
    proof
      fix f f'
      assume par: "par f f'"
      assume eq: "L f = L f'"
      have "B.par f f'"
        using par inclusion arr_charSbC dom_simp cod_simp by fastforce
      moreover have "B.L f = B.L f'"
      proof -
        have "a. Arr a  B.arr a"
          by (simp add: inclusion)
        moreover have 1: "a. arr a  (if arr a then hseq (trg a) a else arr null)"
          using L.preserves_arr by presburger
        moreover have "Arr f  Arr (trg f)  trgB f = srcB (trg f)"
          by (simp add: B.par f f' arrE par trg_closed trg_def)
        ultimately show ?thesis
          by (metis B.par f f' eq hcomp_def hseq_char' par trg_def)
      qed
      ultimately show "f = f'"
        using B.L.is_faithful by blast
    qed
    interpretation L: full_functor (⋅) (⋅) L
    proof
      fix f f' ν
      assume f: "ide f" and f': "ide f'" and ν: "«ν : L f  L f'»"
      have 1: "L f = trgB f B f  L f' = trgB f' B f'"
        using f f' hcomp_def trg_def arr_charSbC ide_charSbC trg_closed by simp
      have 2: "«ν : trgB f B f B trgB f' B f'»"
        using 1 f f' ν hcomp_def trg_def src_def inclusion
              dom_charSbC cod_charSbC hseq_char' arr_charSbC ide_charSbC trg_closed null_char
        by (simp add: arr_charSbC in_hom_charSbC)
      show "μ. «μ : f  f'»  L μ = ν"
      proof -
        let  = "B.𝔩 f' B ν B B.inv (B.𝔩 f)"
        have μ: "« : f  f'»  « : f B f'»"
        proof -
          have "« : f B f'»"
            using f f' ν 2 B.𝔩_ide_simp lunit'_closed lunit_closed' ide_charSbC by auto
          thus ?thesis
            using f f' ν in_hom_charSbC arr_charSbC comp_closed ide_charSbC
                  lunit'_closed lunit_closed
            by (metis (no_types, lifting) B.arrI B.seqE in_homE)
        qed
        have μ_eq: " = B.𝔩 f'  ν  B.inv (B.𝔩 f)"
        proof -
          have " = B.𝔩 f'  ν B B.inv (B.𝔩 f)"
            by (metis (no_types, lifting) B.arrI B.seqE μ ν arrE comp_closed f f'
                ide_charSbC in_hom_charSbC comp_def lunit'_closed lunit_closed)
          also have "... = B.𝔩 f'  ν  B.inv (B.𝔩 f)"
            using f f' ν μ arr_charSbC inclusion comp_char comp_closed ide_charSbC
                  lunit'_closed lunit_closed
            by (metis (no_types, lifting) B.seqE in_homE)
          finally show ?thesis by simp
        qed
        have "L  = ν"
        proof -
          have "L  = trgB  B "
            using μ μ_eq hcomp_def trg_def inclusion arr_charSbC trg_closed by auto
          also have "... = (trgB  B ) B (B.inv (B.𝔩 f) B B.𝔩 f)"
          proof -
            have "B.inv (B.𝔩 f) B B.𝔩 f = trgB f B f"
              using f ide_charSbC B.comp_inv_arr B.inv_is_inverse by auto
            moreover have "B.dom (trgB  B ) = trgB f B f"
            proof -
              have "B.dom (trgB ) = trgB f"
                using f μ B.vconn_implies_hpar(2) by force
              moreover have "B.dom  = f"
                using μ by blast
              ultimately show ?thesis
                using B.hcomp_simps [of "trgB " ]
                by (metis (no_types, lifting) B.hseqI' B.ideD(1) B.src_trg
                    B.trg.preserves_reflects_arr B.trg_dom f ide_charSbC)
            qed
            ultimately show ?thesis
              using μ μ_eq B.comp_arr_dom in_hom_charSbC by auto
          qed
          also have "... = ((trgB  B ) B B.inv (B.𝔩 f)) B B.𝔩 f"
            using B.comp_assoc by simp
          also have "... = (B.inv (B.𝔩 f') B ) B B.𝔩 f"
            using μ μ_eq B.𝔩'.naturality [of ] by auto
          also have "... = (B.inv (B.𝔩 f') B B.𝔩 f') B ν B (B.inv (B.𝔩 f) B B.𝔩 f)"
            using μ μ_eq arr_charSbC arrI comp_simp B.comp_assoc by metis
          also have "... = ν"
            using f f' ν 2 B.comp_arr_dom B.comp_cod_arr ide_charSbC
                  B.𝔩.components_are_iso B.𝔩_ide_simp B.comp_inv_arr'
            by auto
          finally show ?thesis by blast
        qed
        thus ?thesis
          using μ by auto
      qed
    qed

    interpretation R: faithful_functor (⋅) (⋅) R
    proof
      fix f f'
      assume par: "par f f'"
      assume eq: "R f = R f'"
      have "B.par f f'"
        using par inclusion arr_charSbC dom_simp cod_simp by fastforce
      moreover have "B.R f = B.R f'"
      proof -
        have "a. Arr a  B.arr a"
          by (simp add: inclusion)
        moreover have 1: "a. arr a  (if arr a then hseq a (src a) else arr null)"
          using R.preserves_arr by presburger
        moreover have "arr f  arr (src f)  trgB (src f) = srcB f"
          by (meson 1 hcomp_def hseq_char' par)
        ultimately show ?thesis
          by (metis B.par f f' eq hcomp_def hseq_char' src_def)
      qed
      ultimately show "f = f'"
        using B.R.is_faithful by blast
    qed
    interpretation R: full_functor (⋅) (⋅) R
    proof
      fix f f' ν
      assume f: "ide f" and f': "ide f'" and ν: "«ν : R f  R f'»"
      have 1: "R f = f B srcB f  R f' = f' B srcB f'"
        using f f' hcomp_def src_def arr_charSbC ide_charSbC src_closed by simp
      have 2: "«ν : f B srcB f B f' B srcB f'»"
        using 1 f f' ν hcomp_def trg_def src_def inclusion
              dom_charSbC cod_charSbC hseq_char' arr_charSbC ide_charSbC trg_closed null_char
        by (simp add: arr_charSbC in_hom_charSbC)
      show "μ. «μ : f  f'»  R μ = ν"
      proof -
        let  = "B.𝔯 f' B ν B B.inv (B.𝔯 f)"
        have μ: "« : f  f'»  « : f B f'»"
        proof -
          have "« : f B f'»"
            using f f' ν 2 B.𝔯_ide_simp runit'_closed runit_closed' ide_charSbC by auto
          thus ?thesis
            by (metis (no_types, lifting) B.arrI B.seqE ν arrE arrISbC comp_closed f f'
                ide_charSbC in_hom_charSbC runit'_closed runit_closed')
        qed
        have μ_eq: " = B.𝔯 f'  ν  B.inv (B.𝔯 f)"
        proof -
          have " = B.𝔯 f'  ν B B.inv (B.𝔯 f)"
            using f f' ν μ arr_charSbC inclusion comp_char comp_closed ide_charSbC
                 runit'_closed runit_closed
            by (metis (no_types, lifting) B.seqE in_homE)
          also have "... = B.𝔯 f'  ν  B.inv (B.𝔯 f)"
            using f f' ν μ arr_charSbC inclusion comp_char comp_closed ide_charSbC
                  runit'_closed runit_closed
            by (metis (no_types, lifting) B.arrI B.comp_in_homE in_hom_charSbC)
          finally show ?thesis by simp
        qed
        have "R  = ν"
        proof -
          have "R  =  B srcB "
            using μ μ_eq hcomp_def src_def inclusion arr_charSbC src_closed by auto
          also have "... = ( B srcB ) B (B.inv (B.𝔯 f) B B.𝔯 f)"
          proof -
            have "B.inv (B.𝔯 f) B B.𝔯 f = f B srcB f"
              using f ide_charSbC B.comp_inv_arr B.inv_is_inverse by auto
            moreover have "B.dom ( B srcB ) = f B srcB f"
              using f μ μ_eq ide_char arr_charSbC B.src_dom [of ]
              by (metis (no_types, lifting) B.R.as_nat_trans.preserves_comp_2 B.R.preserves_seq
                  B.dom_src B.hcomp_simps(3) B.in_homE)
            ultimately show ?thesis
              using μ μ_eq B.comp_arr_dom in_hom_charSbC by auto
          qed
          also have "... = (( B srcB ) B B.inv (B.𝔯 f)) B B.𝔯 f"
            using B.comp_assoc by simp
          also have "... = (B.inv (B.𝔯 f') B ) B B.𝔯 f"
            using μ μ_eq B.𝔯'.naturality [of ] by auto
          also have "... = (B.inv (B.𝔯 f') B B.𝔯 f') B ν B (B.inv (B.𝔯 f) B B.𝔯 f)"
            using μ μ_eq arr_charSbC arrI comp_simp B.comp_assoc by metis
          also have "... = ν"
            using f f' ν 2 B.comp_arr_dom B.comp_cod_arr ide_charSbC
                  B.𝔩.components_are_iso B.𝔩_ide_simp B.comp_inv_arr'
            by auto
          finally show ?thesis by blast
        qed
        thus ?thesis
          using μ by blast
      qed
    qed

    interpretation bicategory (⋅) (⋆) 𝖺 𝗂 src trg
    proof
      show "a. obj a  «𝗂[a] : a  a  a»"
      proof (intro in_homI)
        fix a
        assume a: "obj a"
        have 1: "Arr (𝗂 a)"
          using a obj_def src_def trg_def in_hom_charSbC B.unit_in_hom
                arr_charSbC hcomp_def B.obj_def ide_charSbC objE hcomp_closed
          by (metis (no_types, lifting) B.𝔩_ide_simp B.unitor_coincidence(1) inclusion lunit_closed)
        show 2: "arr 𝗂[a]"
          using 1 arr_charSbC by simp
        show "dom 𝗂[a] = a  a"
          using a 2 dom_charSbC
          by (metis (full_types) B.objI_trg B.unit_simps(4) R.preserves_reflects_arr
              hcomp_def hseq_char' inclusion objE obj_simps(1)
              subcategory.arrE subcategory_axioms trg_def)
        show "cod 𝗂[a] = a"
          using a 2 cod_charSbC
          by (metis B.obj_def' B.unit_simps(5) inclusion objE obj_simps(1)
              subcategory.arrE subcategory_axioms trg_def)
      qed
      show "a. obj a  iso (𝗂 a)"
      proof -
        fix a
        assume a: "obj a"
        have 1: "trgB a = srcB a"
          using a obj_def src_def trg_def B.obj_def arr_charSbC
          by (metis horizontal_homs.objE horizontal_homs_axioms)
        have 2: "Arr (𝗂 a)"
          using a 1 obj_def src_def trg_def in_hom_charSbC B.unit_in_hom
                arr_charSbC hcomp_def B.obj_def ide_charSbC objE hcomp_closed
          by (metis (no_types, lifting) B.𝔩_ide_simp B.unitor_coincidence(1) inclusion lunit_closed)
        have "iso (B.𝔩 a)"
          using a 2 obj_def B.iso_unit iso_charSbC arr_charSbC lunit_closed lunit'_closed B.iso_lunit
          apply simp
          by (metis (no_types, lifting) B.𝔩.components_are_iso B.ide_src inclusion src_def)
        thus "iso (𝗂 a)"
          using a 2 obj_def B.iso_unit iso_charSbC arr_charSbC B.unitor_coincidence
          apply simp
          by (metis (no_types, lifting) B.𝔩_ide_simp B.ide_src B.obj_src inclusion src_def)
      qed
      show "f g h k.  ide f; ide g; ide h; ide k;
                        src f = trg g; src g = trg h; src h = trg k  
                           (f  𝖺 g h k)  𝖺 f (g  h) k  (𝖺 f g h  k) =
                           𝖺 f g (h  k)  𝖺 (f  g) h k"
        using B.pentagon VVV.arr_charSbC VV.arr_charSbC hcomp_def assoc_closed arr_charSbC comp_char
              hcomp_closed comp_closed ide_charSbC inclusion src_def trg_def
        by simp       
    qed

    proposition is_bicategory:
    shows "bicategory (⋅) (⋆) 𝖺 𝗂 src trg"
      ..

    lemma obj_char:
    shows "obj a  arr a  B.obj a"
    proof
      assume a: "obj a"
      show "arr a  B.obj a"
        using a obj_def B.obj_def src_def arr_charSbC inclusion by metis
      next
      assume a: "arr a  B.obj a"
      have "src a = a"
        using a src_def by auto
      thus "obj a"
        using a obj_def by simp
    qed

    lemma hcomp_char:
    shows "hcomp = (λf g. if arr f  arr g  src f = trg g then f B g else null)"
      using hcomp_def src_def trg_def by metis

    lemma assoc_simp:
    assumes "ide f" and "ide g" and "ide h" and "src f = trg g" and "src g = trg h"
    shows "𝖺 f g h = 𝖺B f g h"
      using assms VVV.arr_charSbC VV.arr_charSbC by auto

    lemma assoc'_simp:
    assumes "ide f" and "ide g" and "ide h" and "src f = trg g" and "src g = trg h"
    shows "𝖺' f g h = B.𝖺' f g h"
    proof -
      have "𝖺' f g h = B.inv (𝖺B f g h)"
        using assms inv_charSbC by fastforce
      also have "... = B.𝖺' f g h"
        using assms ide_charSbC src_def trg_def
              B.VVV.ide_charSbC B.VVV.arr_charSbC B.VV.arr_charSbC
        by force
      finally show ?thesis by blast
    qed

    lemma lunit_simp:
    assumes "ide f"
    shows "lunit f = B.lunit f"
    proof -
      have "B.lunit f = lunit f"
      proof (intro lunit_eqI)
        show "ide f" by fact
        show 1: "«B.lunit f : trg f  f  f»"
        proof
          show 2: "arr (B.lunit f)"
            using assms arr_charSbC lunit_closed
            by (simp add: arr_charSbC B.𝔩_ide_simp ide_charSbC)
          show "dom (B.lunit f) = trg f  f"
            using assms 2 dom_charSbC hcomp_char ide_charSbC src_trg trg.preserves_arr trg_def
            by auto
          show "cod (B.lunit f) = f"
            using assms 2 in_hom_charSbC
            by (simp add: cod_simp ide_charSbC)
        qed
        show "trg f  B.lunit f = (𝗂[trg f]  f)  𝖺' (trg f) (trg f) f"
        proof -
          have "trg f  B.lunit f = trgB f B B.lunit f"
            using assms 1 arr_charSbC hcomp_char
            by (metis (no_types, lifting) ideD(1) src_trg trg.preserves_reflects_arr
                trg_def vconn_implies_hpar(2,4))
          also have "... = (𝗂[trg f] B f) B B.𝖺' (trg f) (trg f) f"
            using assms ide_charSbC B.lunit_char(2) trg_def by simp
          also have "... = (𝗂[trg f] B f) B 𝖺' (trg f) (trg f) f"
            using assms assoc'_simp [of "trg f" "trg f" f] by simp
          also have "... = (𝗂[trg f]  f) B 𝖺' (trg f) (trg f) f"
            using assms hcomp_char by simp
          also have "... = (𝗂[trg f]  f)  𝖺' (trg f) (trg f) f"
            using assms seq_charSbC [of "𝗂[trg f]  f" "𝖺' (trg f) (trg f) f"]
                  comp_char [of "𝗂[trg f]  f" "𝖺' (trg f) (trg f) f"]
            by simp
          finally show ?thesis by blast
        qed
      qed
      thus ?thesis by simp
    qed

    lemma lunit'_simp:
    assumes "ide f"
    shows "lunit' f = B.lunit' f"
      using assms inv_charSbC [of "lunit f"] lunit_simp by fastforce

    lemma runit_simp:
    assumes "ide f"
    shows "runit f = B.runit f"
    proof -
      have "B.runit f = runit f"
      proof (intro runit_eqI)
        show "ide f" by fact
        show 1: "«B.runit f : f  src f  f»"
        proof
          show 2: "arr (B.runit f)"
            using assms arr_charSbC runit_closed
            by (simp add: arr_charSbC B.𝔯_ide_simp ide_charSbC)
          show "dom (B.runit f) = f  src f"
            using assms 2 dom_charSbC hcomp_char
            by (metis (no_types, lifting) B.runit_simps(4) ide_charSbC src.preserves_reflects_arr
                src_def trg_src)
          show "cod (B.runit f) = f"
            using assms 2 in_hom_charSbC
            by (simp add: cod_simp ide_charSbC)
        qed
        show "B.runit f  src f = (f  𝗂[src f])  𝖺 f (src f) (src f)"
        proof -
          have "B.runit f  src f = B.runit f B srcB f"
            using assms 1 arr_charSbC hcomp_char
            by (metis (no_types, lifting) ideD(1) src.preserves_reflects_arr src_def
                trg_src vconn_implies_hpar(1,3))
          also have "... = (f B 𝗂[src f]) B 𝖺B f (src f) (src f)"
            using assms ide_charSbC B.runit_char(2) src_def by simp
          also have "... = (f B 𝗂[src f]) B 𝖺 f (src f) (src f)"
            using assms assoc_simp by simp
          also have "... = (f  𝗂[src f]) B 𝖺 f (src f) (src f)"
            using assms 1 hcomp_char by simp
          also have "... = (f  𝗂[src f])  𝖺 f (src f) (src f)"
          proof -
            have "B.seq (f  𝗂[src f]) (𝖺 f (src f) (src f))"
              using assms seq_charSbC [of "f  𝗂[src f]" "𝖺 f (src f) (src f)"] by simp
            thus ?thesis
              using assms comp_char [of "f  𝗂[src f]" "𝖺 f (src f) (src f)"] by simp
          qed
          finally show ?thesis by blast
        qed
      qed
      thus ?thesis by simp
    qed

    lemma runit'_simp:
    assumes "ide f"
    shows "runit' f = B.runit' f"
      using assms inv_charSbC [of "runit f"] runit_simp by fastforce

    lemma comp_eqI [intro]:
    assumes "seq f g" and "f = f'" and "g = g'"
    shows "f  g = f' B g'"
      using assms comp_char ext ext not_arr_null by auto

    lemma comp_eqI' [intro]:
    assumes "seq f g" and "f = f'" and "g = g'"
    shows "f B g = f'  g'"
      using assms comp_char ext ext not_arr_null by auto

    lemma hcomp_eqI [intro]:
    assumes "hseq f g" and "f = f'" and "g = g'"
    shows "f  g = f' B g'"
      using assms hcomp_char not_arr_null by auto

    lemma hcomp_eqI' [intro]:
    assumes "hseq f g" and "f = f'" and "g = g'"
    shows "f B g = f'  g'"
      using assms hcomp_char not_arr_null by auto

    lemma arr_compI:
    assumes "seq f g"
    shows "arr (f B g)"
      using assms seq_charSbC dom_charSbC cod_charSbC
      by (metis (no_types, lifting) comp_simp)

    lemma arr_hcompI:
    assumes "hseq f g"
    shows "arr (f B g)"
      using assms hseq_char src_def trg_def hcomp_eqI' by auto

  end

  sublocale subbicategory  bicategory (⋅) (⋆) 𝖺 𝗂 src trg
    using is_bicategory by auto

  subsection "The Sub-bicategory of Endo-arrows of an Object"

  text ‹
    We now consider the sub-bicategory consisting of all arrows having the same
    object a› both as their source and their target and we show that the resulting structure
    is a monoidal category.  We actually prove a slightly more general result,
    in which the unit of the monoidal category is taken to be an arbitrary isomorphism
    «ω : w ⋆B w ⇒ w»› with w› isomorphic to a›, rather than the particular choice
    «𝗂[a] : a ⋆B a ⇒ a»› made by the ambient bicategory.
  ›

  locale subbicategory_at_object =
    B: bicategory V H 𝖺B 𝗂 srcB trgB +
    subbicategory V H 𝖺B 𝗂 srcB trgB λμ. B.arr μ  srcB μ = a  trgB μ = a
  for V :: "'a comp"                 (infixr "B" 55)
  and H :: "'a comp"                 (infixr "B" 55)
  and 𝖺B :: "'a  'a  'a  'a"    ("𝖺B[_, _, _]")
  and 𝗂 :: "'a  'a"                 ("𝗂[_]")
  and srcB :: "'a  'a"
  and trgB :: "'a  'a"
  and a :: "'a"
  and w :: "'a"
  and ω :: "'a" +
  assumes obj_a: "B.obj a"
  and isomorphic_a_w: "B.isomorphic a w"
  and ω_in_vhom: "«ω : w B w  w»"
  and ω_is_iso: "B.iso ω"
  begin

    notation hcomp  (infixr "" 53)

    lemma arr_simps:
    assumes "arr μ"
    shows "src μ = a" and "trg μ = a"
      apply (metis (no_types, lifting) arrE assms src_def)
      by (metis (no_types, lifting) arrE assms trg_def)

    lemma ω_simps [simp]:
    shows "arr ω"
    and "src ω = a" and "trg ω = a"
    and "dom ω = w B w" and "cod ω = w"
      using isomorphic_a_w ω_in_vhom in_hom_charSbC arr_simps by auto

    lemma ide_w:
    shows "B.ide w"
      using isomorphic_a_w B.isomorphic_def by auto

    lemma w_simps [simp]:
    shows "ide w" and "B.ide w"
    and "src w = a" and "trg w = a" and "srcB w = a" and "trgB w = a"
    and "dom w = w" and "cod w = w"
    proof -
      show w: "ide w"
        using ω_in_vhom ide_cod by blast
      show "B.ide w"
        using w ide_charSbC by simp
      obtain φ where φ: "«φ : a B w»  B.iso φ"
        using isomorphic_a_w B.isomorphic_def by auto
      show "srcB w = a"
        using obj_a w φ B.src_cod by force
      show "trgB w = a"
        using obj_a w φ B.src_cod by force
      show "src w = a"
        using srcB w = a w ide_w src_def by simp
      show "trg w = a"
        using srcB w = a w ide_w trg_def
        by (simp add: trgB w = a)
      show "dom w = w"
        using w by simp
      show "cod w = w"
        using w by simp
    qed

    lemma VxV_arr_eq_VV_arr:
    shows "VxV.arr f  VV.arr f"
      using inclusion VxV.arr_char VV.arr_charSbC arr_charSbC src_def trg_def
      by auto

    lemma VxV_comp_eq_VV_comp:
    shows "VxV.comp = VV.comp"
    proof -
      have "f g. VxV.comp f g = VV.comp f g"
      proof -
        fix f g
        show "VxV.comp f g = VV.comp f g"
          unfolding VV.comp_def
          using VxV.comp_char arr_simps(1) arr_simps(2)
          apply (cases "seq (fst f) (fst g)", cases "seq (snd f) (snd g)")
          by (elim seqE) auto
      qed
      thus ?thesis by blast
    qed

    lemma VxVxV_arr_eq_VVV_arr:
    shows "VxVxV.arr f  VVV.arr f"
      using VVV.arr_charSbC VV.arr_charSbC src_def trg_def inclusion arr_charSbC
      by auto

    lemma VxVxV_comp_eq_VVV_comp:
    shows "VxVxV.comp = VVV.comp"
    proof -
      have "f g. VxVxV.comp f g = VVV.comp f g"
      proof -
        fix f g
        show "VxVxV.comp f g = VVV.comp f g"
        proof (cases "VxVxV.seq f g")
          assume 1: "¬ VxVxV.seq f g"
          have "VxVxV.comp f g = VxVxV.null"
            using 1 VxVxV.ext by blast
          also have "... = (null, null, null)"
            using VxVxV.null_char VxV.null_char by simp
          also have "... = VVV.null"
            using VVV.null_char VV.null_char by simp
          also have "... = VVV.comp f g"
          proof -
            have "¬ VVV.seq f g"
              using 1 VVV.seq_charSbC by blast
            thus ?thesis
              by (metis (no_types, lifting) VVV.ext)
          qed
          finally show ?thesis by simp
          next
          assume 1: "VxVxV.seq f g"
          have 2: "B.arr (fst f)  B.arr (fst (snd f))  B.arr (snd (snd f)) 
                srcB (fst f) = a  srcB (fst (snd f)) = a  srcB (snd (snd f)) = a 
                trgB (fst f) = a  trgB (fst (snd f)) = a  trgB (snd (snd f)) = a"
            using 1 VxVxV.seq_char VxV.seq_char arr_charSbC by blast
          have 3: "B.arr (fst g)  B.arr (fst (snd g))  B.arr (snd (snd g)) 
                   srcB (fst g) = a  srcB (fst (snd g)) = a  srcB (snd (snd g)) = a 
                   trgB (fst g) = a  trgB (fst (snd g)) = a  trgB (snd (snd g)) = a"
            using 1 VxVxV.seq_char VxV.seq_char arr_charSbC by blast
          have 4: "B.seq (fst f) (fst g)  B.seq (fst (snd f)) (fst (snd g)) 
                   B.seq (snd (snd f)) (snd (snd g))"
            using 1 VxVxV.seq_char VxV.seq_char seq_charSbC by blast
          have 5: "VxVxV.comp f g =
                   (fst f  fst g, fst (snd f)  fst (snd g), snd (snd f)  snd (snd g))"
            using 1 2 3 4 VxVxV.seqEPC VxVxV.comp_char VxV.comp_char seq_charSbC arr_charSbC
            by (metis (no_types, lifting)) 
          also have "... = VVV.comp f g"
            using 1 VVV.comp_char VVV.arr_charSbC VV.arr_charSbC
            apply simp
            using 2 3 5 arrISbC arr_simps(1) arr_simps(2) by presburger
          finally show ?thesis by blast
        qed
      qed
      thus ?thesis by blast
    qed
 
    interpretation H: "functor" VxV.comp (⋅) λμν. fst μν  snd μν
      using H.functor_axioms hcomp_def VxV_comp_eq_VV_comp by simp

    interpretation H: binary_endofunctor (⋅) λμν. fst μν  snd μν ..

    lemma HoHV_eq_ToTC:
    shows "HoHV = H.ToTC"
      using HoHV_def H.ToTC_def VVV.arr_charSbC VV.arr_charSbC src_def trg_def inclusion arr_charSbC
      by auto

    lemma HoVH_eq_ToCT:
    shows "HoVH = H.ToCT"
      using HoVH_def H.ToCT_def VVV.arr_charSbC VV.arr_charSbC src_def trg_def inclusion arr_charSbC
      by auto

    interpretation ToTC: "functor" VxVxV.comp (⋅) H.ToTC
      using HoHV_eq_ToTC VxVxV_comp_eq_VVV_comp HoHV.functor_axioms by simp
    interpretation ToCT: "functor" VxVxV.comp (⋅) H.ToCT
      using HoVH_eq_ToCT VxVxV_comp_eq_VVV_comp HoVH.functor_axioms by simp

    interpretation α: natural_isomorphism VxVxV.comp (⋅) H.ToTC H.ToCT α
      unfolding α_def
      using α.natural_isomorphism_axioms HoHV_eq_ToTC HoVH_eq_ToCT α_def
            VxVxV_comp_eq_VVV_comp
      by simp

    interpretation L: endofunctor (⋅) λf. fst (w, f)  snd (w, f)
    proof
      fix f
      show "¬ arr f  fst (w, f)  snd (w, f) = null"
        using arr_charSbC hcomp_def by auto
      assume f: "arr f"
      show "hseq (fst (w, f)) (snd (w, f))"
        using f hseq_char arr_charSbC src_def trg_def ω_in_vhom cod_charSbC by simp
      show "dom (fst (w, f)  snd (w, f)) = fst (w, dom f)  snd (w, dom f)"
        using f arr_charSbC hcomp_def dom_simp by simp
      show "cod (fst (w, f)  snd (w, f)) = fst (w, cod f)  snd (w, cod f)"
        using f arr_charSbC hcomp_def cod_simp by simp
      next
      fix f g
      assume fg: "seq g f"
      show "fst (w, g  f)  snd (w, g  f) = (fst (w, g)  snd (w, g))  (fst (w, f)  snd (w, f))"
        by (simp add: fg whisker_left)
    qed

    interpretation L': equivalence_functor (⋅) (⋅) λf. fst (w, f)  snd (w, f)
    proof -
      obtain φ where φ: "«φ : w B a»  B.iso φ"
        using isomorphic_a_w B.isomorphic_symmetric by force
      have "«φ : w  a»"
        using φ in_hom_charSbC
        by (metis (no_types, lifting) B.in_homE B.src_cod B.src_src B.trg_cod B.trg_trg
            ω_in_vhom arr_charSbC arr_cod cod_simp)
      hence φ: "«φ : w B a»  B.iso φ  «φ : w  a»  iso φ"
        using φ iso_charSbC arr_charSbC by auto
      interpret 𝗅: natural_isomorphism (⋅) (⋅)
                     λf. fst (w, f)  snd (w, f) map λf. 𝔩 f  (φ  dom f)
      proof
        fix μ
        show "¬ arr μ  𝔩 μ  (φ  dom μ) = null"
          using φ arr_charSbC dom_charSbC ext
          apply simp
          using null_is_zero(2) hcomp_def by fastforce
        assume μ: "arr μ"
        have 0: "in_hhom (dom μ) a a"
          using μ arr_charSbC src_dom trg_dom src_def trg_def dom_simp by simp
        have 1: "in_hhom φ a a"
          using φ arr_charSbC src_dom trg_dom src_def trg_def by auto
        have 2: "hseq φ (B.dom μ)"
          using μ 0 1 dom_simp by (intro hseqI) auto
        have 3: "seq (𝔩 μ) (φ  dom μ)"
        proof (intro seqI')
          show "«φ  dom μ : w  dom μ  a  dom μ»"
            by (metis (no_types, lifting) 0 μ φ hcomp_in_vhom ide_dom ide_in_hom(2)
                in_hhom_def w_simps(3))
          show "«𝔩 μ : a  dom μ  cod μ»"
            using μ 2 𝔩.preserves_hom [of μ "dom μ" "cod μ"] arr_simps(2) arr_cod by fastforce
        qed
        show "dom (𝔩 μ  (φ  dom μ)) = fst (w, dom μ)  snd (w, dom μ)"
        proof -
          have "dom (𝔩 μ  (φ  dom μ)) = dom φ  dom μ"
            using μ 3 hcomp_simps(3) dom_comp dom_dom
            apply (elim seqE) by auto
          also have "... = fst (w, dom μ)  snd (w, dom μ)"
            using ω_in_vhom φ
            by (metis (no_types, lifting) in_homE prod.sel(1) prod.sel(2))
          finally show ?thesis by simp
        qed
        show "cod (𝔩 μ  (φ  dom μ)) = map (cod μ)"
        proof -
          have "seq (𝔩 μ) (φ  dom μ)"
            using 3 by simp
          hence "cod (𝔩 μ  (φ  dom μ)) = cod (𝔩 μ)"
            using cod_comp by blast
          also have "... = map (cod μ)"
            using μ by blast
          finally show ?thesis by blast
        qed
        show "map μ  𝔩 (dom μ)  (φ  dom (dom μ)) = 𝔩 μ  (φ  dom μ)"
        proof -
          have "map μ  𝔩 (dom μ)  (φ  dom (dom μ)) = (map μ  𝔩 (dom μ))  (φ  dom μ)"
            using μ comp_assoc by simp
          also have "... = 𝔩 μ  (φ  dom μ)"
            using μ φ 𝔩.is_natural_1 by auto
          finally show ?thesis by blast
        qed
        show "(𝔩 (cod μ)  (φ  dom (cod μ)))  (fst (w, μ)  snd (w, μ)) = 𝔩 μ  (φ  dom μ)"
        proof -
          have "(𝔩 (cod μ)  (φ  dom (cod μ)))  (fst (w, μ)  snd (w, μ)) =
                (𝔩 (cod μ)  (φ  B.cod μ))  (w  μ)"
            using μ φ dom_charSbC arr_charSbC ω_in_vhom cod_simp by simp
          also have "... = 𝔩 (cod μ)  (φ  w  B.cod μ  μ)"
          proof -
            have "seq φ w"
              using φ ω_in_vhom w_simps(1) by blast
            moreover have 2: "seq (B.cod μ) μ"
              using μ seq_charSbC cod_simp by (simp add: comp_cod_arr)
            moreover have "src φ = trg (B.cod μ)"
              using μ φ 2
              by (metis (no_types, lifting) arr_simps(2) seqE vconn_implies_hpar(1) w_simps(3))
            ultimately show ?thesis
              using interchange comp_assoc by simp
          qed
          also have "... = 𝔩 (cod μ)  (φ  μ)"
            using μ φ ω_in_vhom comp_arr_dom comp_cod_arr cod_simp
            apply (elim conjE in_homE) by auto
          also have "... = (𝔩 (cod μ)  (cod φ  μ))  (φ  dom μ)"
          proof -
            have 1: "seq (cod φ) φ"
              using φ arr_cod_iff_arr dom_cod iso_is_arr seqI by presburger
            moreover have 2: "seq μ (dom μ)"
              using μ by (simp add: comp_arr_dom)
            moreover have "src (cod φ) = trg μ"
              using μ φ arr_cod arr_simps(1-2) iso_is_arr by auto
            ultimately show ?thesis
              using 1 2 interchange [of "cod φ" φ μ "dom μ"] comp_arr_dom comp_cod_arr
                    comp_assoc by fastforce
          qed
          also have "... = 𝔩 μ  (φ  dom μ)"
          proof -
            have "L μ = cod φ  μ"
              using μ φ arr_simps(2) in_homE by auto
            hence "𝔩 (cod μ)  (cod φ  μ) = 𝔩 μ"
              using μ 𝔩.is_natural_2 [of μ] by simp
            thus ?thesis by simp
          qed
          finally show ?thesis by simp
        qed
        next
        show "f. ide f  iso (𝔩 f  (φ  dom f))"
        proof -
          fix f
          assume f: "ide f"
          have "iso (𝔩 f)"
            using f iso_lunit by simp
          moreover have "iso (φ  dom f)"
            using φ f src_def trg_def ide_charSbC arr_charSbC
            apply (intro iso_hcomp, simp_all)
            by (metis (no_types, lifting) in_homE)
          moreover have "seq (𝔩 f) (φ  dom f)"
          proof (intro seqI')
            show " «𝔩 f : a  f  f»"
              using f lunit_in_hom(2) 𝔩_ide_simp ide_charSbC arr_charSbC trg_def by simp
            show "«φ  dom f : w  f  a  f»"
              using φ f ide_charSbC arr_charSbC hcomp_def src_def trg_def obj_a ide_in_hom
                    in_hom_charSbC
              by (intro hcomp_in_vhom, auto)
          qed
          ultimately show "iso (𝔩 f  (φ  dom f))"
            using isos_compose by simp
        qed
      qed
      show "equivalence_functor (⋅) (⋅) (λf. fst (w, f)  snd (w, f))"
        using 𝗅.natural_isomorphism_axioms L.isomorphic_to_identity_is_equivalence by simp
    qed
    interpretation L: equivalence_functor (⋅) (⋅) λf. fst (cod ω, f)  snd (cod ω, f)
    proof -
      have "(λf. fst (cod ω, f)  snd (cod ω, f)) = (λf. fst (w, f)  snd (w, f))"
        using ω_in_vhom by simp
      thus "equivalence_functor (⋅) (⋅) (λf. fst (cod ω, f)  snd (cod ω, f))"
        using L'.equivalence_functor_axioms by simp
    qed

    interpretation R: endofunctor (⋅) λf. fst (f, w)  snd (f, w)
    proof
      fix f
      show "¬ arr f  fst (f, w)  snd (f, w) = null"
        using arr_charSbC hcomp_def by auto
      assume f: "arr f"
      show "hseq (fst (f, w)) (snd (f, w))"
        using f hseq_char arr_charSbC src_def trg_def ω_in_vhom cod_charSbC isomorphic_a_w
              B.isomorphic_def in_hom_charSbC
        by simp
      show "dom (fst (f, w)  snd (f, w)) = fst (dom f, w)  snd (dom f, w)"
        using f arr_charSbC dom_charSbC cod_charSbC hcomp_def ω_in_vhom by simp
      show "cod (fst (f, w)  snd (f, w)) = fst (cod f, w)  snd (cod f, w)"
        using f arr_charSbC dom_charSbC cod_charSbC hcomp_def ω_in_vhom by simp
      next
      fix f g
      assume fg: "seq g f"
      have 1: "a B a = a"
        using obj_a by auto
      show "fst (g  f, w)  snd (g  f, w) = (fst (g, w)  snd (g, w))  (fst (f, w)  snd (f, w))"
        by (simp add: fg whisker_right)
    qed

    interpretation R': equivalence_functor (⋅) (⋅) λf. fst (f, w)  snd (f, w)
    proof -
      obtain φ where φ: "«φ : w B a»  B.iso φ"
        using isomorphic_a_w B.isomorphic_symmetric by force
      have "«φ : w  a»"
        using φ in_hom_charSbC
        by (metis (no_types, lifting) B.in_homE B.src_cod B.src_src B.trg_cod B.trg_trg
            ω_in_vhom arr_charSbC arr_cod cod_simp)
      hence φ: "«φ : w B a»  B.iso φ  «φ : w  a»  iso φ"
        using φ iso_charSbC arr_charSbC by auto
      interpret 𝗋: natural_isomorphism comp comp
                     λf. fst (f, w)  snd (f, w) map λf. 𝔯 f  (dom f  φ)
      proof
        fix μ
        show "¬ arr μ  𝔯 μ  (dom μ  φ) = null"
          using φ arr_charSbC dom_charSbC ext
          apply simp
          using null_is_zero(2) hcomp_def by fastforce
        assume μ: "arr μ"
        have 0: "in_hhom (dom μ) a a"
          using μ arr_charSbC src_dom trg_dom src_def trg_def dom_simp by simp
        have 1: "in_hhom φ a a"
          using φ arr_charSbC src_dom trg_dom src_def trg_def by auto
        have 2: "hseq (B.dom μ) φ"
          using μ 0 1 dom_simp hseqI by auto
        have 3: "seq (𝔯 μ) (dom μ  φ)"
        proof (intro seqI')
          show "«dom μ  φ : dom μ  w  dom μ  a»"
            by (metis (no_types, lifting) "0" "1" μ φ hcomp_in_vhom hseqI hseq_char
                ide_dom ide_in_hom(2) vconn_implies_hpar(2))
          show "«𝔯 μ : dom μ  a  cod μ»"
            using μ 2 𝔯.preserves_hom [of μ "dom μ" "cod μ"] arr_simps(2) arr_cod
                  dom_simp cod_simp
            by fastforce
        qed
        show "dom (𝔯 μ  (dom μ  φ)) = fst (dom μ, w)  snd (dom μ, w)"
        proof -
          have "dom (𝔯 μ  (dom μ  φ)) = dom μ  dom φ"
            using μ 3 hcomp_simps(3) dom_comp dom_dom
            apply (elim seqE) by auto
          also have "... = fst (dom μ, w)  snd (dom μ, w)"
            using ω_in_vhom φ
            by (metis (no_types, lifting) in_homE prod.sel(1) prod.sel(2))
          finally show ?thesis by simp
        qed
        show "cod (𝔯 μ  (dom μ  φ)) = map (cod μ)"
        proof -
          have "seq (𝔯 μ) (dom μ  φ)"
            using 3 by simp
          hence "cod (𝔯 μ  (dom μ  φ)) = cod (𝔯 μ)"
            using cod_comp by blast
          also have "... = map (cod μ)"
            using μ by blast
          finally show ?thesis by blast
        qed
        show "map μ  𝔯 (dom μ)  (dom (dom μ)  φ) = 𝔯 μ  (dom μ  φ)"
        proof -
          have "map μ  𝔯 (dom μ)  (dom (dom μ)  φ) =
                (map μ  𝔯 (dom μ))  (dom (dom μ)  φ)"
            using comp_assoc by simp
          also have "... = (map μ  𝔯 (dom μ))  (dom μ  φ)"
            using μ dom_dom by simp
          also have "... = 𝔯 μ  (dom μ  φ)"
            using μ φ 𝔯.is_natural_1 by auto
          finally show ?thesis by blast
        qed
        show "(𝔯 (cod μ)  (dom (cod μ)  φ))  (fst (μ, w)  snd (μ, w)) = 𝔯 μ  (dom μ  φ)"
        proof -
          have "(𝔯 (cod μ)  (dom (cod μ)  φ))  (fst (μ, w)  snd (μ, w)) =
                (𝔯 (cod μ)  (B.cod μ  φ))  (μ  w)"
            using μ φ dom_charSbC arr_charSbC ω_in_vhom cod_simp by simp
          also have "... = 𝔯 (cod μ)  (B.cod μ  μ  φ  w)"
          proof -
            have 2: "seq φ w"
              using φ ω_in_vhom w_simps(1) by blast
            moreover have "seq (B.cod μ) μ"
              using μ seq_charSbC cod_simp by (simp add: comp_cod_arr)
            moreover have "src (B.cod μ) = trg φ"
              using μ φ 2
              using arr_simps(1) calculation(2) seq_charSbC vconn_implies_hpar(2) by force
            ultimately show ?thesis
              using interchange comp_assoc by simp
          qed
          also have "... = 𝔯 (cod μ)  (μ  φ)"
            using μ φ ω_in_vhom comp_arr_dom comp_cod_arr cod_simp
            apply (elim conjE in_homE) by auto
          also have "... = (𝔯 (cod μ)  (μ  cod φ))  (dom μ  φ)"
          proof -
            have "(μ  cod φ)  (dom μ  φ) = μ  φ"
            proof -
              have "seq μ (dom μ)"
                using μ by (simp add: comp_arr_dom)
              moreover have "seq (cod φ) φ"
                using φ iso_is_arr arr_cod dom_cod by auto
              moreover have "src μ = trg (cod φ)"
                using μ φ 2
                by (metis (no_types, lifting) arr_simps(1) arr_simps(2) calculation(2) seqE)
              ultimately show ?thesis
                using μ φ iso_is_arr comp_arr_dom comp_cod_arr
                      interchange [of μ "dom μ" "cod φ" φ]
                by simp
            qed
            thus ?thesis
              using comp_assoc by simp
          qed
          also have "... = 𝔯 μ  (dom μ  φ)"
          proof -
            have "μ  cod φ = R μ"
              using μ φ arr_simps(1) in_homE by auto
            hence "𝔯 (cod μ)  (μ  cod φ) = 𝔯 μ"
              using μ φ 𝔯.is_natural_2 by simp
            thus ?thesis by simp
          qed
          finally show ?thesis by simp
        qed
        next
        show "f. ide f  iso (𝔯 f  (dom f  φ))"
        proof -
          fix f
          assume f: "ide f"
          have 1: "iso (𝔯 f)"
            using f iso_lunit by simp
          moreover have 2: "iso (dom f  φ)"
            using φ f src_def trg_def ide_charSbC arr_charSbC
            apply (intro iso_hcomp, simp_all)
            by (metis (no_types, lifting) in_homE)
          moreover have "seq (𝔯 f) (dom f  φ)"
          proof (intro seqI')
            show "«𝔯 f : f  a  f»"
              using f runit_in_hom(2) 𝔯_ide_simp ide_charSbC arr_charSbC src_def by simp
            show "«dom f  φ : f  w  f  a»"
              using φ f ide_charSbC arr_charSbC hcomp_def src_def trg_def obj_a ide_in_hom
                    in_hom_charSbC
              by (intro hcomp_in_vhom, auto)
          qed
          ultimately show "iso (𝔯 f  (dom f  φ))"
            using isos_compose by blast
         qed
      qed
      show "equivalence_functor (⋅) (⋅) (λf. fst (f, w)  snd (f, w))"
        using 𝗋.natural_isomorphism_axioms R.isomorphic_to_identity_is_equivalence by simp
    qed
    interpretation R: equivalence_functor (⋅) (⋅) λf. fst (f, cod ω)  snd (f, cod ω)
    proof -
      have "(λf. fst (f, cod ω)  snd (f, cod ω)) = (λf. fst (f, w)  snd (f, w))"
        using ω_in_vhom by simp
      thus "equivalence_functor (⋅) (⋅) (λf. fst (f, cod ω)  snd (f, cod ω))"
        using R'.equivalence_functor_axioms by simp
    qed

    interpretation M: monoidal_category (⋅) λμν. fst μν  snd μν α ω
    proof
      show "«ω : fst (cod ω, cod ω)  snd (cod ω, cod ω)  cod ω»"
        using ω_in_vhom hcomp_def arr_charSbC by auto
      show "iso ω"
        using ω_is_iso iso_charSbC arr_charSbC inv_charSbC ω_in_vhom by auto
      show "f g h k.  ide f; ide g; ide h; ide k  
                       (fst (f, α (g, h, k))  snd (f, α (g, h, k))) 
                         α (f, hcomp (fst (g, h)) (snd (g, h)), k) 
                         (fst (α (f, g, h), k)  snd (α (f, g, h), k)) =
                       α (f, g, fst (h, k)  snd (h, k))  α (fst (f, g)  snd (f, g), h, k)"
      proof -
        fix f g h k
        assume f: "ide f" and g: "ide g" and h: "ide h" and k: "ide k"
        have 1: "VVV.arr (f, g, h)  VVV.arr (g, h, k)"
          using f g h k VVV.arr_charSbC VV.arr_charSbC src_def trg_def ide_charSbC arr_charSbC
          by simp
        have 2: "VVV.arr (f, g  h, k)"
          using f g h k src_def trg_def ide_charSbC arr_charSbC VxVxV_comp_eq_VVV_comp hseqI'
          by auto
        have 3: "VVV.arr (f, g, h  k)"
          using f g h k 1 VVV.arr_charSbC VV.arr_charSbC src_def trg_def ide_charSbC arr_charSbC
                VxV.arrI VxVxV.arrI VxVxV_comp_eq_VVV_comp H.preserves_reflects_arr hseqI'
          by auto
        have 4: "VVV.arr (f  g, h, k)"
          using f g h k src_def trg_def ide_charSbC arr_charSbC hseq_char VxVxV_comp_eq_VVV_comp
          by auto
        have "(fst (f, α (g, h, k))  snd (f, α (g, h, k))) 
                α (f, fst (g, h)  snd (g, h), k) 
                (fst (α (f, g, h), k)  snd (α (f, g, h), k)) =
              (f  𝖺B[g, h, k])  𝖺B[f, g  h, k]  (𝖺B[f, g, h]  k)"
          unfolding α_def by (simp add: 1 2)
        also have "... = (f B 𝖺B g h k)  𝖺B f (g B h) k  (𝖺B f g h B k)"
          unfolding hcomp_def
          using f g h k src_def trg_def arr_charSbC
          using assoc_closed ide_charSbC by auto
        also have "... = (f B 𝖺B g h k) B 𝖺B f (g B h) k B (𝖺B f g h B k)"
        proof -
          have "arr (f B 𝖺B g h k)"
            using ide_charSbC arr_charSbC assoc_closed f g h hcomp_closed k by simp
          moreover have "arr (𝖺B f (g B h) k)"
            using ide_charSbC arr_charSbC assoc_closed f g h hcomp_closed k by simp
          moreover have "arr (𝖺B f g h B k)"
            using ide_charSbC arr_charSbC assoc_closed f g h hcomp_closed k by simp
          moreover have "arr (𝖺B f (g B h) k B (𝖺B f g h B k))"
            unfolding arr_charSbC
            apply (intro conjI)
            using ide_charSbC arr_charSbC assoc_closed f g h hcomp_closed k B.HoHV_def B.HoVH_def
            apply (intro B.seqI)
                apply simp_all
          proof -
            have 1: "B.arr (𝖺B f (g B h) k B 𝖺B f g h B k)"
              using f g h k ide_charSbC arr_charSbC B.HoHV_def B.HoVH_def
              apply (intro B.seqI)
              by auto
            show "srcB (𝖺B f (g B h) k B 𝖺B f g h B k) = a"
              using 1 f g h k arr_charSbC B.src_vcomp B.vseq_implies_hpar(1) by fastforce
            show "trgB (𝖺B f (g B h) k B 𝖺B f g h B k) = a"
              using "1" arr_charSbC calculation(2-3) by auto
          qed
          ultimately show ?thesis
            using B.ext comp_char by (metis (no_types, lifting))
        qed
        also have "... = 𝖺B f g (h B k) B 𝖺B (f B g) h k"
          using f g h k src_def trg_def arr_charSbC ide_charSbC B.pentagon
          using "4" α_def hcomp_def by auto
        also have "... = 𝖺B f g (h B k)  𝖺B (f B g) h k"
        proof -
          have "arr (𝖺B (f B g) h k)"
            using ide_charSbC arr_charSbC assoc_closed f g h hcomp_closed k by simp
          moreover have "arr (𝖺B f g (h B k))"
            using ide_charSbC arr_charSbC assoc_closed f g h hcomp_closed k by fastforce
          ultimately show ?thesis
            using B.ext comp_char by auto
        qed
        also have "... = 𝖺B[f, g, fst (h, k)  snd (h, k)]  𝖺B[fst (f, g)  snd (f, g), h, k]"
          unfolding hcomp_def
          using f g h k src_def trg_def arr_charSbC ide_charSbC by simp
        also have "... = α (f, g, fst (h, k)  snd (h, k))  α (fst (f, g)  snd (f, g), h, k)"
          unfolding α_def using 1 2 3 4 by simp
        finally show "(fst (f, α (g, h, k))  snd (f, α (g, h, k))) 
                        α (f, fst (g, h)  snd (g, h), k) 
                        (fst (α (f, g, h), k)  snd (α (f, g, h), k)) =
                      α (f, g, fst (h, k)  snd (h, k))  α (fst (f, g)  snd (f, g), h, k)"
          by simp
      qed
    qed

    proposition is_monoidal_category:
    shows "monoidal_category (⋅) (λμν. fst μν  snd μν) α ω"
      ..

  end

  text ‹
    In a bicategory, the ``objects'' are essentially arbitrarily chosen representatives
    of their isomorphism classes.  Choosing any other representatives results in an
    equivalent structure.  Each object a› is additionally equipped with an arbitrarily chosen
    unit isomorphism «ι : a ⋆ a ⇒ a»›.  For any (a, ι)› and (a', ι')›,
    where a› and a'› are isomorphic to the same object, there exists a unique isomorphism
    «ψ: a ⇒ a'»› that is compatible with the chosen unit isomorphisms ι› and ι'›.
    We have already proved this property for monoidal categories, which are bicategories
    with just one ``object''.  Here we use that already-proven property to establish its
    generalization to arbitary bicategories, by exploiting the fact that if a› is an object
    in a bicategory, then the sub-bicategory consisting of all μ› such that
    src μ = a = trg μ›, is a monoidal category.

    At some point it would potentially be nicer to transfer the proof for monoidal
    categories to obtain a direct, ``native'' proof of this fact for bicategories.
  ›

  lemma (in bicategory) unit_unique_upto_unique_iso:
  assumes "obj a"
  and "isomorphic a w"
  and "«ω : w  w  w»"
  and "iso ω"
  shows "∃!ψ. «ψ : a  w»  iso ψ  ψ  𝗂[a] = ω  (ψ  ψ)"
  proof -
    have ω_in_hhom: "«ω : a  a»"
      using assms
      apply (intro in_hhomI)
        apply auto
       apply (metis src_cod in_homE isomorphic_implies_hpar(3) objE)
      by (metis trg_cod in_homE isomorphic_implies_hpar(4) objE)
    interpret S: subbicategory V H 𝖺 𝗂 src trg λμ. arr μ  src μ = a  trg μ = a
      using assms iso_unit in_homE isoE isomorphicE VVV.arr_charSbC VV.arr_charSbC
      apply unfold_locales
                 apply auto[7]
    proof
      fix f g h
      assume f: "(arr f  src f = a  trg f = a)  ide f"
      and g: "(arr g  src g = a  trg g = a)  ide g"
      and h: "(arr h  src h = a  trg h = a)  ide h"
      and fg: "src f = trg g" and gh: "src g = trg h"
      show "arr (𝖺[f, g, h])"
        using assms f g h fg gh by auto
      show "src (𝖺[f, g, h]) = a  trg (𝖺[f, g, h]) = a"
        using assms f g h fg gh by auto
      show "arr (inv (𝖺[f, g, h]))  src (inv (𝖺[f, g, h])) = a  trg (inv (𝖺[f, g, h])) = a"
        using assms f g h fg gh α.preserves_hom src_dom trg_dom by simp
      next
      fix f
      assume f: "arr f  src f = a  trg f = a"
      assume ide_left: "ide f"
      show "arr (𝔩 f)  src (𝔩 f) = a  trg (𝔩 f) = a"
        using f assms(1) 𝔩.preserves_hom src_cod [of "𝔩 f"] trg_cod [of "𝔩 f"] by simp
      show "arr (inv (𝔩 f))  src (inv (𝔩 f)) = a  trg (inv (𝔩 f)) = a"
        using f ide_left assms(1) 𝔩'.preserves_hom src_dom [of "𝔩'.map f"] trg_dom [of "𝔩'.map f"]
        by simp
      show "arr (𝔯 f)  src (𝔯 f) = a  trg (𝔯 f) = a"
        using f assms(1) 𝔯.preserves_hom src_cod [of "𝔯 f"] trg_cod [of "𝔯 f"] by simp
      show "arr (inv (𝔯 f))  src (inv (𝔯 f)) = a  trg (inv (𝔯 f)) = a"
        using f ide_left assms(1) 𝔯'.preserves_hom src_dom [of "𝔯'.map f"] trg_dom [of "𝔯'.map f"]
        by simp
    qed
    interpret S: subbicategory_at_object V H 𝖺 𝗂 src trg a a 𝗂[a]
    proof
      show "obj a" by fact
      show "isomorphic a a"
        using assms(1) isomorphic_reflexive by blast
      show "S.in_hom 𝗂[a] (a  a) a"
        using S.arr_charSbC S.in_hom_charSbC assms(1) by fastforce
      show "iso 𝗂[a]"
        using assms iso_unit by simp
    qed
    interpret Sω: subbicategory_at_object V H 𝖺 𝗂 src trg a w ω
    proof
      show "obj a" by fact
      show "iso ω" by fact
      show "isomorphic a w"
        using assms by simp
      show "S.in_hom ω (w  w) w"
        using assms S.arr_charSbC S.dom_charSbC S.cod_charSbC ω_in_hhom
        by (intro S.in_homI, auto)
    qed
    interpret M: monoidal_category S.comp λμν. S.hcomp (fst μν) (snd μν) S.α 𝗂[a]
      using S.is_monoidal_category by simp
    interpret Mω: monoidal_category S.comp λμν. S.hcomp (fst μν) (snd μν) S.α ω
      using Sω.is_monoidal_category by simp
    interpret M: monoidal_category_with_alternate_unit
                   S.comp λμν. S.hcomp (fst μν) (snd μν) S.α 𝗂[a] ω ..
    have 1: "Mω.unity = w"
      using assms S.cod_charSbC S.arr_charSbC
      by (metis (no_types, lifting) S.in_homE Sω.ω_in_vhom)
    have 2: "M.unity = a"
      using assms S.cod_charSbC S.arr_charSbC by simp
    have "∃!ψ. S.in_hom ψ a w  S.iso ψ  S.comp ψ 𝗂[a] = S.comp ω (M.tensor ψ ψ)"
      using assms 1 2 M.unit_unique_upto_unique_iso S.cod_charSbC
      by simp
    show "∃!ψ. «ψ : a  w»  iso ψ  ψ  𝗂[a] = ω  (ψ  ψ)"
    proof -
      have 1: "ψ. S.in_hom ψ a w  «ψ : a  w»"
        using assms S.in_hom_charSbC S.arr_charSbC
        by (metis (no_types, lifting) S.ideD(1) S.w_simps(1) Sω.w_simps(1) in_homE
            src_dom trg_dom)
      moreover have "ψ. S.in_hom ψ a w  S.iso ψ  iso ψ"
        using assms S.in_hom_charSbC S.arr_charSbC S.iso_charSbC by auto
      moreover have "ψ. S.in_hom ψ a w  M.tensor ψ ψ = ψ  ψ"
        using assms S.in_hom_charSbC S.arr_charSbC S.hcomp_def by simp
      moreover have "ψ. S.in_hom ψ a w  S.comp ψ 𝗂[a] = ψ  𝗂[a]"
        using assms S.in_hom_charSbC S.comp_char by auto
      moreover have "ψ. S.in_hom ψ a w  S.comp ω (M.tensor ψ ψ) = ω  (ψ  ψ)"
        using assms S.in_hom_charSbC S.arr_charSbC S.hcomp_def S.comp_char S.dom_charSbC S.cod_charSbC
        by (metis (no_types, lifting) Mω.arr_tensor Sω.ω_simps(1) calculation(3) ext)
      ultimately show ?thesis
        by (metis (no_types, lifting) M.unit_unique_upto_unique_iso S.ω_in_vhom S.in_homE
            Sω.ω_in_vhom)
    qed
  qed

end