I’ve recently returned from POPL 2018 in Los Angeles, where Carlo Angiuli and I gave a tutorial on Computational (Higher) Type Theory. It was structured into two parts, each consisting of a presentation of the theory followed by a demonstration of its use in the RedPRL prover. The tutorial was based on work that I have been doing over the last several years with my students, Carlo, Evan Cavallo, Favonia, and Jon Sterling, and with my colleague Daniel Licata, supported by AFOSR MURI grant FA9550-15-1-0053.
Computational higher type theory integrates two themes in type theory:
- Type theory is a theory of computation that classifies programs according to their behavior, rather than their structure. Types are themselves programs whose values stand for specifications of program equivalence.
- Type theory can be extended to higher dimensions that account for identifications of types and their elements. An identification is evidence for the interchangeability of two types in all contexts by computable transformations.
The idea of computational type theory was pioneered by Per Martin-Löf in his famous paper Constructive Mathematics and Computer Programming, and developed extensively in the NuPRL type theory and proof development environment.
The idea of higher type theory arose from several developments, notably the late Vladimir Voevodsky‘s univalence principle, which identifies equivalent types. As a first approximation equivalence may be thought of as a generalized form of isomorphism, which is respected by the constructs of type theory. The idea of univalence is to make precise informal conventions, such as not distinguishing between isomorphic structures, a handy expedient in many situations.
Voevodsky’s formulation of univalence was as a new axiom in intensional formal type theory that populates the identity type with new elements. This move was justified mathematically by Hofmann and Streicher’s proof that type theory does not preclude there being additional elements and by Voevodsky’s construction of a model of univalence using combinatorial structures called simplicial sets. However, these arguments left open the computational meaning of the extended theory, which disrupted the inversion principle governing the elimination form. What is J supposed to do with these new forms of identification?
This question sparked several attempts to give a constructive formulation of univalence by a variety of methods. One approach is to give a model of the theory in a constructive type theory with clear computational content, which was carried out by Bickford last year using NuPRL. Another is to develop a new semantic framework for type theory that accounts for univalence within a larger theory of identifications of types and elements.
The decisive first steps in this direction were taken by Bezem, Coquand, and Huber, and later developed by Cohen, Coquand, Huber, and Mörtberg, and by Licata and Brunerie, using cubical methods. The main idea is that “ordinary” types and elements are points, identifications of points are lines, identifications of lines are squares, and so forth at all dimensions. The approaches differ in the definition of a “cube” (there is more than one!), and in the conditions specifying the existence and action of cubes in the theory. For example, a line between types ought to induce a coercion between their elements, and it ought to be possible to compose two adjacent lines to get a third line.
The approach described in this tutorial extends the NuPRL type theory to account for higher-dimensional structure. Unlike structural type theories, a computational type theory is defined not by rules, but by semantics, specifically meaning explanations based on a prior notion of computation. In the present case we begin with a cubical programming language based on Licata and Brunerie’s formalism, and define types as programs that evaluate to specifications of the behavior of other programs. The resulting theory gives a computational meaning to univalence, and accounts for a higher-dimensional notion of inductive types in which one may specify generators not only for points, but also for lines, squares, and other higher-dimensional objects. The semantics ensures that every well-typed program evaluates to a value satisfying the specification given by its type. In particular closed programs of boolean type evaluate to either true or false; there are no “stuck” states, and no exotic elements.
This type theory is implemented in the RedPRL system, a new, open-source, implementation of computational type theory in the NuPRL tradition. It is based on a generalized form of refinement logic, the proof theory developed for NuPRL that emphasizes program extraction as a primitive notion. It does not look very much like standard proof theories for types, because it is not designed to correspond to any extant notion of logic, but rather to be useful in practice for deriving proofs (programs).
The slides from the presentation are available on my web site, and the implementation is freely available for download and experimentation. Enjoy!
Posted by Robert Harper