(credits: Assia Mahboubi)
In this class, we shall present how the type system of Coq allows us to define
data types using inductive declarations.
Inductive
declarations
An arbitrary type as assumed by :
Parameter T:Type.
gives no a priori information on the
nature, the number, or the properties of its inhabitants.
An
inductive type declaration explains how the inhabitants of the type are
built, by giving names to each construction
rule :
Each such rule
is called a constructor.
Inductive
declarations in Coq
Inductive types in Coq can be seen as the generalization of similar type
constructions in more common programming languages.
They are in fact an extremely rich
way of defining data-types, operators, connectives, specifications,...
They are at the core of powerful
programming and reasoning techniques.
Enumerated
types
Enumerated types are types which list and name
exhaustively their inhabitants.
Labels refer to distinct elements.
Enumerated
types :program by case analysis
Inspect the
enumerated type inhabitants and assign values :
Enumerated
types :reason by case analysis
Inspect the
enumerated type inhabitants and build proofs :
Recursive
types
Base case constructors do not
feature self-reference to the type. Recursive case
constructors do.
Let us craft new inductive types :
Inductive natBinTree : Set :=
An inhabitant of a recursive type is
built from a finite number of constructor
applications.
Recursive
types :program by case analysis
We have already
seen some examples of such pattern matching
:
Constructors
are injective :
Recursive
types :structural induction
Let us go back to the definition of natural numbers :
The
Inductive keyword means that at definition time, this system generates an induction principle :
To prove that
for P : term ->
Prop,
the theorem forall t
: term, P t holds, it is sufficient to :
4 Prove that the
property holds for the base cases :
4 (P Zero)
4 (P One)
4 Prove that the
property is transmitted inductively :
4 forall t1 t2 term,
P t1 -> P t2 -> P (Plus t1 t2)
4 forall t1 t2 term,
P t1 -> P t2 -> P (Mult t1 t2)
The type term
is the smallest type containing Zero
and One, and closed under Plus
and Mult.
The induction principles generated
at definition time by the system allow to :
4 Program by
recursion (Fixpoint)
4 Prove by
induction (induction)
Recursive
types : program by structural induction
We can compute
some information on the size of a term :
We can access
some information contained in a term :
We have already seen induction at
work on nats and lists. Here it goes on binary trees :
Option
types
A polymorphic
(like list) non recursive
type :
Use it to lift
a type to a copy of this type but with a default
value :
Pairs
& co
A polymorphic
(like list) pair
construction :
The notation A * B denotes (prod A B).
The notation (x, y) denotes (pair x y) (implicit argument).
Fetching the
components :
This can also
be adapted to polymorphic n-tuples :
Inductive
triple (T1 T2 T3 : Type) :=
| Triple : T1 -> T2 -> T3 -> triple T1 T2 T3.
Record
types
A record type
bundles pieces of data you wish to gather in a single type.
They are also
inductive types with a single constructor !
You can access
to the fields :
In proofs, you can break an element
of record type with tactics case/destruct.
Warning :this is pure functional programming...