Lecture 5: Inductive data types

(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...