Chuangjie Xu

-------------------------
    A minimal library
-------------------------

for the course "Executing Proofs as Computer Programs"

\begin{code}

module Preliminaries where

open import Agda.Primitive using (Level ; _⊔_)


infix 10 _∈_

_∈_ : {X : Set}  X  (X  Set)  Set
x  A = A x


infixr 10 _,_

record Σ {i j : Level} {A : Set i} (B : A  Set j) : Set (i  j) where
 constructor _,_
 field
  pr₁ : A
  pr₂ : B pr₁

open Σ public

infixl 20 _×_
infixl 15 _+_
infixl 10 _↔_

_×_ : {i j : Level}  Set i  Set j  Set (i  j)
A × B = Σ \(_ : A)  B

_↔_ : {i j : Level}  Set i  Set j  Set (i  j)
A  B = (A  B) × (B  A)

data _+_ {i j : Level} (A : Set i) (B : Set j) : Set (i  j) where
 inl : A  A + B
 inr : B  A + B

case : {i j k : Level} {A : Set i} {B : Set j} {C : Set k}
      (A  C)  (B  C)  A + B  C
case f g (inl a) = f a
case f g (inr b) = g b

cases : {i j k l : Level} {A : Set i} {B : Set j} {C : Set k} {D : Set l}
       (A  C)  (B  D)  A + B  C + D
cases f g (inl a) = inl (f a)
cases f g (inr b) = inr (g b)

infix 1 _≡_

data _≡_ {i : Level} {A : Set i} (a : A) : A  Set i where
 refl : a  a

transport : {i j : Level} {A : Set i} (P : A  Set j) {x y : A}
           x  y  P x  P y
transport P refl p = p

ap : {i j : Level} {A : Set i} {B : Set j}
    (f : A  B) {x y : A}  x  y  f x  f y
ap f refl = refl

sym : {i : Level} {A : Set i} {x y : A}
     x  y  y  x
sym refl = refl

trans : {i : Level} {A : Set i} {x y z : A}
       x  y  y  z  x  z
trans refl refl = refl

pair⁼ : {A : Set} {B : A  Set} {a a' : A} {b : B a} {b' : B a'}
       (e : a  a')  transport B e b  b'
       (a , b)  (a' , b')
pair⁼ refl refl = refl

pairˣ⁼ : {A B : Set} {a a' : A} {b b' : B}
        a  a'  b  b'
        (a , b)  (a' , b')
pairˣ⁼ refl refl = refl

data 𝟘 : Set where

𝟘-elim : {i : Level} {A : Set i}  𝟘  A
𝟘-elim ()

¬_ : {i : Level}  Set i  Set i
¬_ A = A  𝟘

infix 10 _≢_

_≢_ : {i : Level} {A : Set i}  A  A  Set i
x  y = ¬ (x  y)

data 𝟙 : Set where
  : 𝟙

data 𝟚 : Set where
 𝟎 𝟏 : 𝟚

𝟚-discrete : {x y : 𝟚}  (x  y) + (x  y)
𝟚-discrete {𝟎} {𝟎} = inl refl
𝟚-discrete {𝟎} {𝟏} = inr  ())
𝟚-discrete {𝟏} {𝟎} = inr  ())
𝟚-discrete {𝟏} {𝟏} = inl refl

Lemma[b≡0∨b≡1] : (b : 𝟚)  (b  𝟎) + (b  𝟏)
Lemma[b≡0∨b≡1] 𝟎 = inl refl
Lemma[b≡0∨b≡1] 𝟏 = inr refl

data  : Set where
 zero : 
 succ :   

{-# BUILTIN NATURAL  #-}

pred :   
pred  0       = 0
pred (succ n) = n

ℕ-discrete : {n m : }  (n  m) + (n  m)
ℕ-discrete {0}      {0}      = inl refl
ℕ-discrete {0}      {succ m} = inr  ())
ℕ-discrete {succ n} {0}      = inr  ())
ℕ-discrete {succ n} {succ m} = step ℕ-discrete
 where
  step : (n  m) + (n  m)  (succ n  succ m) + (succ n  succ m)
  step (inl e) = inl (ap succ e)
  step (inr f) = inr  e  f (ap pred e))

