{-# OPTIONS --without-K --safe #-} module lecture2 where -- lecture 2 -- Plan: basic MLTT types, including their elimination principles. -- open import lecture1 hiding (π ; π ; D ; β ; _+_) open import introduction using (β ; zero ; suc ; _+_) -- empty type data π : Type where -- Ξ x κ X , A x -- (X β B) =. Ξ x κ X , B π-elim : {A : π β Type} (x : π) β A x π-elim () -- π interpreted as "false" Β¬_ : Type β Type Β¬ A = A β π infix 1000 Β¬_ π-nondep-elim : {B : Type} β π β B π-nondep-elim {B} = π-elim {Ξ» _ β B} -- A := Ξ» _ β B is-empty : Type β Type is-empty A = A β π -- A β‘ π or A β π. π-is-empty'' : is-empty π π-is-empty'' = Ξ» () π-is-empty : is-empty π π-is-empty = π-nondep-elim π-is-empty' : is-empty π π-is-empty' = id -- Unit type: -- Record definitions satisfy a certain "Ξ·" rule. record π : Type where constructor β open π public π-is-nonempty' : Β¬ is-empty π π-is-nonempty' = Ξ» (f : π β π) β f β π-is-nonempty : Β¬ is-empty π π-is-nonempty f = f β π-elim : {A : π β Type} β A β β (x : π) β A x π-elim a x = a π-nondep-elim : {A : Type} β A β π β A π-nondep-elim {A} = π-elim {Ξ» _ β A} -- Type of binary digits: data π : Type where π π : π π-elim : {A : π β Type} β A π β A π β (x : π) β A x π-elim aβ aβ π = aβ π-elim aβ aβ π = aβ π-nondep-elim : {A : Type} β A β A β π β A π-nondep-elim {A} = π-elim {Ξ» _ β A} -- Ξ types in Agda are primitive. -- -- We have that Ξ x κ X , A x is written -- -- (x : X) β A x, or -- β (x : X) β A x, or -- β x β A x (if Agda can infer X). -- -- We can introduce Ξ -syntax if we wish: Pi : (A : Type) (B : A β Type) β Type Pi A B = (x : A) β B x syntax Pi A (Ξ» x β b) = Ξ x κ A , b -- β -- this is typed "\:4" in emacs mode and is not the same as ":". -- (we can't use the normal one unfortunately.) -- Function composition. -- The usual one found in mathematics: module _ where private _β_ : {A B C : Type} β (B β C) β (A β B) β (A β C) (g β f) x = g (f x) -- A more general version: _β_ : {A B : Type} {C : B β Type} β ((y : B) β C y) β (f : A β B) β (x : A) β C (f x) (g β f) x = g (f x) -- The types-as-mathematical-statements reading of dependent function composition is: -- -- If (for all y : B we have that C y) and f : A β B is any function, then -- for all x : A we have that C (f x). -- -- The proof is function composition. -- Ξ£-types: module _ where private data Ξ£ {A : Type } (B : A β Type) : Type where _,_ : (x : A) (y : B x) β Ξ£ {A} B prβ : {A : Type} {B : A β Type} β Ξ£ B β A prβ (x , y) = x prβ : {A : Type} {B : A β Type} β (z : Ξ£ B) β B (prβ z) prβ (x , y) = y -- Our preferred definition: record Ξ£ {A : Type } (B : A β Type) : Type where constructor _,_ field prβ : A prβ : B prβ open Ξ£ public infixr 0 _,_ prβ-again : {A : Type} {B : A β Type} β Ξ£ B β A prβ-again = prβ prβ-again : {A : Type} {B : A β Type} ((x , y) : Ξ£ B) β B x prβ-again = prβ -- This satisfies the Ξ·-rule z = (prβ z , prβ z), which the definition using `data` doesn't. Sigma : (A : Type) (B : A β Type) β Type Sigma A B = Ξ£ {A} B syntax Sigma A (Ξ» x β b) = Ξ£ x κ A , b infix -1 Sigma -- Recall that we defined D as follows in the first lecture: D : Bool β Type D true = β D false = Bool -- Example Ξ£-exampleβ Ξ£-exampleβ : Ξ£ b κ Bool , D b Ξ£-exampleβ = (true , 17) Ξ£-exampleβ = (false , true) -- Ξ£-elim is "curry": Ξ£-elim : {A : Type } {B : A β Type} {C : (Ξ£ x κ A , B x) β Type} β ((x : A) (y : B x) β C (x , y)) β (z : Ξ£ x κ A , B x) β C z Ξ£-elim f (x , y) = f x y Ξ£-uncurry : {A : Type } {B : A β Type} {C : (Ξ£ x κ A , B x) β Type} β ((z : Ξ£ x κ A , B x) β C z) β (x : A) (y : B x) β C (x , y) Ξ£-uncurry g x y = g (x , y) _Γ_ : Type β Type β Type A Γ B = Ξ£ x κ A , B -- (x : X) β A x -- (x : X) Γ A x infixr 2 _Γ_ -- We will have that Aβ Γ Aβ β Ξ (n : π) , A n β ((n : π) β A n) -- where A π = Aβ -- A π = Aβ -- A : π β Type -- f β¦ (f π , f π) -- (aβ , aβ) β¦ π-elim aβ aβ -- But we need function extensionality to prove that this works. -- Binary products are special cases of products.
Various uses of Ξ£:
-- Binary sums _+_ β data _β_ (A B : Type) : Type where inl : A β A β B inr : B β A β B -- Mathematically A β B is (disjoint) union. -- Logically, it is "or" (disjunction). -- β₯ A β B β₯. infixr 20 _β_ β-elim : {A B : Type} (C : A β B β Type) β ((x : A) β C (inl x)) -- f β ((y : B) β C (inr y)) -- g β (z : A β B) β C z β-elim C f g (inl x) = f x β-elim C f g (inr y) = g y β-nondep-elim : {A B C : Type} β (A β C) β (B β C) β (A β B β C) β-nondep-elim {A} {B} {C} = β-elim (Ξ» z β C) -- We will have that Aβ β Aβ β Ξ£ (n : π) , A n -- where A π = Aβ -- A π = Aβ -- inl aβ β¦ (π , aβ) -- inr aβ β¦ (π , aβ) -- Binary sums are special cases of sums. -- We call an element of the identity type x β‘ y an -- "identification". The terminology "path" is also used. -- I prefer the former. data _β‘_ {A : Type} : A β A β Type where refl : (x : A) β x β‘ x -- refl x : proof that x is equal to itself. infix 0 _β‘_ -- The following is also called "J": β‘-elim : {X : Type} (A : (x y : X) β x β‘ y β Type) β ((x : X) β A x x (refl x)) β (x y : X) (p : x β‘ y) β A x y p β‘-elim A f x x (refl x) = f x -- To conclude that a property A x y p of identifications p of -- elements x and y holds for all x, y and p, it is enough to show -- that A x x (refl x) holds for all x. β‘-nondep-elim : {X : Type} (A : X β X β Type) β ((x : X) β A x x) β (x y : X) β x β‘ y β A x y β‘-nondep-elim A = β‘-elim (Ξ» x y _ β A x y) -- We finished lecture 2 here. So we'll start lecture 3 here. trans : {A : Type} {x y z : A} β x β‘ y β y β‘ z β x β‘ z trans p (refl y) = p sym : {A : Type} {x y : A} β x β‘ y β y β‘ x sym (refl x) = refl x ap : {A B : Type} (f : A β B) {x y : A} β x β‘ y β f x β‘ f y ap f (refl x) = refl (f x) apβ : {A B C : Type} (f : A β B β C) {x x' : A} {y y' : B} β x β‘ x' β y β‘ y' β f x y β‘ f x' y' apβ f (refl x) (refl y) = refl (f x y) transport : {X : Type} (A : X β Type) β {x y : X} β x β‘ y β A x β A y transport A (refl x) a = a _β_ : {A : Type} {x y z : A} β x β‘ y β y β‘ z β x β‘ z _β_ = trans infixl 7 _β_ _β»ΒΉ : {A : Type} {x y : A} β x β‘ y β y β‘ x _β»ΒΉ = sym infix 40 _β»ΒΉ _β€_ : β β β β Type 0 β€ y = π suc x β€ 0 = π suc x β€ suc y = x β€ y _β₯_ : β β β β Type x β₯ y = y β€ x _*_ : β β β β β 0 * y = 0 suc x * y = x * y + y infixr 30 _*_ _divides_ : β β β β Type x divides y = Ξ£ z κ β , x * z β‘ y is-prime : β β Type is-prime p = (p β₯ 2) Γ ((n : β) β n divides p β (n β‘ 1) β (n β‘ p)) twin-prime-conjecture : Type twin-prime-conjecture = (n : β) β Ξ£ p κ β , (p β₯ n) Γ is-prime p Γ is-prime (p + 2) there-are-infinitely-many-primes : Type there-are-infinitely-many-primes = (n : β) β Ξ£ p κ β , (p β₯ n) Γ is-prime p