open import Cat.Displayed.Cartesian.Discrete
open import Cat.Displayed.Functor
open import Cat.Displayed.Base
open import Cat.Prelude

import Cat.Displayed.Cartesian
import Cat.Displayed.Reasoning
import Cat.Displayed.Morphism
import Cat.Reasoning
module Cat.Displayed.Cartesian.Right
  {o ℓ o' ℓ'}
  {: Precategory o ℓ}
  (: Displayed ℬ o' ℓ')
  where

open Cat.Reasoning ℬ
open Displayed ℰ
open Cat.Displayed.Cartesian ℰ
open Cat.Displayed.Morphism ℰ
open Cat.Displayed.Reasoning ℰ
open is-fibred-functor

Right fibrations🔗

A cartesian fibration is said to be a right fibration if every morphism in is cartesian.

record Right-fibration : Type (o ⊔ ℓ ⊔ o' ⊔ ℓ') where
  no-eta-equality
  field
    is-fibration : Cartesian-fibration
    cartesian
      :  {x y} {f : Hom x y}
        {x' y'} (f' : Hom[ f ] x' y')
       is-cartesian f f'

  open Cartesian-fibration is-fibration public

One notable fact is every vertical morphism of a right fibrations is invertible. In other words, if is a right fibration, then all of its fibre categories are groupoids. This follows directly from the fact that vertical cartesian maps are invertible.

right-fibration→vertical-invertible
  : Right-fibration
    {x} {x' x'' : Ob[ x ]}  (f' : Hom[ id ] x' x'')  is-invertible↓ f'
right-fibration→vertical-invertible rfib f' =
  vertical+cartesian→invertible (Right-fibration.cartesian rfib f')

More notably, this is an exact characterization of categories fibred in groupoids! If is a cartesian fibration where all vertical morphisms are invertible, then it must be a right fibration.

vertical-invertible+fibration→right-fibration
  : Cartesian-fibration
   (∀ {x} {x' x'' : Ob[ x ]}  (f' : Hom[ id ] x' x'')  is-invertible↓ f')
   Right-fibration
vertical-invertible+fibration→right-fibration fib vert-inv
  .Right-fibration.is-fibration = fib
vertical-invertible+fibration→right-fibration fib vert-inv
  .Right-fibration.cartesian {x = x} {f = f} {x' = x'} {y' = y'} f' = f-cart where
    open Cartesian-fibration fib
    open Cartesian-lift renaming (x' to x-lift)

To see this, recall that cartesian morphisms are stable under vertical retractions. The cartesian lift of is obviously cartesian, so it suffices to show that there is a vertical retraction To construct this retraction, we shall factorize over which yields a vertical morphism By our hypotheses, is invertible, and thus is a retraction. What remains to be shown is that the inverse to factors and this follows from the factorisation of and the fact that is invertible.

    i* : Hom[ id ] x' (f ^* y')
    i* = π*.universal' (idr f) f'

    module i*-inv = is-invertible[_] (vert-inv i*)

    i*⁻¹ : Hom[ id ] (f ^* y') x'
    i*⁻¹ = i*-inv.inv'

    factors : f' ∘' i*⁻¹ ≡[ idr f ] π* f y'
    factors = to-pathp⁻ $
      f' ∘' i*⁻¹                    ≡⟨ shiftr _ (pushl' _ (symP $ π*.commutesp (idr f) f') {q = ap (f ∘_) (sym (idl _))})
      hom[] (π* f y' ∘' i* ∘' i*⁻¹) ≡⟨ weave _ (elimr (idl id)) _ (elimr' _ i*-inv.invl')
      hom[] (π* f y')

    f-cart : is-cartesian f f'
    f-cart = cartesian-vertical-retraction-stable
      π*.cartesian
      (inverses[]→from-has-section[] i*-inv.inverses')
      factors

As a corollary, we get that all discrete fibrations are right fibrations. Intuitively, this is true, as sets are 0-groupoids.

discrete→right-fibration
  : is-discrete-cartesian-fibration ℰ
   Right-fibration
discrete→right-fibration dfib =
  vertical-invertible+fibration→right-fibration
    (discrete→cartesian ℰ dfib)
    (is-discrete-cartesian-fibration.all-invertible↓ dfib)

Fibred functors and right fibrations🔗

As every map in a right fibration is cartesian, every displayed functor into a right fibration is automatically fibred.

functor+right-fibration→fibred
  :  {o₂ ℓ₂ o₂' ℓ₂'}
   {𝒟 : Precategory o₂ ℓ₂}
   {: Displayed 𝒟 o₂' ℓ₂'}
   {F : Functor 𝒟 ℬ}
   Right-fibration
   (F' : Displayed-functor F ℱ ℰ)
   is-fibred-functor F'
functor+right-fibration→fibred rfib F' .F-cartesian {f' = f'} _ =
  Right-fibration.cartesian rfib (F₁' f')
  where
    open Displayed-functor F'

Specifically, this implies that all displayed functors into a discrete fibrations are fibred. This means that we can drop the fibred condition when working with functors between discrete fibrations.

functor+discrete→fibred
  :  {o₂ ℓ₂ o₂' ℓ₂'}
   {𝒟 : Precategory o₂ ℓ₂}
   {: Displayed 𝒟 o₂' ℓ₂'}
   {F : Functor 𝒟 ℬ}
   is-discrete-cartesian-fibration ℰ
   (F' : Displayed-functor F ℱ ℰ)
   is-fibred-functor F'
functor+discrete→fibred disc F' =
  functor+right-fibration→fibred (discrete→right-fibration disc) F'