infix 50 _≤_
infix 50 _<_

data _≤_ :     Set where
 zero≤ : {n : }  0  n
 succ≤ : {n m : }  n  m  succ n  succ m

pred≤ : {n m : }  succ n  succ m  n  m
pred≤ (succ≤ r) = r

_<_ :     Set
n < m = succ n  m

≤-refl : {n : }  n  n
≤-refl {0}      = zero≤
≤-refl {succ n} = succ≤ ≤-refl

≤-r-succ : {n m : }  n  m  n  succ m
≤-r-succ  zero≤    = zero≤
≤-r-succ (succ≤ r) = succ≤ (≤-r-succ r)

≤-trans : {n m k : }  n  m  m  k  n  k
≤-trans  zero≤     _        = zero≤
≤-trans (succ≤ r) (succ≤ s) = succ≤ (≤-trans r s)

Lemma[n≯m→n≤m] : {n m : }  ¬ (m < n)  n  m
Lemma[n≯m→n≤m] {0}      {m}      _ = zero≤
Lemma[n≯m→n≤m] {succ n} {0}      f = 𝟘-elim (f (succ≤ zero≤))
Lemma[n≯m→n≤m] {succ n} {succ m} f = succ≤ (Lemma[n≯m→n≤m]  r  f (succ≤ r)))

Lemma[n≤m∧m≤n→n≡m] : {n m : }  n  m  m  n  n  m
Lemma[n≤m∧m≤n→n≡m]  zero≤     zero≤    = refl
Lemma[n≤m∧m≤n→n≡m] (succ≤ r) (succ≤ s) = ap succ (Lemma[n≤m∧m≤n→n≡m] r s)

Lemma[n≤m→n<m∨n≡m] : {n m : }  n  m  (n < m) + (n  m)
Lemma[n≤m→n<m∨n≡m] {0}      {0}       zero≤    = inr refl
Lemma[n≤m→n<m∨n≡m] {0}      {succ m}  zero≤    = inl (succ≤ zero≤)
Lemma[n≤m→n<m∨n≡m] {succ n} {0}      ()
Lemma[n≤m→n<m∨n≡m] {succ n} {succ m} (succ≤ r) = cases succ≤ (ap succ) (Lemma[n≤m→n<m∨n≡m] r)

Lemma[≤-decidable] : {n m : }  (n  m) + ¬ (n  m)
Lemma[≤-decidable] {0}      {m}      = inl zero≤
Lemma[≤-decidable] {succ n} {0}      = inr  ())
Lemma[≤-decidable] {succ n} {succ m} = cases succ≤  f r  f (pred≤ r)) Lemma[≤-decidable]


max :     
max  0        m       = m
max (succ n)  0       = succ n
max (succ n) (succ m) = succ (max n m)

max-spec₀ : (n m : )  n  max n m
max-spec₀  0        m       = zero≤
max-spec₀ (succ n)  0       = ≤-refl
max-spec₀ (succ n) (succ m) = succ≤ (max-spec₀ n m)

max-spec₁ : (n m : )  m  max n m
max-spec₁  0        m       = ≤-refl
max-spec₁ (succ n)  0       = zero≤
max-spec₁ (succ n) (succ m) = succ≤ (max-spec₁ n m)

\end{code}

-------------------------------------------------
    Propositions and propositional truncation
-------------------------------------------------

\begin{code}

isProp : { : Level}  Set   Set 
isProp P = (x y : P)  x  y

postulate
 ∥_∥ : { : Level}  Set   Set 
 ∣_∣ : { : Level} {A : Set }  A   A 
 ∥∥-isProp : { : Level} {A : Set }  isProp  A 
 ∥∥-elim : { ℓ' : Level} {A : Set } {P : Set ℓ'}  isProp P  (A  P)   A   P

∥∥-functor : { ℓ' : Level} {A : Set } {B : Set ℓ'}  (A  B)   A    B 
∥∥-functor f = ∥∥-elim ∥∥-isProp  a   f a )

\end{code}

-------------------------------
    Function extensionality
-------------------------------

\begin{code}

postulate
 funext : { ℓ' : Level} {A : Set } {B : A  Set ℓ'} {f g : (x : A)  B x}
         (∀ x  f x  g x)  f  g

\end{code}