data ℕ : Set where
zero : ℕ
succ : ℕ → ℕ
data ∅ : Set where
one : ℕ
one = succ zero
two : ℕ
two = succ (succ zero)
four : ℕ
four = succ (succ (succ (succ zero)))
-- We will now define, for any natural number n, "Even n".
-- More precisely, "Even n" is a certain type.
-- Namely the type of *witnesses that n is even*.
-- For instance, the type "Even one" (where one = succ zero) should be an empty type.
-- In contrast, the types "Even zero" and "Even four" should each be inhabited.
data Even : ℕ → Set where
Base : Even zero -- "the number zero is even"
Step : (n : ℕ) → Even n → Even (succ (succ n)) -- "for every number n, if n is even, so is succ (succ n)"
-- "Odd" is a function which maps natural numbers to (newly created) types.
-- Namely, "Odd n" is the type of witnesses that n is odd.
-- For instance, the type "Odd zero" is empty and the type "Odd one" is inhabited.
data Odd : ℕ → Set where
Base' : Odd one
Step' : (n : ℕ) → Odd n → Odd (succ (succ n))
lemma-even-odd : (n : ℕ) → Even n → Odd (succ n)
lemma-even-odd .zero Base = Base'
lemma-even-odd .(succ (succ n)) (Step n p) = Step' (succ n) (lemma-even-odd n p)
{-
in English:
By induction on n.
Base case n = 0: In this case we have to verify that 1 is odd. This is trivial (by Base').
Induction step m → 2 + m: In this case we have to verify that, if m is even, then succ m is odd.
Because m is even, m is of the form succ (succ n) for some even number n.
Hence by the inductive hypothesis, the number succ n is odd.
Hence by Step', the number succ (succ (succ n)) is odd.
-}
data _⊎_ (A B : Set) : Set where -- in Haskell, this type is called "Either"
left : A → A ⊎ B
right : B → A ⊎ B
-- The type "ℕ ⊎ Bool" contains the following values:
-- left zero, left (succ zero), left (succ (succ zero)), ...
-- right false, right true
-- "Every natural number is even or odd."
theorem : (n : ℕ) → Even n ⊎ Odd n
theorem zero = left Base
theorem (succ n) with theorem n
... | left p = right (lemma-even-odd n p)
... | right q = {!!}
fun-fact : Even zero
fun-fact = Base
fun-fact' : Even two
fun-fact' = Step zero Base
fun-fact'' : Even four
-- fun-fact'' = Step (succ (succ zero)) (Step zero Base)
fun-fact'' = Step two fun-fact'
fun-fact''' : Odd (succ (succ (succ zero)))
fun-fact''' = Step' (succ zero) Base'
lemma : (n : ℕ) → Even n → Even n -- "for every number n, if n is even, then n is even"
lemma n p = p
lemma' : (n : ℕ) → Odd n → Odd n -- "for every number n, if n is odd, then n is odd
lemma' n p = p
lemma'' : {A : Set} → A → A -- "A implies A" "if A, then A"
lemma'' x = x
{-
ROSETTA STONE BETWEEN COMPUTING AND LOGIC
programming logic/type theory
----------------------------------------------
type A → A of functions statement that A implies A
identity function proof of the statement that A implies A
-}
{-
-- CLAIM: There is no function from ℕ → ∅.
claim : (ℕ → ∅) → ∅
claim f = f zero
-- "There are no function f : ℕ → ∅, just have a look at what f(zero) would be!"
claim' : (ℕ → ∅) → ∅
claim' f = f (succ zero)
-- "There are no function f : ℕ → ∅, just have a look at what f(1) would be!"
data Bool : Set where
false true : Bool
Set-of-decidable-subsets : Set → Set
Set-of-decidable-subsets X = X → Bool
Powerset : Set → Set₁
Powerset X = X → Set
-- the empty subset of X is given by the function λ x → ∅
truer-Powerset : Set → Set₂
truer-Powerset X = X → Set₁
{-
even-truer-Powerset : Set → Set
even-truer-Powerset X = X → Set₂
-}
-- Prop is the type of all those small types which contain at most one inhabitant.
-- Prop itself is not a small type, but a large type.
is-prop : Set → Set
is-prop X = {!(a : X) → (b : X) → a ≡ b!} -- "is-prop X" means: "X contains at most one inhabitant"
{-
Prop : Set₁
Prop = ? -- (the type of pairs (X,p) where X is a small type and p is an element of is-prop X)
-}
data Σ (A : Set) (B : A → Set) : Set where
⟨_,_⟩ : (x : A) → B x → Σ A B
is-decidable : Set → Set
is-decidable X = X ⊎ (X → ∅)
is-semidecidable-oracle : {X : Set} → (X → Bool ⊎ ∅) → Set
is-semidecidable-oracle f = ?
-- Prop₁ is the type of all those large types which contain at most one inhabitant.
-- Prop₁ itself is not a large type, but a very large type.
-- Prop₂ is the type of all those very large types which contain at most one inhabitant.
-- Prop₂ itself is not a very large type, but a very very large type.
{-
Powerset' : Set → Set₁
Powerset' X = X → Prop
-- the empty subset of X is given by the function λ x → ∅
truer-Powerset' : Set → Set₂
truer-Powerset' X = X → Prop₁
even-truer-Powerset' : Set → Set₃
even-truer-Powerset' X = X → Prop₂
-- Set is the type of small types, but Set itself is not a small type.
-- zero : ℕ : Set : Set₁ : Set₂ : Set₃ : ...
-- For most types X, there is no procedure for checking whether any
-- given predicate f : X → Bool has a zero (attains false).
-- But for some types, there is.
-- For instance, for finite types there is.
-- Amazing wonder: Also for some infinite types there is such a checking procedure.
-- Approximately: There is such a checking procedure if and only if X is compact (when thought of as a space).
-- CLAIM: The number one is not even.
-- RECALL: In logic, "¬ φ" is a shorthand for "φ ⇒ ⊥".
{-
lemma-one-not-even : Even one → ∅
lemma-one-not-even = ?
-}
-}
-}