module Prelude
  (C : Set1)
  (HomC : C -> C -> Set)
  (idC : (c : C) -> HomC c c)
  (_∘C_ : {a b c : C} -> HomC b c -> HomC a b -> HomC a c)
  where

-- This file contains some basic definitions missing (or well-hidden)
-- in the standard library, and then defines the category Fam C,
-- parameterised by the category C, together with its coproducts.


open import Data.Product
open import Data.Bool
open import Function

-- Dependent elimination for Bool

Bool-elim :  {a} (P : Bool -> Set a) -> P true -> P false -> (x : Bool) -> P x
Bool-elim P Pt Pf true = Pt
Bool-elim P Pt Pf false = Pf


-- Fam C and Fam C morphisms, plus coproduct stuff for Fam C -----

record FamC : Set1 where
  constructor _,_
  field
    index : Set
    fam : index -> C
open FamC public

record HomFamC  (A B : FamC) : Set1 where
  constructor _,_
  field
    indfun : index A -> index B
    famfun : (x : index A) -> HomC (fam A x) (fam B (indfun x))
open HomFamC

idFamC : {A : FamC} -> HomFamC A A
idFamC {A} = id ,  x  idC (fam A x))

_∘FamC_ :  {a b c} -> HomFamC b c -> HomFamC a b -> HomFamC a c
(h , k) ∘FamC (h' , k') = (h  h') ,  x  k (h' x) ∘C k' x)

-- Fam C has coproducts

ΣFamC : (A : Set) -> (A -> FamC) -> FamC
ΣFamC A B = (Σ A (index  B)) ,  { (a , b)  fam (B a) b })


inA :  {A B} -> (a : A) -> HomFamC (B a) (ΣFamC A B)
inA a =  b  (a , b)) ,  b  idC _)

outΣ :  A {B C} -> ((a : A) -> HomFamC (B a) C) -> HomFamC (ΣFamC A B) C
outΣ A p =  { (a , b)  indfun (p a) b }) ,  { (a , b)  famfun (p a) b })

syntax outΣ A  a  p) = [ p ][ a ∈ A ]

ΣFamCmor : {I J : Set}  {X : I -> FamC}{Y : J -> FamC} ->
          (f : I -> J) ->
          (g : (i : I) -> HomFamC (X i) (Y (f i))) ->
          HomFamC (ΣFamC I X) (ΣFamC J Y)
ΣFamCmor {I} f g = [ inA (f i) ∘FamC (g i) ][ i  I ]