open import Cat.Functor.Properties
open import Cat.Prelude hiding (injective)

import Cat.Functor.Reasoning as Fr
import Cat.Reasoning
module
  Cat.Functor.Reasoning.FullyFaithful
  {o β„“ o' β„“'} {C : Precategory o β„“} {D : Precategory o' β„“'}
  (F : Functor C D) (ff : is-fully-faithful F)
  where

Reasoning for ff functorsπŸ”—

This module contains a few short combinators for reasoning about the actions of fully faithful functors on morphisms and isomorphisms.

open Fr F public
private
  module C = Cat.Reasoning C
  module D = Cat.Reasoning D

private variable
  a b c d : C.Ob
  Ξ± Ξ² Ξ³ Ξ΄ : D.Ob
  f g g' h i : C.Hom a b
  w x x' y z : D.Hom Ξ± Ξ²

module _ {a} {b} where
  open Equiv (F₁ {a} {b} , ff) public

invertible-equiv
  : βˆ€ {a b} {f : C.Hom a b}
  β†’ C.is-invertible f ≃ D.is-invertible (F₁ f)
invertible-equiv {f = f} =
  prop-ext! F-map-invertible (is-ff→is-conservative F ff f)

iso-equiv : βˆ€ {a b} β†’ (a C.β‰… b) ≃ (Fβ‚€ a D.β‰… Fβ‚€ b)
iso-equiv {a} {b} = (F-map-iso {x = a} {b} , is-ff→F-map-iso-is-equiv {F = F} ff)

module invertible {a} {b} {f : C.Hom a b} =
  Equiv (invertible-equiv {f = f})

module iso {a} {b} =
  Equiv (F-map-iso {x = a} {b} , is-ff→F-map-iso-is-equiv {F = F} ff)
fromn't : w ≑ F₁ f β†’ from w ≑ f
fromn't p = ap from p βˆ™ Ξ· _

from-id : (w ≑ D.id) ≃ (from w ≑ C.id)
from-id = ap-equiv ((F₁ , ff) e⁻¹) βˆ™e βˆ™-post-equiv (injectiveβ‚‚ (Ξ΅ D.id) F-id)

to-id : (f ≑ C.id) ≃ (F₁ f ≑ D.id)
to-id = ap-equiv (F₁ , ff) βˆ™e id-equivr

module from-id {Ξ±} {w : D.Hom (Fβ‚€ Ξ±) (Fβ‚€ Ξ±)} = Equiv (from-id {w = w})
module to-id {a} {f : C.Hom a a} = Equiv (to-id {f = f})

from-∘ : from (w D.∘ x) ≑ from w C.∘ from x
from-∘ = injective (Ξ΅ _ βˆ™ sym (F-∘ _ _ βˆ™ apβ‚‚ D._∘_ (Ξ΅ _) (Ξ΅ _)))

ipushr : x D.∘ F₁ g ≑ x' β†’ from (w D.∘ x) C.∘ g ≑ from (w D.∘ x')
ipushr p = injective (F-∘ _ _ βˆ™βˆ™ apβ‚‚ D._∘_ (Ξ΅ _) refl βˆ™βˆ™ D.pullr p βˆ™ sym (Ξ΅ _))

Ξ΅-lswizzle : w D.∘ x ≑ D.id β†’ w D.∘ F₁ (from (x D.∘ y)) ≑ y
Ξ΅-lswizzle = D.lswizzle (Ξ΅ _)

Ξ΅-expand : w D.∘ x ≑ y β†’ F₁ (from w C.∘ from x) ≑ y
Ξ΅-expand p = F-∘ _ _ βˆ™βˆ™ apβ‚‚ D._∘_ (Ξ΅ _) (Ξ΅ _) βˆ™βˆ™ p

Ξ΅-twist : F₁ f D.∘ x ≑ y D.∘ F₁ g β†’ f C.∘ from x ≑ from y C.∘ g
Ξ΅-twist {f = f} {g = g} p = injective $ swap $
  ap (F₁ f D.∘_) (Ξ΅ _) βˆ™βˆ™ p βˆ™βˆ™ ap (D._∘ F₁ g) (sym (Ξ΅ _))

inv∘l : x D.∘ F₁ f ≑ y β†’ from x C.∘ f ≑ from y
inv∘l x = sym (Ξ΅-twist (D.eliml F-id βˆ™ sym x)) βˆ™ C.idl _

whackl : x D.∘ F₁ f ≑ F₁ g β†’ from x C.∘ f ≑ g
whackl p = sym (Ξ΅-twist (D.idr _ βˆ™ sym p)) βˆ™ C.elimr (from-id.to refl)

whackr : F₁ f D.∘ x ≑ F₁ g β†’ f C.∘ from x ≑ g
whackr p = Ξ΅-twist (p βˆ™ sym (D.idl _)) βˆ™ C.eliml (from-id.to refl)

pouncer : F₁ f D.∘ x ≑ z β†’ f C.∘ from x ≑ from z
pouncer p = Ξ΅-twist (p βˆ™ intror refl) βˆ™ C.idr _

Ξ·-expand : f C.∘ g ≑ h β†’ from (F₁ f D.∘ F₁ g) ≑ h
Ξ·-expand p = from-∘ βˆ™βˆ™ apβ‚‚ C._∘_ (Ξ· _) (Ξ· _) βˆ™βˆ™ p

Ξ·-twist : from x C.∘ f ≑ g C.∘ from y β†’ x D.∘ F₁ f ≑ F₁ g D.∘ y
Ξ·-twist {x = x} {f = f} {g = g} {y = y} p =
 x D.∘ F₁ f                  β‰‘Λ˜βŸ¨ Ξ΅-expand refl      ⟩
 F₁ (from x C.∘ from (F₁ f)) β‰‘βŸ¨  ⟨ C.refl⟩∘⟨ Ξ· _ ⟩  ⟩
 F₁ (from x C.∘ f)           β‰‘βŸ¨  ⟨ p             ⟩  ⟩
 F₁ (g C.∘ from y)           β‰‘Λ˜βŸ¨ ⟨ Ξ· _ C.⟩∘⟨refl ⟩  ⟩
 F₁ (from (F₁ g) C.∘ from y) β‰‘βŸ¨  Ξ΅-expand refl      ⟩
 F₁ g D.∘ y                  ∎

unwhackr : f C.∘ from w ≑ g β†’ F₁ f D.∘ w ≑ F₁ g
unwhackr {f = f} {w = w} p = sym (Ξ·-twist $ C.idr _ βˆ™βˆ™ Ξ· _ βˆ™βˆ™ sym p) βˆ™ elimr refl

Lifting ShapesπŸ”—

module _ {f : C.Hom b c} {g : C.Hom a b} {h : C.Hom a c} where

  triangle-equivl : (F₁ f D.∘ F₁ g ≑ F₁ h) ≃ (f C.∘ g ≑ h)
  triangle-equivl =
    F₁ f D.∘ F₁ g ≑ F₁ h
      β‰ƒΛ˜βŸ¨ βˆ™-pre-equiv (sym (F-∘ f g)) ⟩
    F₁ (f C.∘ g) ≑ F₁ h
      β‰ƒΛ˜βŸ¨ ap-equiv (F₁ , ff) ⟩
    f C.∘ g ≑ h β‰ƒβˆŽ

  module triangle-equivl = Equiv triangle-equivl