5.3 W-types
Inductive types are very general, which is excellent for their usefulness and applicability, but makes them difficult to study as a whole. Fortunately, they can all be formally reduced to a few special cases. It is beyond the scope of this book to discuss this reduction β which is anyway irrelevant to the mathematician using type theory in practice β but we will take a little time to discuss the one of the basic special cases that we have not yet met. These are Martin-LΓΆfβs -types, also known as the types of well-founded trees. -types are a generalization of such types as natural numbers, lists, and binary trees, which are sufficiently general to encapsulate the βrecursionβ aspect of any inductive type.
A particular -type is specified by giving two parameters and , in which case the resulting -type is written . The type represents the type of labels for , which function as constructors (however, we reserve that word for the actual functions which arise in inductive definitions). For instance, when defining natural numbers as a -type, the type would be the type inhabited by the two elements and , since there are precisely two ways to obtain a natural number β either it will be zero or a successor of another natural number.
The type family is used to record the arity of labels: a label will take a family of inductive arguments, indexed over . We can therefore think of the β-manyβ arguments of . These arguments are represented by a function , with the understanding that for any , is the β-thβ argument to the label . The -type can thus be thought of as the type of well-founded trees, where nodes are labeled by elements of and each node labeled by has -many branches.
In the case of natural numbers, the label has arity 0, since it constructs the constant zero; the label has arity 1, since it constructs the successor of its argument. We can capture this by using simple elimination on to define a function into a universe of types; this function returns the empty type for and the unit type for . We can thus define
where the superscript serves to distinguish this version of natural numbers from the previously used one. Similarly, we can define the type of lists over as a -type with many labels: one nullary label for the empty list, plus one unary label for each , corresponding to appending to the head of a list:
In general, the -type specified by and is the inductive type generated by the following constructor:
-
β’
.
The constructor (short for supremum) takes a label and a function representing the arguments to , and constructs a new element of . Using our previous encoding of natural numbers as -types, we can for instance define
Put differently, we use the label to construct . Then, evaluates to , as it should since is a nullary label. Thus, we need to construct a function , which represents the (zero) arguments supplied to . This is of course trivial, using simple elimination on as shown. Similarly, we can define
and so on.
We have the following induction principle for -types:
-
β’
When proving a statement about all elements of the -type , it suffices to prove it for , assuming it holds for all with . In other words, it suffices to give a proof
The variable represents our inductive hypothesis, namely that all arguments of satisfy . To state this, we quantify over all elements of type , since each corresponds to one argument of .
How would we define the function on natural numbers encoded as a -type? We would like to use the recursion principle of with a codomain of itself. We thus need to construct a suitable function
which will represent the recurrence for the function; for simplicity we denote the type family by .
Clearly, will be a function taking as its first argument. The next step is to perform case analysis on and proceed based on whether it is or . This suggests the following form
where
If is , the type becomes . Thus, given and , we want to construct an element of . Since the label represents , it needs zero inductive arguments and the variables and are irrelevant. We return as a result:
Analogously, if is , the type becomes . Since the label represents the successor operator, it needs one inductive argument β the predecessor β which is represented by the variable . The value of the recursive call on the predecessor is represented by the variable . Thus, taking this value (namely ) and applying the successor operator twice thus yields the desired result:
Putting this together, we thus have
with as defined above.
The associated computation rule for the function is as follows.
-
β’
For any and we have
In other words, the function satisfies the recurrence .
By the above computation rule, the function behaves as expected:
and | ||||
and so on.
Just as for natural numbers, we can prove a uniqueness theorem for -types:
Theorem 5.3.1.
Let be two functions which satisfy the recurrence
i.e., such that
Then and are equal.
Title | 5.3 W-types |
---|---|
\metatable |