Type theory

In mathematics, logic, and computer science, a type theory is any of a class of formal systems, some of which can serve as alternatives to set theory as a foundation for all mathematics. In type theory, every "term" has a "type" and operations are restricted to terms of a certain type.

Type theory is closely related to (and in some cases overlaps with) type systems, which are a programming language feature used to reduce bugs. The types of type theory were created to avoid paradoxes in a variety of formal logics and rewrite systems and sometimes "type theory" is used to refer to this broader application.

The types of type theory were invented by Bertrand Russell in response to his discovery that Gottlob Frege's version of naive set theory was afflicted with Russell's paradox. This theory of types features prominently in Whitehead and Russell's Principia Mathematica. It avoids Russell's paradox by first creating a hierarchy of types, then assigning each mathematical (and possibly other) entity to a type. Objects of a given type are built exclusively from objects of preceding types (those lower in the hierarchy), thus preventing loops.

In a system of type theory, each term has a type and operations are restricted to terms of a certain type. A typing judgment describes that the term has type . For example, may be a type representing the natural numbers and may be inhabitants of that type. The judgement that has type is written as .

A function in type theory is denoted with an arrow . The function (commonly called successor), has the judgement . Calling or "applying" a function to an argument is usually written without parentheses, so instead of . (This allows for consistent currying.)

Type theories also contain rules for rewriting terms. These are called conversion rules or, if the rule only works in one direction, a reduction rule. For example, and are syntactically different terms, but the first reduces to the latter. This reduction is denoted as .

There are many different set theories and many different systems of type theory, so what follows are generalizations.

Set theory is built on top of logic. It requires a separate system like Frege's underneath it. In type theory, concepts like "and" and "or" can be encoded as types in the type theory itself.

In set theory, an element can belong to multiple sets, either to a subset or superset. In type theory, terms (generally) belong to only one type. (Where a subset would be used, type theory creates a new type, called a dependent sum type, with new terms. Union is similarly achieved by a new sum type and new terms.)

In set theory, sets can contain unrelated elements, e.g., apples and real numbers. In type theory, types that combine unrelated types do so by creating new terms.

Set theory usually encodes numbers as sets. (0 is the empty set, 1 is a set containing the empty set, etc.) Type theory can encode numbers as functions using Church encoding or more naturally as inductive types, which are a type with well-behaved constant terms.

The term reduces to . Since cannot be reduced further, it is called a normal form. A system of type theory is said to be strongly normalizing if all terms have a normal form and any order of reductions reaches it. Weakly normalizing systems have a normal form but some orders of reductions may loop forever and never reach it.

For a normalizing system, some borrow the word element from set theory and use it to refer to all closed terms that can reduce to the same normal form. A closed term is one without parameters. (A term like with its parameter is called an open term.) Thus, and may be different terms but they're both from the element .

A similar idea that works for open and closed terms is convertibility. Two terms are convertible if there exists a term that they both reduce to. For example, and are convertible. As are and . However, and (where is a free variable) are not because both are in normal form and they are not the same. Confluent and weakly normalizing systems can test if two terms are convertible by checking if they both reduce to the same normal form.

A dependent type is a type that depends on a term or on another type. Thus, the type returned by a function may depend upon the argument to the function.

For example, a list of s of length 4 may be a different type than a list of s of length 5. In a type theory with dependent types, it is possible to define a function that take a parameter "n" and returns a list containing "n" zeros. Calling the function with 4 would produce a term with a different type than if the function was called with 5.

Many systems of type theory have a type that represents equality of types and terms. This type is different from convertibility, and is often denoted propositional equality.

In intuitionistic type theory, the equality type is known as for identity. There is a type when is a type and and are both terms of type . A term of type is interpreted as meaning that is equal to .

In practice, it is possible to build a type but there will not exist a term of that type. In intuitionistic type theory, new terms of equality start with reflexivity. If is a term of type , then there exists a term of type . More complicated equalities can be created by creating a reflexive term and then doing a reduction on one side. So if is a term of type , then there is a term of type and, by reduction, generate a term of type . Thus, in this system, the equality type denotes that two values of the same type are convertible by reductions.

Having a type for equality is important because it can be manipulated inside the system. There is usually no judgement to say two terms are not equal; instead, as in the Brouwer–Heyting–Kolmogorov interpretation, we map to , where is the bottom type having no values. There exists a term with type , but not one of type .

A system of type theory requires some basic terms and types to operate on. Some systems build them out of functions using Church encoding. Other systems have inductive types: a set of base types and a set of type constructors that generate types with well-behaved properties. For example, certain recursive functions called on inductive types are guaranteed to terminate.

Coinductive type are infinite data types created by giving a function that generates the next element(s). See Coinduction and Corecursion.

Induction induction is a feature for declaring an inductive type and a family of types that depends on the inductive type.

Induction recursion allows a wider range of well-behaved types but requires that the type and the recursive functions that operate on them be defined at the same time.

Types were created to prevent paradoxes, such as Russell's paradox. However, the motives that lead to those paradoxes – being able to say things about all types – still exist. So many type theories have a "universe type", which contains all other types.

In systems where you might want to say something about universe types, there is a hierarchy of universe types, each containing the one below it in the hierarchy. The hierarchy is defined as being infinite, but statements must only refer to a finite number of universe levels.

There is extensive overlap and interaction between the fields of type theory and type systems. Type systems are a programming language feature designed to identify bugs. Any static program analysis, such as the type checking algorithms in the semantic analysis phase of compiler, has a connection to type theory.

A prime example is Agda, a programming language which uses intuitionistic type theory for its type system. The programming language ML was developed for manipulating type theories (see LCF) and its own type system was heavily influenced by them.

The first computer proof assistant, called Automath, used type theory to encode mathematics on a computer. Martin-Löf specifically developed intuitionistic type theory to encode all mathematics - to serve as a new foundation for mathematics. There is current research into mathematical foundations using homotopy type theory.

Much of the current research into type theory is driven by proof checkers, interactive proof assistants, and automated theorem provers. Most of these systems use a type theory as the mathematical foundation for encoding proofs. This is not surprising, given the close connection between type theory and programming languages.

The most common construction takes the basic types and for individuals and truth-values, respectively, and defines the set of types recursively as follows:

if and are types, then so is .

Nothing except the basic types, and what can be constructed from them by means of the previous clause are types.

A complex type is the type of functions from entities of type to entities of type . Thus one has types like which are interpreted as elements of the set of functions from entities to truth-values, i.e. indicator functions of sets of entities. An expression of type is a function from sets of entities to truth-values, i.e. a (indicator function of a) set of sets. This latter type is standardly taken to be the type of natural language quantifiers, like everybody or nobody (Montague 1973, Barwise and Cooper 1981).

Although the initial motivation for category theory was far removed from foundationalism, the two fields turned out to have deep connections. As John Lane Bell writes: "In fact categories can themselves be viewed as type theories of a certain kind; this fact alone indicates that type theory is much more closely related to category theory than it is to set theory." In brief, a category can be viewed as a type theory by regarding its objects as types (or sorts), i.e. "Roughly speaking, a category may be thought of as a type theory shorn of its syntax." A number of significant results follow in this way:[3]

José Ferreirós, José Ferreirós Domínguez, Labyrinth of thought: a history of set theory and its role in modern mathematics, Edition 2, Springer, 2007, ISBN 3-7643-8349-6, chapter X "Logic and Type Theory in the Interwar Period"