------------------------------------------------------------------------
-- Various types and functions
--
-- Nils Anders Danielsson
------------------------------------------------------------------------

module Prelude where

------------------------------------------------------------------------
-- Equality

-- Equality. Note that this definition is very similar to the one
-- given in Lecture 8.

infix 4 _≡_

data _≡_ {A : Set} (x : A) : A  Set where
  refl : x  x

-- Symmetry. Agda checks [*] that all cases are covered, and that the
-- function is terminating/productive, because otherwise one could
-- prove anything.
--
-- [*] Unless the implementation is buggy.

sym :  {A} {x y : A}  x  y  y  x
sym refl = refl

-- Transitivity.

trans :  {A} {x y z : A}  x  y  y  z  x  z
trans refl refl = refl

-- Equality is a congruence: every function preserves equality.

cong :  {A B} (f : A  B) {x y}  x  y  f x  f y
cong f refl = refl

cong₂ :  {A B C} (f : A  B  C) {x y u v} 
        x  y  u  v  f x u  f y v
cong₂ f refl refl = refl

------------------------------------------------------------------------
-- The unit type

data Unit : Set where
  unit : Unit

------------------------------------------------------------------------
-- The maybe type

data Maybe (A : Set) : Set where
  just    : A  Maybe A
  nothing : Maybe A

-- Applicative functor application.

infixl 4 _<$>_ _⊛_

_⊛_ :  {A B}  Maybe (A  B)  Maybe A  Maybe B
just f   just x  = just (f x)
just f   nothing = nothing
nothing  _       = nothing

-- Map.

_<$>_ :  {A B}  (A  B)  Maybe A  Maybe B
f <$> x = just f  x

-- A safe variant of fromJust. If the value is nothing, then the
-- return type is the unit type.

FromJust :  A  Maybe A  Set
FromJust A (just _) = A
FromJust A nothing  = Unit

fromJust :  {A} (x : Maybe A)  FromJust A x
fromJust (just x) = x
fromJust nothing  = unit

------------------------------------------------------------------------
-- Numbers

-- Unary natural numbers

data  : Set where
  zero : 
  suc  :   

-- Support for natural number literals.

{-# BUILTIN NATURAL     #-}
{-# BUILTIN ZERO    zero #-}
{-# BUILTIN SUC     suc  #-}

-- Bounded natural numbers. A value of type Fin n is smaller than n.

data Fin :   Set where
  zero :  {n}  Fin (suc n)
  suc  :  {n}  Fin n  Fin (suc n)

-- A decision procedure for equality. If the two numbers are equal,
-- then a proof is returned (just as in Lecture 8).

infix 5 _≟-Fin_

_≟-Fin_ :  {n} (i j : Fin n)  Maybe (i  j)
zero  ≟-Fin zero  = just refl
suc i ≟-Fin suc j = cong suc <$> i ≟-Fin j
_     ≟-Fin _     = nothing

------------------------------------------------------------------------
-- Lists and vectors

-- Finite lists.

infixr 5 _∷_

data List (A : Set) : Set where
  []  : List A
  _∷_ : A  List A  List A

-- Append.

infixr 5 _++_

_++_ :  {A}  List A  List A  List A
[]       ++ ys = ys
(x  xs) ++ ys = x  (xs ++ ys)

-- Vectors. A vector of type Vec A n has length n.

data Vec (A : Set) :   Set where
  []  : Vec A zero
  _∷_ :  {n}  A  Vec A n  Vec A (suc n)

-- Safe lookup.

lookup :  {A n}  Fin n  Vec A n  A
lookup zero    (x  xs) = x
lookup (suc i) (x  xs) = lookup i xs