Type Theory
TODO
TODO Introduction
TODO Objective
- Define a language precise enough to so that translating to a programming language is feasable, but simple enough so that we understand each others.
- If anything is ambiguous, please send a suggestion.
:β‘
x :β‘ y means that x is a new name and that for now on, whenever one reads x, one may replace x by y.
If x :β‘ 1, then Β« x + x Β» may be read as Β« 1 + 1 Β».
If x :β‘ azerty, then Β« x + x Β» may be read as Β« azerty + azerty Β».
If x :β‘ '1', then Β« x + x Β» may be read as Β« '1' + '1' Β».
β‘
x β‘ y means that whenever one read x, one may replace x by y as it was already introduced before using :β‘.
π
π is a "hole" to be completed.
string : β β String :β‘ π
β¦
β¦ means that something is implicit and correctly typed.
string : β β String :β‘ β¦
X β Y
Why
We want to express the fact that there is a way to start from here and get to there.
For instance, given a number, say 0, there is a unique string representation "0". So, we say: string(0) :β‘ "0".
More over, if we call our numbers β, then for all n : β, we have string(n) : String.
We may see string as the name of a path, i.e. a way, to get from β to String.
Formation
X, Y : Type X β Y : Type
Introduction
x : X, y is a formula such that y(x) : Y Ξ»x.y : X β Y x β¦ y :β‘ Ξ»x.y
Elimination
f : X β Y x : X f(x) : Y :β‘ (Ξ»x.y)(x)
Ξ (x:X),Y(x)
Why
We want to express the fact that there is a way to start from here and get to there ; but the place we end up depends on where we start.
For instance, we might want to start from β and end up in String or β depending on where we started from.
For instance, if n is even, then f(n) :β‘ n and if n is odd, then f(n) :β‘ string(n).
Formation
Y : X β Type Ξ (x:X),Y(x) : Type
Introduction
Y : X β Type x : X y formula such that y(x) : Y(x) Ξ»x.y : Ξ (x:X),Y(x)
Elimination
f : Ξ (x:X),Y(x) x : X f(x) : Y(x) :β‘ (Ξ»x.y)(x)
β
Standard function composition.
β : (A β B) (B β C) β A β C :β‘ f g a β¦ g(f(a))
βΈ
We want to define "pipelines" of transformations that can be read left to right.
βΈ : (A β B) (B β C) β A β C :β‘ f g β¦ g β f a βΈ f βΈ g :β‘ βΈ(f g)(a)
2Γ : β β β :β‘ n β¦ 2 Γ n string : β β String :β‘ β¦ f :β‘ 2Γ βΈ string f : β β String f(1) = "2"
X Γ Y
Why
Given two types of instances X and Y, we might want to consider both instances at the same time.
For instance, we might want to speak about the pair Capital and Country like Paris and France at the same time.
Formation
X, Y : Type X Γ Y : Type
Introduction
< , > : X Y β X Γ Y
Elimination
f : X β Y β Z Ο : X Γ Y β Z :β‘ <x, y> β¦ f(x)(y)
C : X Γ Y β Type f : Ξ (x:X,y:Y),C(<x,y>) Ο : Ξ (p:XΓY),C(p) :β‘ <x, y> β¦ f(x)(y)
Ξ£(x:X),Y(x)
Why
We want instances of some type such that they represent a pair of instances where the second instance type depends on the first instance.
For instance, we might want to speak about pairs such that the second components is a string if the firt component is an even number.
Formation
X : Type Y : X β Type Ξ£(x:X),Y(x) : Type
Introduction
< , > : x:X Y(x) β Ξ£(x:X),Y(x)
Elimination
f : Ξ (x:X),Y(x) β Z Ο : Ξ£(x:X),Y(x) β Z :β‘ <x, y> β¦ f(x)(y)
C : Ξ (x:X),Y(x) β Type f : Ξ (x:X) Ξ (y:Y(x)) C(<x,y>) Ο : Ξ (p:Ξ (x:X),Y(x)),C(p) :β‘ <x, y> β¦ f(x)(y)
Magma
Magma :β‘ Ξ£(A:Type)(A β A β A)
PointedMagma
PointedMagma :β‘ Ξ£(A:Type)(A β A β A) Γ A
X + Y
Why
Given two types X and Y, we might want to consider an instance that may be of one type or the other.
For instance, we might want to speak about a Capital or a Country like Paris or France.
Formation
X, Y : Type X + Y : Type
Introduction
left : X β X + Y right : Y β X + Y
Elimination
elim : (f : X β Z) (g : Y β Z) β X + Y β Z :β‘ left(x) β¦ f(x) right(y) β¦ g(y)
Target :β‘ X + Y β Type Left : Target β Type :β‘ C β¦ Ξ (x:X),C((left(x))) Right : Target β Type :β‘ C β¦ Ξ (y:Y),C((right(y))) ind : C:Target Left(C) Right(C) β Ξ (p:X+Y),C(p) :β‘ left(x) β¦ f(x) right(y) β¦ g(y)
As long as there are no ambiguities, we will use the following for conciseness:
a : A + B b : A + B c : A + B + C β¦
β
Why
We want to be able to count things.
Formation
β : Type
Introduction
0 : β succ : β β β n+1 :β‘ succ(n)
Elimination
T : Type elim : t:T β (next : β T β T) β β β T :β‘ 0 β¦ t n+1 β¦ next n f(n)
P : β β Type Init :β‘ P(0) Step :β‘ β P(n) β P(n+1) ind : (t0 : Init) (step : Step) β Ξ (n:β),P(n) :β‘ 0 β¦ t0 n+1 β¦ step n f(n)
π
Why
We need to have a type that has one element, to represent True.
Formation
π : Type
Introduction
x : π
Elimination
C : Type elim : (c:C) π β C :β‘ x β¦ c
ind : (C : π β Type) (c : C(x)) β Ξ (x:π), C(x) :β‘ x β¦ c
π
Why
We need to have a type that has no element, which is used to represent falsity.
Formation
π : Type
Introduction
Elimination
C : Type f : π β C
C : π β Type f : Ξ (x:π), C(x)
Boolean
Why
We need to represents booleans i.e. a type with two elements, true or false.
Formation
Boolean : Type
Introduction
0 : Boolean 1 : Boolean
Elimination
C : Type elim : (c0:C) (c1:C) β Boolean β C :β‘ 0 β¦ c0 1 β¦ c1
C : Boolean β Type ind : (c0:C(0)) (c1:C(1)) β Ξ (x:Boolean), C(x) :β‘ 0 β¦ c0 1 β¦ c1
Symbol
Why
We need to represents symbols i.e. unique instances (they are only equal to themselves an nothing else).
Formation
Symbol : Type
Introduction
Symbol#mk : String β Symbol
:name :β‘ Symbol#mk("name")
Elimination
Behaves like a FinSet where elements are all the symbols that have been introduced so far.
Type
Following the preceding examples of types, we provide the following template to define new types:
Why
Why do we need to introduce this new type?
Formation
What is the name of that type?
Introduction
How to build instances of that type?
Elimination
How to use instances of that type?
Propositions as types
However, the type-theoretic perspective on proofs is nevertheless different in important ways. The basic principle of the logic of type theory is that a proposition is not merely true or false, but rather can be seen as the collection of all possible witnesses of its truth.
[β¦]
propositions are nothing but special types β namely, types whose elements are proofs.
English Type Theory True 1 False 0 A and B A Γ B A or B A + B If A then B A β B A if and only if B (A β B) Γ (B β A) Not A A β 0 For all x : A, P(x) holds β(x : A),P(x) There exists x : A such that P(x) β(x : A),P(x)
Identity type
Why
The identity type internalizes the notion of equality (or identification) within the type theory. Given two terms a and b of the same type A, the identity type a = b is the type of evidences that a and b are equal.
Formation
A : Type a, b : A IdA(a, b) : U a = b :β‘ IdA(a, b)
Introduction
refl : Ξ (a:A), a = a
Elimination
C : A β U f : β(x,y:A)β(p:x=y),C(x) β C(y) f(x,x,refl(x)) :β‘ id(C(x))
C : β(x,y:A),x=y β U c : β(x:A),C(x,x,refl(x)) f : β(x,y:A), β(p:x=y), C(x,y,p) f(x,x,refl(x)) :β‘ c(x)
List(X)
Why
Lists of things are a common data structures, we need a way to represent them.
Formation
X : Type List(X) : Type
Introduction
[] : List(X) cons : X List(X) β List(X)
Elimination
C : Type elim : (c0 : C) (g : X β C β C) β List(X) β C :β‘ f [] :β‘ c0 f cons(x lst) :β‘ g x f(lst)
C : List(X) β Type c0 : C([]) g : Ξ (x:X)Ξ (lst:List(X)), C(lst) β C(cons(x lst)) f : Ξ (lst:List(X)), C(lst) :β‘ [] β¦ c0 cons x lst β¦ g x lst f(lst)
map
Standard map function.
map : List(A) (A β B) β List(B) :β‘
as b β¦
match as
[] β¦ []
cons(a as) β¦ cons(b(a) map(as b))
Bit
Why
Computers manipulates bits, let's represent them.
Formation
Bit : Type
Introduction
0 : Bit 1 : Bit
Elimination
C : Type c0, c1 : C f : Bit β C :β‘ 0 β¦ c0 1 β¦ c1
C : Bit β Type c0 : C(0) c1 : C(1) f : Ξ (x:Bit), C(x) :β‘ 0 β¦ c0 1 β¦ c1
Data
Why
Computers manipulate data which are just lists of bits.
Formation
Data :β‘ List(Bit)
Undefined
Why
Programmning languages have a tendency to represent undefined object, which is to say to there is something but we have no idea what that is beyond that point.
Formation
Undefined : Type
Introduction
undefined : Undefined
Elimination
Nothing
Why
How to represent the absence of a value? By using the unique instance of the Nothing type, isomorphic to π.
Formation
Nothing : Type
Introduction
nothing : Nothing
Elimination
Maybe
Why
Assume that a computers tries to map some data received from the network to some type using a given program. Assume an injective mapping, then the algorithm might fail. So, given a piece of data, the algorithm is expected to either provide an instance of some type or nothing. Let's represent that.
Formation
X : Type Maybe(X) :β‘ Nothing + X
Construction
none :β‘ left(nothing) just(x) :β‘ right(x)
TODO Vector(X n)
Why
Finite lists of things that have a known length are common in programming languages, let's defined them.
Formation
X : Type n : β Vector(X n) : Type
Introduction
nil : Vector(X zero) cons(x lst) : X Vector(X n) β Vector(X n+1)
Elimination
π
TODO index
index(lst n) represents the nth element of lst if any, else undefined.
index : List(X 0) Nat β X | Undefined index([] n) :β‘ undefined
index : List(X 1) Nat β X | Undefined index([x] 0) :β‘ undefined index([x] 1) :β‘ x Given k > 1, then index([x] k) :β‘ undefined.
Given index : List(X n) Nat β X | Undefined, lst+x : List(X n+1), and k : Nat, then:
if k < n+1, then index(lst k) :β‘ index(lst k) if k = n+1, then index(lst n+1) :β‘ x if k > n+1, then index(lst k) :β‘ undefined
TODO String
String :β‘ List(Nat)
TODO Just
X : Type Just(X) :β‘ π
TODO StrictPartialOrder
StrictPartialOrder(X) :β‘ π
TODO Set
X : Type = : X X β Boolean = is an equality Set(X =) :β‘ list : List(X) e(i) β list, e(j) β list, i β j, e(i) β e(j)
Predicate
Predicate :β‘ X β Boolean
Language
cond
To express the fact if a given predicate() = true holds, then some list of
instructions should be executed, we use the following syntacting form:
cond predicate β¦ instructions β¦ true β¦ instructions
match
To express the fact if some piece of data x has a given form (i.e. it matches some pattern), then some list of instructions should be executed, potentially using matched patterns, we use the following syntacting form:
match x pattern β¦ instructions β¦ _ β¦ instructions
If x does not match any pattern, then it is an error of the author. _ matches
anything. For instance:
match maybe nothing β¦ "nothing" just(x) β¦ x
The meaning should be obvious: if maybe : Maybe(X) β‘ none, then replace the whole expression by "nothing". If maybe β‘ just(x), then replace the whole expression by x. Patterns may be extended by predicates using guards. For instance:
match x pattern when predicate β¦ instructions β¦