module ThinSemiCategory where

open import Axioms public
open import InitialAlgebra public
open import Prelude public

----------------------------------------------------------------------
-- Small thin semi-categories
----------------------------------------------------------------------
record Thin (κ : Set) : Set₁ where
  infix 4 _<_
  field
    _<_   : κ  κ  Prop
    << : ∀{x y z}  y < z  x < y  x < z

open Thin{{...}} public

{-# DISPLAY Thin._<_ _ i j = i < j #-}

----------------------------------------------------------------------
-- Use instance search for proofs about <
----------------------------------------------------------------------
infix 4 _<ᵇ_
record _<ᵇ_  {κ : Set}{{_ : Thin κ}}(i j : κ) : Prop where
  constructor <inst
  field <prf : i < j

open _<ᵇ_ public

instance
  <ᵇ<ᵇ :
    {κ : Set}
    {{_ : Thin κ}}
    {i j k : κ}
    {{q : j <ᵇ k}}
    {{p : i <ᵇ j}}
     ------------
    i <ᵇ k
  <ᵇ<ᵇ {{q = q}} {{p}} = <inst (<< (<prf q) (<prf p))

-- Bounded dependent function
∏ᵇ :
  {κ : Set}
  {{_ : Thin κ}}
  (i : κ)
  {l : Level}
  (B : (j : κ){{_ : j <ᵇ i}}  Set l)
   ---------------------------------
  Set l
∏ᵇ {κ} i B = (j : κ){{_ : j <ᵇ i}}  B j

syntax ∏ᵇ i  j  B) = ∏ᵇ j < i , B

-- Restricting functions
infix 6 _↓_
_↓_ :
  {κ : Set}
  {{_ : Thin κ}}
  {l : Level}
  {B : κ  Set l}
  (f : (i : κ)  B i)
  (i : κ)
   -----------------
  ∏ᵇ j < i , B j
(f  _) j = f j

-- Bounded universal quantification
∀ᵇ :
  {κ : Set}
  {{_ : Thin κ}}
  (i : κ)
  {l : Level}
  (P : (j : κ){{_ : j <ᵇ i}}  Prop l)
   ----------------------------------
  Prop l
∀ᵇ i P =   j   {{_ : j <ᵇ i}}  P j

syntax ∀ᵇ i  j  P) = ∀ᵇ j < i , P

funᵇ-ext :
  {κ : Set}
  {{_ : Thin κ}}
  {i : κ}
  {l : Level}
  {B : (j : κ){{_ : j <ᵇ i}}  Set l}
  {f f' : ∏ᵇ i B}
  (_ : ∀ᵇ j < i , (f j  f' j))
   ---------------------------------
  f  f'
funᵇ-ext e =
  funext λ j 
  instance-funexp λ p  e j {{p}}

-- Bounded dependent product
record ∑ᵇ
  {κ : Set}
  {{_ : Thin κ}}
  (i : κ)
  {l : Level}
  (B : (j : κ){{_ : j <ᵇ i}}  Set l)
  : ---------------------------------
  Set l
  where
  constructor pairᵇ
  field
    fst      : κ
    {{fst<}} : fst <ᵇ i
    snd      : B fst
open ∑ᵇ public

syntax ∑ᵇ i  j  B) = ∑ᵇ j < i , B

-- Bounded existential quantification
data ∃ᵇ
  {κ : Set}
  {{_ : Thin κ}}
  (i : κ)
  {l : Level}
  (P : (j : κ){{_ : j <ᵇ i}}  Prop l)
  : ----------------------------------
  Prop l
  where
    ∃ᵇi : (j : κ){{_ : j <ᵇ i}}  P j  ∃ᵇ i P

syntax ∃ᵇ i  j  P) = ∃ᵇ j < i , P

-- Restricting bounded functions
infix 6 _↓ᵇ_
_↓ᵇ_ :
  {κ : Set}
  {{_ : Thin κ}}
  {i : κ}
  {l : Level}
  {B : ∏ᵇ j < i , Set l}
  (f : ∏ᵇ j < i , B j)
  (j : κ)
  {{_ : j <ᵇ i}}
   --------------------
  ∏ᵇ k < j , B k
(f ↓ᵇ _) k = f k