Data Types as Quotients of Polynomial Functors Jeremy Avigad Department of Philosophy, Carnegie Mellon University, Pittsburgh, PA, USA http://www.andrew.cmu.edu/user/avigad/ [email protected] Mario Carneiro Department of Philosophy, Carnegie Mellon University, Pittsburgh, PA, USA [email protected] Simon Hudon Department of Philosophy, Carnegie Mellon University, Pittsburgh, PA, USA https://www.cmu.edu/dietrich/philosophy/people/postdoc-fellows/simon-hudon%20.html [email protected] Abstract A broad class of data types, including arbitrary nestings of inductive types, coinductive types, and quotients, can be represented as quotients of polynomial functors. This provides perspicuous ways of constructing them and reasoning about them in an interactive theorem prover. 2012 ACM Subject Classification Theory of computation → Logic and verification; Theory of computation → Type theory; Theory of computation → Data structures design and analysis Keywords and phrases data types, polynomial functors, inductive types, coinductive types Digital Object Identifier 10.4230/LIPIcs.ITP.2019.6 Supplement Material Lean formalizations are online at https://github.com/avigad/qpf. Funding Work partially supported by AFOSR grant FA9550-18-1-0120 and the Sloan Foundation. Acknowledgements We are grateful to Andrei Popescu, Dmitriy Traytel, and Jasmin Blanchette for extensive discussions and very helpful advice. 1 Introduction Data types are fundamental to programming, and theoretical computer science provides abstract characterizations of such data types and principles for reasoning about them. For example, an inductive type, such as the type of lists of elements of type α, is freely generated by its constructors: inductive list( α : Type) | nil: list | cons: α → list → list Such a declaration gives rise to a type constructor, list, constructors nil and cons, and a recursor: list.rec{ α β}: β → (α → list α → β → β) → list α → β The recursor satisfies the following equations: list.recbf nil=b list.recbf(consal)=fal(list.recbfl) We also have an induction principle: ∀ {α}(P: list α → Prop),P nil → (∀ al,Pl → P(consal)) → ∀ l,Pl © Jeremy Avigad, Mario Carneiro, and Simon Hudon; licensed under Creative Commons License CC-BY 10th International Conference on Interactive Theorem Proving (ITP 2019). Editors: John Harrison, John O’Leary, and Andrew Tolmach; Article No. 6; pp. 6:1–6:19 Leibniz International Proceedings in Informatics Schloss Dagstuhl – Leibniz-Zentrum für Informatik, Dagstuhl Publishing, Germany 6:2 Data Types as Quotients of Polynomial Functors In words, to prove that a property holds of all lists, it is enough to show that it holds of the empty list and is preserved under the cons operation. Here we have adopted the syntax of the Lean theorem prover [19], so the curly braces around the type arguments α and β indicate that these arguments are generally left implicit and inferred from context. The type of the variable P, namely list α → Prop, indicates that it is a predicate on lists. Dual to the notion of an inductive type is the notion of a coinductive type, such as the type of streams of elements of α: coinductive stream( α : Type) | cons(head: α)(tail: stream): stream Our syntax is similar to that used for the inductive declaration, but the fundamental properties of such a type can be expressed naturally in terms of the destructors rather than the constructors. Roughly speaking, when one observes a stream of elements of α, one sees an element of α, the head, and another stream, the tail. In addition to the type constructor stream and the destructors head and tail, one obtains a corecursor: stream.corec{ α β}:(β → α × β) → β → stream α It satisfies these defining equations: head(stream.corecfb)= fst(fb) tail(stream.corecfb)= stream.corecf(snd(fb)) We also have a coinduction principle: ∀ {α}(R: stream α → stream α → Prop), (∀ xy,Rxy → headx= heady ∧ R(tailx)(taily)) → ∀ xy,Rxy → x=y Intuitively, the corecursor allows one to construct a stream from an element b of β by giving an element of α, the head, and another element of β to continue the construction. The coinductive principle says we can prove two streams are equal by showing that they satisfy a relation on streams that implies the heads are the same and the tails are again related. Inductive definitions date to the beginning of modern logic, with inductive character- izations of the natural numbers by Dedekind [20] and Frege [24], and generalizations by Knaster [31], Tarski [39], Kreisel [32], and many others (e.g. [3]). The general study of coinductive definition seems to have originated with Aczel [3, 4], and has since been extended by many others (e.g. [6, 9, 37]). The algebraic study of data types begins with the observation that many constructions are functorial in their arguments. For example, an element x of list(α) and a function f : α → β give rise to an element of list(β), the result of applying f to each element in the list. Similarly, products α × β and sums α + β are functorial in either argument. In category-theoretic notation, given a functor F (α), one would write F (f) to denote the map from F (α) to F (β). In Lean, given a functor F , we can write f <$> x to denote F (f)(x), since the system can infer F from the type of x, namely, F α. In this paper, we will generally use category-theoretic notation and the language of set-valued functors when talking about the general constructions, to be consistent with the general literature. When we focus on dependent type theory and our formalizations, however, we will resort to type-theoretic syntax and take α to be a type rather than a set. For any functor F from sets to sets, a function F (α) → α is known as an F -algebra, and specifying an inductive definition amounts to specifying such an algebra. For example, the natural numbers are defined by a constant 0 ∈ N and a function from N to N. Putting J. Avigad, M. Carneiro, and S. Hudon 6:3 these together yields a function 1 + N → N, where 1 denotes a singleton set and + denotes a disjoint union. So the constructors for N amount to a function F (N) → N, where F (α) is the functor 1 + α. The inductive character of the natural numbers means that N is an initial F -algebra, in the sense that for any F -algebra F (α) → α, there is a function rec from N to α such that the following square commutes: F (rec) F (N) F (α) rec N α Similarly, list(α) is an initial algebra for the functor F (β) = 1 + α × β. Dually, a coalgebra for a functor F (α) is a function α → F (α). A coinductive definition corresponds to a final coalgebra, that is, a coalgebra λ → F (λ) with the property that for any colagebra α → F (α), there is a map from α → λ making the corresponding square commute. The question is then: Which set-valued functors have initial algebras and final coalgebras? Not all do: initial algebras and final coalgebras are both fixed points (that is, satisfy F (α) ' α), so the usual diagonalization argument shows that the power-set functor has neither. A sufficient condition for the existence of both is that the functor F is κ-bounded for some cardinal κ [6, 37]. To formalize these constructions in the context of simple type theory, developers of the Isabelle theorem prover [35] proposed the notion of a bounded natural functor [12, 15], or BNF for short. A functor F (α) is a BNF if it satisfies the following: There is a natural transformation set which for each α maps elements of F (α) to elements of the power set of α, such that for any pair of maps f, g : α → β and any element of x of F (α), if f and g agree on set(x), then F (f)(x) = F (g)(x). There is a fixed cardinal κ ≥ ℵ0 such that for every x, |set(x)| ≤ κ. F preserves weak pullbacks (see Section 5). The generalization to multivariate functors is straightforward. BNFs are closed under composition and formation of initial and final coalgebras, and the class of BNFs includes data type constructions such as finite sets and finite multisets. This forms the basis for a powerful and extensible data type package [12, 15]. Here we present a variation on the BNF constructions based on the notion of a quotient of a polynomial functor, or QPF for short. Like BNFs, QPFs support definitions such as the following, which defines a well-founded tree on α to consist of a node labeled by an element of α together with a finite set of subtrees : inductive tree( α : Type) | mk: α → finset tree → tree Here finset can be replaced by list, multiset, or stream, or, indeed, any QPF constructor. Moreover, replacing inductive by coinductive yields the corresponding coinductive type of arbitrary trees, not just the well-founded ones. QPFs are more general than BNFs in a sense we will make precise in Section 5, but their main appeal is that they provide another perspective on the BNF constructions, and are amenable to formalization. Our approach is well-suited to dependent type theory, and the components of our constructions, including polynomial functors, W types, M types, and quotients, are familiar inhabitants of the type theory literature. At the same time, the use of dependent types is mild, and the constructions can easily be translated to the language of set theory or simple type theory. I T P 2 0 1 9 6:4 Data Types as Quotients of Polynomial Functors We have found that working with QPFs is natural and intuitive.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages19 Page
-
File Size-