{-# OPTIONS --without-K --safe #-}
module lecture1 where
import introduction
Type = Set
Type₁ = Set₁
data Bool : Type where
true false : Bool
-- Type "→" as "\to" or "\->"
not : Bool → Bool
not true = false
not false = true
idBool : Bool → Bool
idBool x = x
idBool' : Bool → Bool
idBool' = λ (x : Bool) → x
-- The following is a Π type
id' : (X : Type) → X → X
id' X x = x
-- Implicit
id : {X : Type} → X → X
id x = x
idBool'' : Bool → Bool
idBool'' = id' _
-- "propositions as types" "mathematical statements as types"
example : {P Q : Type} → P → (Q → P)
example {P} {Q} p = f
where
f : Q → P
f _ = p
example' : {P Q : Type} → P → (Q → P)
example' p = λ q → p
open import binary-products
-- "×" is "and" in propositions as types
ex : {P Q : Type} → P × Q → Q × P
ex (p , q) = (q , p)
-- \bN
data ℕ : Type where
zero : ℕ
suc : ℕ → ℕ
three : ℕ
three = suc (suc (suc zero))
-- {-# BUILTIN NATURAL ℕ #-}
-- for technical reasons we can not have this binding here. however
-- there is already a type ℕ in the introduction module which /does/
-- support numeral notation. we are careful not to use the ℕ type
-- defined in this module again.
three' : introduction.ℕ
three' = 3 -- synonym for the above
D : Bool → Type
D true = introduction.ℕ
D false = Bool
-- "mix-fix" operator (3rd sense of "_" in Agda)
-- b x y
if_then_else_ : {X : Type} → Bool → X → X → X
if true then x else y = x
if false then x else y = y
if[_]_then_else_ : (X : Bool → Type)
→ (b : Bool)
→ X true
→ X false
→ X b
if[ X ] true then x else y = x
if[ X ] false then x else y = y
-- Π (b : Bool), D b
unfamiliar : (b : Bool) → D b
unfamiliar b = if[ D ] b then 3 else false
data List (A : Type) : Type where
[] : List A -- empty list
_::_ : A → List A → List A -- if xs is a list then x :: xs is list
infixr 10 _::_
ff : Type → Type
ff = List
sample-list₀ : List introduction.ℕ
sample-list₀ = 0 :: 1 :: 2 :: []
length : {X : Type} → List X → ℕ
length [] = zero
length (x :: xs) = suc (length xs)
-- Principle of induction on ℕ
ℕ-elim : {A : ℕ → Type}
→ A zero -- base case
→ ((k : ℕ) → A k → A (suc k)) -- induction step
→ (n : ℕ) → A n
ℕ-elim {A} a₀ f = h
where
h : (n : ℕ) → A n
h zero = a₀
h (suc n) = f n IH
where
IH : A n
IH = h n
ℕ-elim' : {A : ℕ → Type}
→ A zero -- base case
→ ((k : ℕ) → A k → A (suc k)) -- induction step
→ (n : ℕ) → A n
ℕ-elim' {A} a₀ f zero = a₀
ℕ-elim' {A} a₀ f (suc n) = f n (ℕ-elim' a₀ f n)
List-elim : {X : Type} (A : List X → Type)
→ A [] -- base
→ ((x : X) (xs : List X) → A xs → A (x :: xs)) -- step
→ (xs : List X) → A xs
List-elim {X} A a f = h
where
h : (xs : List X) → A xs
h [] = a -- base
h (x :: xs) = f x xs (h xs) -- step
-- \b0
data 𝟘 : Type where
-- \b1
data 𝟙 : Type where
⋆ : 𝟙 -- \star
_≣_ : ℕ → ℕ → Type
zero ≣ zero = 𝟙
zero ≣ suc y = 𝟘
suc x ≣ zero = 𝟘
suc x ≣ suc y = x ≣ y
infix 0 _≣_
ℕ-refl : (x : ℕ) → x ≣ x
ℕ-refl zero = ⋆
ℕ-refl (suc x) = ℕ-refl x
_+_ : ℕ → ℕ → ℕ
zero + y = y
suc x + y = suc (x + y)
infixr 20 _+_
_++_ : {A : Type} → List A → List A → List A
[] ++ ys = ys
(x :: xs) ++ ys = x :: (xs ++ ys)
lh : {X : Type} (xs ys : List X)
→ length (xs ++ ys) ≣ length xs + length ys
lh [] ys = ℕ-refl (length ys)
lh (x :: xs) ys = IH
where
IH : length (xs ++ ys) ≣ (length xs + length ys)
IH = lh xs ys