DOKK Library

Data types as quotients of polynomial functors

Authors Jeremy Avigad Mario Carneiro Simon Hudon

License CC-BY-3.0

Plaintext
Data types as quotients of polynomial functors
Jeremy Avigad
Department of Philosophy, Carnegie Mellon University
avigad@cmu.edu

Mario Carneiro
Department of Philosophy, Carnegie Mellon University
di.gama@gmail.com

Simon Hudon
Department of Philosophy, Carnegie Mellon University
simon.hudon@gmail.com

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

Supplement Material Lean formalizations are online at www.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.rec b f nil        = b
  list.rec b f (cons a l) = f a l (list.rec b f l)

We also have an induction principle:
  ∀ {α} (P : list α → Prop), P nil → (∀ a l, P l → P (cons a l)) → ∀ l, P l

            © 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. 17; pp. 17:1–17:19
                   Leibniz International Proceedings in Informatics
                   Schloss Dagstuhl – Leibniz-Zentrum für Informatik, Dagstuhl Publishing, Germany
17: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.corec f b) = fst (f b)
         tail (stream.corec f b) = stream.corec f (snd (f b))

       We also have a coinduction principle:
         ∀ {α} (R : stream α → stream α → Prop),
             (∀ x y, R x y → head x = head y ∧ R (tail x) (tail y)) →
           ∀ x y, R x y → 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                                                                17: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.



                                                                                                  ITP 2019
17:4   Data types as quotients of polynomial functors


           We have found that working with QPFs is natural and intuitive. Indeed, after hitting
       upon the notion, we discovered that Adámek and Porst [5, Proposition 5.2] have shown that a
       functor is accessible if and only if it is a quotient of a polynomial functor (see also [6, Example
       6.4]). But we have not seen constructions of initial algebras and final coalgebras carried out
       directly in these terms, and the approach via QPFs makes them easy to understand. We
       expect that the QPF perspective will also be conducive to generalizations, as discussed in
       Section 7.
           The constructions described in this paper have been formalized in Lean and are available
       online, as indicated below the abstract to this paper. Lean’s underlying logical framework, like
       that of Coq, is a variant of the Calculus of Inductive Constructions, which has a computational
       interpretation. This version provides non-nested inductive type families with only primitive
       recursors, following the specification of Dybjer [21]. On top of the core logic, Lean’s library
       includes propositional extensionality, quotient types [18, 8], and a classical choice principle
       [8]. Our constructions make use of the first two, which imply function extensionality. We
       had to use the choice principle in only one place, when constructing the QPF instance for the
       final coalgebra of a multivariate constructor. We believe the use of Lean’s built-in quotient
       types could be avoided, but we do not know whether it is possible to avoid propositional and
       function extensionality.
           We are in the process of implementing a data type package for Lean based on these
       constructions. Lean currently supports nested inductive definitions, compiling them down
       to indexed inductive definitions and compiling recursive definitions down to well-founded
       recursion along a synthesized measure of size. Our approach, like the Isabelle approach, adds
       a wealth of new constructions: not only coinductive definitions, but also arbitrary nestings
       of inductive definitions, coinductive definitions, and quotient constructions. Moreover, it
       provides principles of recursion and corecursion based on the associated functorial map.


        2     Polynomial functors
       Let us start with the notion of a polynomial functor, also known as a container [1, 2, 25].
       These are functors of the form P (α) = Σx∈A (B(x) → α), where B denotes a family of sets
       (B(x))x∈A and Σ denotes the dependent sum. Thus, an element of P (α) is a pair (a, f ) with
       a ∈ A and f : B(a) → α. Think of (a, f ) as representing a structured object with data from
       α, where a ∈ A specifies the shape of the element and f ∈ B(a) → α specifies its contents.
       In the literature on containers, the polynomial functor given by the data A and B is usually
       denoted A . B. There is an obvious functorial action: given g : α → β, P (g) maps (a, f ) in
       P (α) to (a, g ◦ f ) in P (β), preserving the shape while transforming the contents. Below, we
       will say more generally that P is a polynomial functor if it is isomorphic to one of this form.
       It is easy to define these in Lean:
         structure pfunctor := (A : Type u) (B : A → Type u)

         variable P : pfunctor.{u}

         def apply (α : Type u) := Σ x : P.A, P.B x → α

         def map {α β : Type u} (g : α → β) : P.apply α → P.apply β :=
         λ ha, fi, ha, g ◦ fi

       In these definitions, Type u denotes a fixed but arbitrary universe of types. Lean’s projection
       notation is a convenient syntactic device: since P has type pfunctor, Lean interprets P.apply
J. Avigad, M. Carneiro, and S. Hudon                                                                 17:5


as pfunctor.apply P. Similarly, the corner brackets denote anonymous constructors: since
P.apply reduces to a sigma type, Lean interprets ha, f ◦ gi as sigma.mk a (f ◦ g). We
also make use of a pattern-matching lambda, which translates the variables in the bound
pattern to applications of destructors of a single bound variable.
    Many familiar data types are polynomial functors. For instance, any list of elements of
α is given by its length, n, and a function from {0, . . . , n − 1} to α. Streams of elements
of α have only one shape, and the contents are functions from N to α. The type of lazy
lists of elements of α can be seen as the disjoint union of these two, so the set of shapes is
the disjoint union of N and a singleton. A tree with nodes labeled by α has as shape the
unlabeled tree and as contents a map from the nodes to α.
    It is not hard to show that if P (α) and Q(α) are polynomial functors, then so is their
composition, P (Q(α)). Moreover, every polynomial functor P has an initial algebra, a
familiar construct in dependent type theory known as a W type [34]. Elements of the data
type WP corresponding to P can be viewed as well-founded trees in which every node has a
label a from A and children indexed by B(a). In other words, an element of WP is given by an
element a in A and a function f : B(a) → WP . Such inductive types are given axiomatically
by Lean’s type-theoretic foundation, and can be declared as follows:

  inductive W (P : pfunctor)
  | mk (a : P.A) (f : P.B a → W) : W

The constructor forms an element of W from a ∈ A and f : B(a) → W . This is just a variant
of the usual algebra map P (W ) → W in which the argument, an element of P (W ), has been
replaced by its two components. The built-in recursion principle for the type above says
exactly that this map is the initial algebra.
    Every polynomial functor P also has a final coalgebra, known as the associated M type.
The data type MP has the same description as above except that the trees are no longer
required to be well founded. Abstractly, M types can be specified as follows:

  def M (P : pfunctor.{u}) : Type u

  def M_dest : M P → P.apply (M P)

  def M_corec : (α → P.apply α) → (α → M P)

  theorem M_dest_corec (g : α → P.apply α) (x : α) :
    M_dest (M_corec g x) = M_corec g <$> g x

  theorem M_bisim (r : M P → M P → Prop)
    (h : ∀ x y, r x y →
        ∃ a f g, M_dest x = ha, fi ∧ M_dest y = ha, gi ∧ ∀ i, r (f i) (g i)) :
      ∀ x y, r x y → x = y

The principle M_bisim is a coinduction principle for trees. Here the anonymous constructor
ha, f i is used to represent an element of P (M ) in terms of a : A and f : B(a) → M . A
bisimulation relation between trees is a relation r such that r(x, y) holds if and only if x and
y have the same branching type at the top node and the children at the top node are again
pointwise related by r. Two trees are bisimilar if there is a bisimulation between them, and
the principle M_bisim says that any two trees that are bisimilar are in fact equal.
    M types are not given axiomatically by the Calculus of Inductive Constructions, but as
the specification above suggests, they can be defined in Lean. One way to go about it is



                                                                                                   ITP 2019
17:6   Data types as quotients of polynomial functors


       to define for each n the type of trees of depth at most n, using a special node to denote
       potential continuations at the leaves:
         inductive M_approx : N → Type u
         | continue : M_approx 0
         | intro {n} : ∀ a, (P.B a → M_approx n) → M_approx (n + 1)

       We can then say what it means for an approximation of depth n to agree with one of depth
       n + 1, and define an element of the M type to be a sequence of approximations such that
       each is consistent with the next:
         inductive agree : ∀ {n : N}, M_approx P n → M_approx P (n+1) → Prop
         | continue (x : M_approx P 0) (y : M_approx P 1) : agree x y
         | intro {n} {a} (x : P.B a → M_approx P n) (y : P.B a → M_approx P (n+1)) :
           (∀ i, agree (x i) (y i)) → agree (M_approx.intro a x) (M_approx.intro a y)

         structure M := (approx : Π n, M_approx P n) (agrees : ∀ n, agree (x n) (x (n+1)))

           We will see in Section 4 that these considerations extend to the multivariate case. In
       other words, there is a natural notion of an n-ary polynomial functor, and if P (~    α, β) is an
       (n + 1)-ary polynomial functor, then for each fixed tuple α  ~ , it has an initial algebra W (~α)
       and a final coalgebra M (~  α). Moreover, W (~α) and M (~α) are polynomial functors in α  ~.
           In short, polynomial functors are closed under composition, initial algebras, and final
       coalgebras, and so seem to have all the virtues of BNFs. Why not take them as the basis for
       a data type package?
           The answer is that the class of polynomial functors is not as general as the class of
       BNFs. For example, although the type finset(α) of finite sets of elements of α and the type
       multiset(α) of finite multisets of elements of α are both BNFs, cardinality considerations
       can be used to show that they are not polynomial functors. For another view of what goes
       wrong, note that if we map the finite set {1, 2} under a function which sends both 1 and 2 to
       3, we get the set {3}, which does not have the same shape.
           But we can view finset(α) as a quotient of a polynomial functor, namely, the quotient
       of list(α) that identifies any two lists that have the same elements. Similarly, we can view
       multiset(α) as the quotient of list(α) by equivalence up to permutation. This points the
       way to a solution: rather than consider only polynomial functors, we should consider their
       quotients as well.


        3     Quotients of polynomial functors

       A natural way to say that a functor F (α) is a quotient of the polynomial functor P (α) is to
       say that, for every α, there is a surjective function abs from P (α) to F (α). Think of elements
       of P (α) as being concrete representations of more abstract objects in F (α). We can express
       the fact that abs is surjective by supplying a right inverse, repr, which maps any element
       of F (α) to some representative in P (α). Finally, we should assert that abs is a natural
       transformation between P and F , which is to say, it respects their functorial behavior:

                                                      P (f )
                                              P (α)            P (β)
                                            absα                  absβ
                                                      F (f )
                                              F (α)            F (β)
J. Avigad, M. Carneiro, and S. Hudon                                                                     17:7


Remember that given f : α → β, there is a map P (f ) from P (α) to P (β). We require this
map to be preserved by abs, so that absβ ◦ P (f ) = F (f ) ◦ absα . In other words, mapping a
representation x and then abstracting it should yield the same result as abstracting it and
then mapping it, making the square above commute.
   In Lean, we can specify that F is a quotient of a polynomial functor as follows:
  class qpf (F : Type u → Type u) [functor F] :=
  (P         : pfunctor.{u})
  (abs       : Π {α}, P.apply α → F α)
  (repr      : Π {α}, F α → P.apply α)
  (abs_repr : ∀ {α} (x : F α), abs (repr x) = x)
  (abs_map   : ∀ {α β} (f : α → β) (p : P.apply α), abs (f <$> p) = f <$> abs p)

One can show that every BNF can be represented in this way. (Briefly, if κ is the relevant
cardinal bound, we can take the shapes in the polynomial functor to be the set of pairs of
the form (I, F (I)) with I ⊆ κ, and the contents of such a shape to be indexed by I.)
    To see that every QPF has an initial algebra, suppose that F is a quotient of P in the
sense above. Let W be the initial P -algebra. We want to construct the least fixed point fix
of F . By initiality, there is an isomorphism between W and P (W ), so every tree in W can
be viewed as consisting of a shape, a ∈ A, and a sequence f : B(a) → W of subtrees. Via the
abs function, these represent an element of F (W ). The problem is that multiple elements of
P (W ) can represent the same element of F (W ), so that multiple elements of W can represent
the same element of F (W ). So already W looks like an overapproximation to fix. Moreover,
recursively, under the functorial map for F , F (W ) is again an overapproximation to F (fix).
    The solution is to say what it means for two elements of W to represent the same element
of fix, and then define fix to be the quotient of W by that equivalence relation. The relation
we are after is the smallest equivalence relation closed under the following two rules:

    abs(a, f ) = abs(a0 , f 0 )   ∀x (f (x) ≡ f 0 (x))
       ha, f i ≡ ha0 , f 0 i       ha, f i ≡ ha, f 0 i

The key condition is the first one, which says that two trees represented by (a, f ) and (a0 , f 0 )
are equivalent if their abstractions are the same element of F (W ). The second clause extends
the relation recursively to trees with the same shape and equivalent subtrees. The relation is
defined inductively in Lean as follows:
  inductive Wequiv : q.P.W → q.P.W → Prop
  | abs (a : q.P.A) (f : q.P.B a → q.P.W) (a' : q.P.A) (f' : q.P.B a' → q.P.W) :
      abs ha, fi = abs ha', f'i → Wequiv ha, fi ha', f'i
  | ind (a : q.P.A) (f f' : q.P.B a → q.P.W) :
      (∀ x, Wequiv (f x) (f' x)) → Wequiv ha, fi ha, f'i
  | trans (u v w : q.P.W) : Wequiv u v → Wequiv v w → Wequiv u w

Notationally, here q is the relevant QPF structure, q.P is the polynomial functor, and q.P.W
denotes the associated W construction, a function of q.P. The third clause ensures that the
relation is transitive, and hence an equivalence relation. We then define fix to be the quotient:
  def fix (F : Type u → Type u) [functor F] [q : qpf F] :=
  quotient (Wsetoid : setoid q.P.W)

Wsetoid bundles Wequiv with a proof that the latter is an equivalence relation. Any function
g : F (W ) → β gives rise to a function g 0 : P (W ) → β defined by g 0 = g ◦ repr, and so we can
use g to define functions by recursion on W :



                                                                                                       ITP 2019
17:8   Data types as quotients of polynomial functors



         def recF {α : Type u} (g : F α → α) : q.P.W → α
         | ha, fi := g (abs ha, λ x, recF (f x)i)

       This is just an ordinary recursion on W , using repr to mediate the difference between P and
       F . Moreover, any function defined by such a recursion will respect the equivalence relation
       Wequiv, and so lifts to a function from fix to α.
         def fix.rec {α : Type u} (g : F α → α) : fix F → α :=
         quot.lift (recF g) (recF_eq_of_Wequiv g)

       We can map any tree W to a canonical representative, in such a way that any two equivalent
       trees are mapped to the same representative. This gives us a choice-free way of mapping
       fix back to W . Composing maps F (fix) → P (fix) → P (W ) → W → fix gives us the desired
       constructor. With these definitions, we can prove:
         theorem fix.rec_eq {α : Type u} (g : F α → α) (x : F (fix F)) :
           fix.rec g (fix.mk x) = g (fix.rec g <$> x)

         theorem fix.ind_rec {α : Type u} (g g' : fix F → α)
             (h : ∀ x : F (fix F), g <$> x = g' <$> x → g (fix.mk x) = g' (fix.mk x)) :
           ∀ x, g x = g' x

         theorem fix.ind (p : fix F → Prop)
             (h : ∀ x : F (fix F), liftp p x → p (fix.mk x)) :
           ∀ x, p x

       The last theorem above expresses the induction principle, defined in terms of a predicate
       lifting operation defined in Section 5. The second-to-last theorem implies the uniqueness of
       functions satisfying the defining equations for the recursor.
            With the recursor, we can then define a destructor from fix to F (fix) and prove that it is
       an inverse to the constructor. This completes the construction of the initial algebra for any
       unary quotient of polynomial functors.
            We can analogously construct the greatest fixed point of F (α) as a suitable quotient of
       MP . Remember that the M -type analogue of the principle of induction on a W type is the
       bisimulation principle, M_bisim, presented at the end of the last section. The corresponding
       version for the final algebra should look like this:
         theorem cofix.bisim (r : cofix F → cofix F → Prop)
             (h : ∀ x y, r x y → liftr r (cofix.dest x) (cofix.dest y) :
           ∀ x y, r x y → x = y

       The function liftr in the statement of the principle refers to the canonical method of lifting
       a binary relation r on α to a relation r̂ on F (α), described in Section 5. One strategy of
       constructing the final coalgebra cofix, familiar from the literature on set-valued functors
       (e.g. [37]), is to define the relation R to be the union of all bisimulation relations on the
       underlying M type, and then define cofix to be the the quotient M/R. For that proof to
       go through, we need to know that the union of all bisimulation relations is an equivalence
       relation, which in turn requires showing that the composition of bisimulation relations is
       again a bisimulation. And that can be shown as a consequence of the fact that the function
       F (α) preserves weak pullbacks. This explains why this assumption appears in Isabelle’s
       definition of BNFs.
           Going back to an early paper by Aczel and Mendler [4], however, we were able to find a
       construction that avoids the additional assumption. The trick is to use an alternative notion
J. Avigad, M. Carneiro, and S. Hudon                                                                       17:9


of lift for binary relations on a set α. Given a binary relation r on α, let qr be the quotient
map corresponding to the least equivalence relation on α that includes r. We can then define
the alternative notion of lift which holds of x and y in F (α) if and only if F (qr )(x) = F (qr )(y).
In other words, rather than lift the relation, we map the quotient function. We now define
two elements of M to bear this lifted version of r if their F -abstractions do, and define cofix
to be the quotient under the union of all such relations.
  def is_precongr (r : q.P.M → q.P.M → Prop) : Prop :=
  ∀ {x y}, r x y → abs (quot.mk r <$> M_dest x) = abs (quot.mk r <$> M_dest y)

  def Mcongr : q.P.M → q.P.M → Prop := λ x y, ∃ r, is_precongr r ∧ r x y

  def cofix (F : Type u → Type u) [functor F] [q : qpf F]:= quot (@Mcongr F _ q)

It is especially convenient that Lean’s fundamental quotient construction, quot.mk r, does
not require r to be an equivalence relation. (The axioms governing quotients in Lean imply
that the result is equivalent to quotienting by the equivalence relation generated by r.) We
can show that quotient by a finer relation factors through the quotient by a coarser one:
  def factor {α : Type*} (r s : α → α → Prop) (h : ∀ x y, r x y → s x y) :
    quot r → quot s :=
  quot.lift (quot.mk s) (λ x y rxy, quot.sound (h x y rxy))

  def factor_mk_eq {α : Type*} (r s: α → α → Prop) (h : ∀ x y, r x y → s x y) :
    factor r s h ◦ quot.mk r = quot.mk s := rfl

With this fact, we can use the bisimulation principle on M to derive the bisimulation principle
on the quotient. When the dust settles, we have all the desired functions and properties:
  def cofix.dest : cofix F → F (cofix F)

  def cofix.corec {α : Type u} (g : α → F α) : α → cofix F

  theorem cofix.dest_corec {α : Type u} (g : α → F α) (x : α) :
    cofix.dest (cofix.corec g x) = cofix.corec g <$> g x

  theorem cofix.bisim_rel (r : cofix F → cofix F → Prop)
      (h : ∀ x y, r x y →
        quot.mk r <$> cofix.dest x = quot.mk r <$> cofix.dest y) :
    ∀ x y, r x y → x = y

Since identity under the mapped quotients of r is implied by the lift of r, this formulation of
the bisimulation principle implies cofix.bisim above, as well as the following variation:
  theorem cofix.bisim' {α : Type u} (q : α → Prop) (u v : α → cofix F)
      (h : ∀ x, q x → ∃ a f f',
        cofix.dest (u x) = abs ha, fi ∧
        cofix.dest (v x) = abs ha, f'i ∧
        ∀ i, ∃ x', q x' ∧ f i = u x' ∧ f' i = v x') :
    ∀ x, q x → u x = v x

   It is, moreover, straightforward to show that quotients of polynomial functors are closed
under composition and quotients:
  def comp {G : Type u → Type u} [functor G] [qpf G]
           {F : Type u → Type u} [functor F] [qpf F] :




                                                                                                         ITP 2019
17:10   Data types as quotients of polynomial functors


             qpf (functor.comp G F)

          def quotient_qpf {F : Type u → Type u} [functor F] [qpf F]
                           {G : Type u → Type u} [functor G]
              {abs : Π {α}, F α → G α}
              {repr : Π {α}, G α → F α}
              (abs_repr : Π {α} (x : G α), abs (repr x) = x)
              (abs_map : ∀ {α β} (f : α → β) (x : F α abs (f <$> x) = f <$> abs x) :
            qpf G

        In short, we have shown that unary QPFs support the same constructions as unary BNFs.
        We now turn to the multivariate case.


         4     Multivariate constructions

        A ternary functor on F (α, β, γ) on sets is one that is functorial in each argument. Our goal
        is to extend the notion of a QPF to such functors, and, indeed, functors of arbitrary arity.
        In this respect, dependent type theory offers a distinct advantage over simple type theory:
        whereas Isabelle’s BNF package has to synthesize definitions of n-ary functors dynamically
        for each n, in dependent type theory we can treat an n-tuple of types as a first-class object
        parameterized by n. This facilitates the implementation of a data type package, as discussed
        in Section 6.
            Formally, we define an n-tuple of types to be a function from a canonical finite type fin(n)
        of elements to an arbitrary type universe:
          def typevec (n : N) := fin n → Type*

        We can then define the usual morphisms on the category of n-tuples, namely, n-tuples of
        functions, with composition and identity.
          def arrow (α β : typevec n) := Π i : fin n, α i → β i

          infixl ` =⇒ `:40 := arrow

          def id {α : typevec n} : α =⇒ β := λ i x, x

          def comp {α β γ : typevec n} (g : β =⇒ γ) (f : α =⇒ β) : α =⇒ γ :=
          λ i x, g i (f i x)

          infixr `     `:80 := typevec.comp

        Lean’s notions of functor (a type constructor with a map function) and lawful functor (a
        functor satisfying the usual laws) carry over straightforwardly to the multivariate setting:
          class mvfunctor {n : N} (F : typevec n → Type*) :=
          (map : Π {α β : typevec n}, (α =⇒ β) → (F α → F β))

          infixr ` <$$> `:100 := mvfunctor.map

          class is_lawful_mvfunctor {n : N} (F : typevec n → Type*) [mvfunctor F] :=
          (id_map   : Π {α : typevec n} (x : F α), id <$$> x = x)
          (comp_map : Π {α β λ : typevec n} (g : α =⇒ β) (h : β =⇒ λ) (x : F α),
                            (h    g) <$$> x = h <$$> g <$$> x)
J. Avigad, M. Carneiro, and S. Hudon                                                                    17:11


Notice that we use the notation f <$$> x to denote the functorial map of the n-tuple of
functions f on the element x, where x is an element of the multivariate F (~ α). With these
definitions and notation, the definition of a multivariate QPF is almost exactly the same as
the definition of a unary one:
  class mvqpf {n : N} (F : typevec.{u} n → Type*) [mvfunctor F] :=
  (P         : mvpfunctor.{u} n)
  (abs       : Π {α}, P.apply α → F α)
  (repr      : Π {α}, F α → P.apply α)
  (abs_repr : ∀ {α} (x : F α), abs (repr x) = x)
  (abs_map   : ∀ {α β} (f : α =⇒ β) (p : P.apply α),
                 abs (f <$$> p) = f <$$> abs p)

    We need to show that if F (~   α, β) is an (n + 1)-ary QPF, then for each tuple α ~ it has both
an initial algebra fix(~α) and a final coalgebra cofix(~α), and, moreover, that the latter are n-ary
functors in α~ . The constructions require operations append1(~   α, β) for extending an n-tuple of
types α~ by a single type β, and operations drop(~   α) and last(~α) that return the initial n-tuple
and final elements of such an (n + 1)-tuple. Similarly, we need an operation append-fun(f, g)
that appends a function to an n-tuple of functions, and operations drop-fun and last-fun that
destruct the resulting (n + 1)-tuple. One minor problem is that constructions like these
sometimes give rise to types that are provably but not definitionally equal. For example,
append1(drop(~   α), last(α)) is provably equal to α ~ , but we need an explicit cast from one to
the other if we want expressions to type check. Such difficulties were mild, and they were a
small price to pay for the benefits of being able to reason about arbitrary tuples uniformly.
    With a formal theory of tuples of types and maps between them, unary notions carry
over nicely to the multivariate setting. The definition of a multivariate polynomial functor
P (~
   α) is straightforward:
  structure mvpfunctor (n : N) := (A : Type.{u}) (B : A → typevec.{u} n)

  variables {n : N} (P : mvpfunctor.{u} n)

  def apply (α : typevec.{u} n) : Type u := Σ a : P.A, P.B a =⇒ α

  def map {α β : typevec n} (f : α =⇒ β) : P.apply α → P.apply β :=
  λ ha, gi, ha, f  gi

As before, we can think of an element of P (~    α) as consisting of a shape, a, and a map
f : B(a) =⇒ α ~ . All that has changed is that the contents now consist of tuples of functions.
    Given an (n + 1)-ary polynomial functor P (~ α, β), we need to construct its initial algebra,
W (~α), and show that it is again a polynomial functor. Intuitively, each element of W (~     α)
is a well-founded tree, in which each node is labeled by an element of A together with
a function f 0 : drop(B(a)) =⇒ α  ~ , and the children of that node are given by a function
f : last(B(a)) → W (~ α):

                                               (a, f 0 )



                              f (i0 )    f (i1 )       f (i2 )   f (. . .)

There are various ways to view such a tree. One is as an ordinary unary W type, where
the set of shapes at each node is given by A0 = Σa∈A (drop(B(a)) → α
                                                                   ~ . Given an element



                                                                                                       ITP 2019
17:12   Data types as quotients of polynomial functors


        p = (a, f 0 ) of A0 , the set of indices B 0 (p) = last(B(p.fst)) depends only on the first component.
        This, however, introduces an artificial dependency of the index set of the branches on the
        contents f 0 . A slightly modified description is to view the W (~     α) as given inductively by the
        following constructor and recursion principle:
          def W_mk {α : typevec n} (a : P.A) (f' : P.drop.B a =⇒ α)
            (f : P.last.B a → P.W α) : P.W α

          def W_rec {α : typevec n} {C : Type*}
            (g : Π a : P.A, ((P.drop).B a =⇒ α) → ((P.last).B a → P.W α) →
              ((P.last).B a → C) → C) : P.W α → C

        In words, an element of W (~ α) is given inductively by a triple (a, f 0 , f ) where a is in A, f 0
        is a tuple of functions from drop(B(a)) to α~ , and f 0 is a function from last(B(a)) to W (~  α).
        The induction principle and defining equations for the recursor are as expected.
            An alternative view of W (~
                                      α) makes it clear that it is a polynomial functor. As the picture
        suggests, we can think of an element of W (~   α) as having the shape of a well-founded tree
        with labels from A, with children at a node labeled a indexed by the set last(B(a)). In other
        words, the shape is just the ordinary W type given by these data. The contents of the tree
        amount to the sum total of all the functions f 0 at each node. We can combine these into one
        big function from the disjoint union of all the index sets drop(B(a)) at all the nodes. This
        disjoint union can be conveniently described by an inductive definition:
          inductive W_path : P.last.W → fin n → Type u
          | root (a : P.A) (f : P.last.B a → P.last.W) (i : fin n) (c : P.drop.B a i) :
              W_path ha, fi i
          | child (a : P.A) (f : P.last.B a → P.last.W) (i : fin n) (j : P.last.B a)
              (c : W_path (f j) i) : W_path ha, fi i

        Here, P.last denotes the polynomial functor just described, and P.last.W is the correspond-
        ing W type, which we take to be the shape of W (~α). The type W_path describes the index set
        associated to this shape as the sum of the index sets P.drop.B a i for each i < n, together
        with the index sets assigned to all the children. This gives us the desired representation of
        W (~α) as a multivariate polynomial functor:
          def Wp : mvpfunctor n := { A := P.last.W, B := P.W_path }

            There are two things worth noting here. First, the type of W_path is equivalent to
        P.last.W =⇒ typevec n. This makes use of the specific representation of typevec n, but
        this use is not essential; with another representation, we could still define W_path as above,
        and then compose it with the relevant isomorphism. The second thing to note is that the
        analogous inductive definition works just as well for M types, since it does not require the
        tree to be well founded.
            Both characterizations of W (~  α) are essential. The first description, the inductive one,
        allows us to carry out the construction of the initial algebra. The second description of W (~
                                                                                                     α),
        as a polynomial functor, enables us to show that the initial algebra of a QPF is again a QPF.
        Rather than define both objects and prove them isomorphic, we found it more convenient to
        take the second description to be the official definition of W (~ α) and use that to define the
        constructor and recursor specified by the first description.
            Coordinating the different notions of a polynomial functor was the most difficult part
        of extending the constructions from the unary to the multivariate setting. With these
        characterizations of W (~  α), the construction of the initial algebra fix(~
                                                                                   α) of a multivariate
J. Avigad, M. Carneiro, and S. Hudon                                                                     17:13


QPF F (~ α, β) is almost line-by-line the same as the construction in the unary case, replacing
unary primitives with their multivariate counterparts. Suppose F (~    α, β) is a quotient of the
polynomial functor of P (~  α, β). The associated W (~  α) is again a polynomial functor, and
fix(~
    α) is defined as a quotient of that. It is not hard to define the map on fix(~ α) in terms of
the map on W (~   α), and then use the QPF property of F to show that the maps commute
with the abstraction function from W (~    α) to fix(~
                                                     α). In short, we have that if F (~ α, β) is a
multivariate QPF, then so is fix(~  α).
    The construction of the final coalgebra cofix(~  α) is similar: the approach above can be
used to construct the M types M (~     α) as polynomial functors, and, once again, the unary
construction carries over. Showing that multivariate QPFs are closed under compositions
and quotients is once again straightforward.


 5     Lifting predicates and relations
Let F be any set-valued functor. By definition, F allows us to map any function f : α → β
to a function from F (α) → F (β), enabling us to reason about the behavior of f under F .
For instance, list(f ) applies f to every element of a list, and finset(f ) maps any finite set s
to f [s], the image of s under f .
    Sometimes it is useful to reason about the behavior of predicates and relations as well. A
standard way of doing that is to consider their lifts [33, 36, 38], defined as follows. Let p be
any predicate on α. Then there is an inclusion map ι : {u ∈ α | p(u)} → α, and saying that
p(u) holds is equivalent to saying that u is in the image of ι. To lift p to F (α), consider the
map F (ι) : F ({u | p(u)}) → F (α), and given any element x of F (α), say that the lift p̂ holds
of x if and only if there is an element z of F ({u | p(u)}) such that F (ι)(z) = x.
    Similarly, if r(u, v) is a binary relation between α and β, we can lift r to a relation r̂
between F (α) and F (β) as follows. Consider the set {(u, v) ∈ α × β | r(u, v)} of pairs, and
the two projections π0 and π1 . Given x in F (α) and y in F (β), say that r̂(x, y) holds if there
is an element z of F ({(u, v) | r(u, v)}) such that F (π0 )(z) = x and F (π1 )(z) = y.
    It is straightforward to define these notions in the type-theoretic setting, with types and
subtypes in place of sets and subsets.
  def liftp {α : Type u} (p : α → Prop) : F α → Prop :=
  λ x, ∃ z : F (subtype p), subtype.val <$> z = x

  def liftr {α : Type u} (r : α → β → Prop) : F α → F β → Prop :=
  λ x y, ∃ z : F {p : α × β // r p.fst p.snd},
    (λ t, t.val.fst) <$> z = x ∧ (λ t, t.val.snd) <$> z = y

    If P is a polynomial functor, p is a predicate on α, and x is in P (α), it is easy to check
that p̂(x) holds if and only if x is of the form (a, f ) and for every i ∈ B(a), p(f (i)). Similarly,
for a relation r between α and β, x in P (α), and y ∈ P (β), r̂(x, y) if and only if there
are a, f , and f 0 such that x is of the form (a, f ), y is of the form (a, f 0 ) and for every i,
r(f (i), f 0 (i)). In words, r̂(x, y) holds if x and y have the same shape and their contents are
pointwise related. If F is a quotient of a polynomial functor, the statements are the same up
to a choice of representative.

I Theorem 1. Let F be a QPF, let p be a predicate on α, and r be a binary relation between
α and β.
   p̂(x) holds if and only if there are a and f such that x = abs(a, f ) and, for every i,
   p(f (i)).



                                                                                                        ITP 2019
17:14   Data types as quotients of polynomial functors


           r̂(x, y) holds if and only if there are a, f, f 0 such that x = abs(a, f ), y = abs(a, f 0 ), and
           for every i, r(f (i), f 0 (i)).

             Lifting extends straightforwardly to multivariate QPFs: if F (~α) is an n-ary QPF, we can
        lift n-ary tuples of predicates and n-ary tuples of relations analogously, and the corresponding
        version of Theorem 1 holds.
             We can use these notions to clarify the additional structure that comes with the Isabelle
        formulation of a BNF. If F is a QPF and x is an element of F (α), intuitively, p̂(x) says that
        p holds of the contents of x. When F is a polynomial functor, this is literally true, but the
        possibility of multiple representations in a QPF muddies the waters. We would like to have
        a function supp(x), the “support” of x, such that for every predicate p on α and x in F (α),
        we have p̂(x) ↔ ∀u ∈ supp(x) p(u). Call this condition (∗).

        I Theorem 2. Let F be any set-valued functor. If supp satisfies (∗), then for any x ∈ F (α)
                                                   T
        we have supp(x) = {u | ∀p (p̂(x) → p(u))} = {β | β ⊆ α ∧ x ∈ Im F (ιβ→α )}, where ιβ→α is
        the inclusion map from β to α.

        Proof. We check the first equation, and leave it to the reader to verify the second. Suppose
        u ∈ supp(x) and p̂(x). Then (∗) implies that p(u) holds. For the converse, note that
        taking p(u) to be u ∈ supp(x) in (∗), it is immediate that p̂(x) holds. So any u satisfying
        ∀p (p̂(x) → p(u)) is an element of supp(x).                                               J

        I Theorem 3. Let F be a QPF, and let supp(x) = {u | ∀p (p̂(x) → p(u))}.
                                     T
           For every x, supp(x) = {Im f | abs(a, f ) = x}.
           Condition (∗) holds at x for every p if and only if there are a, f such that abs(a, f ) = x
          and for every a0 , f 0 such that abs(a0 , f 0 ) = x, Im f ⊆ Im f 0 .

        Proof. For the first clause, let x be arbitrary, and suppose p̂(x) implies p(u) for every p. If
        x = abs(a, f ), let p be the predicate u ∈ Im f . Then it is easy to check that p̂(x) holds, and
        hence p(u). Conversely, suppose u is an element of the right-hand side and p is a predicate
        such that p̂(x) holds. Then there are a and f such that abs(a, f ) = x and such that p(f (i))
        holds for every i. Hence p(u).
           For the forward direction of the second clause, note that if p(u) is the predicate u ∈ supp(x),
        then, by (∗), we have p̂(x). The conclusion follows from Theorem 2 and the first clause.
        Using the first clause, the converse direction of the second clause is also straightforward. J

            Theorem 3 says that condition (∗) holds for a QPF F if and only if every element x of
        F (α) has a representation (a, f ) whose contents are minimal, and these contents determine
        which lifted predicates hold. Unfortunately, there is nothing in the definition of a QPF that
        rules out representations having superfluous elements, but the next theorem shows that
        adding this as an additional assumption has pleasant consequences.

        I Theorem 4. Let F be a QPF satisfing the additional property that for every a, f , a0 , and
        f 0 , if abs(a, f ) = abs(a0 , f 0 ), then Im f = Im f 0 . Then:
              supp satisfies (∗), and whenever x = abs(a, f ), supp(x) = Im f .
              For every x in F (α) and g : α → β, supp(F (g)(x)) = g[supp(x)].

             In other words, with the additional assumption, our function supp has the same properties
        as the function set associated to Isabelle’s BNFs.
             BNFs have one additional property, which can also conveniently be expressed in terms of
        lifts. If r is a relation between α and β and s is a relation between β and γ, the composition
        r ◦ s is defined by (r ◦ s)(u, w) ≡ ∃v (r(u, v) ∧ s(v, w)). It is straightforward to show from the
J. Avigad, M. Carneiro, and S. Hudon                                                                    17:15


definition of lifting that for every x in F (α) and z in F (γ), rd◦ s(x, z) implies (r̂ ◦ ŝ)(x, z).
But the converse does not necessarily hold, and the special case where F is a QPF gives an
inkling of what can go wrong: the fact that there is a shape that relates x to y by r̂ and
another shape that relates y to z by ŝ does not necessarily mean there is a single shape that
does both, and hence relates x and z by rd   ◦ s.
    When the converse does hold for every r and s, F is said to preserve weak pullbacks. This
is a useful property: it implies that the composition of bisimulation relations relative to
F is again a bisimulation relation. There are, however, interesting examples of QPFs that
do not preserve weak pullbacks, such as a bounded finite powerset, which for some fixed k
returns the collection of finite subsets with at most k elements. For details and alternative
characterizations of preservation of weak pullbacks, see [6, 33, 36, 38], and for more instances
of QPFs that do not preserve them, see [4, Section 6] and [28, Section 6.4].


 6     Implementation

We are currently writing a data type compiler for Lean that builds on the formal constructions
just described. The compiler, which is implemented entirely in Lean’s metaprogramming
framework [22], introduces the keywords data and codata into Lean’s normal syntax and
translates each data type specification into a number of definitions. Whereas the Isabelle
implementation has to construct n-ary instances of the constructions for each fixed n, the
uniform theory of multivariate constructions described in Section 4 simplifies the expressions
we need to construct, and therefore reduces the likelihood of failure at compile time.
    The commands data and codata, respectively, declare the initial algebra and final
coalgebra of a multivariate QPF F (~α, β). In our implementation, we refer to F as the shape
of the declaration. The key insight is that both the functor and its representation as a QPF
can be synthesized from the syntactic specification. Consider the following input:
  data tree (α β : Type) : Type
  | leaf : tree
  | node : α → (β → tree) → tree

This describes the type of trees in which every internal node has a label from α and a sequence
of children indexed by β. Since β occurs in a negative position, our compiler interprets that
as a dead parameter. It then replaces tree with a parameter X and interprets the resulting
shape as a binary functor Fβ (α, X).
  inductive tree.shape (α : Type) (β : Type) (X : Type) : Type
  | nil : tree.shape
  | cons : α → (β → X) → tree.shape

  def tree.shape.internal (β : Type) : typevec 2 → Type
  | hα, Xi := shape α β X

Note that the internal version bundles α and X together into a vector of length 2. The next
task is to synthesize a QPF instance. In general, the arguments to each constructor are
compositions of QPFs, so the entire shape, a sum of products of QPFs, is again a QPF.
  instance (β : Type) : mvfunctor (tree.shape.internal β) := . . .
  instance (β : Type) : mvqpf (tree.shape.internal β) := . . .

We then use the generic QPF fix construction to define the initial fixed point.



                                                                                                       ITP 2019
17:16   Data types as quotients of polynomial functors



            def tree.internal (β : Type) (v : typevec 1) : Type :=
            fix (list.shape.internal β) v

            def tree (α β : Type) : Type := tree.internal β dαe

            instance (β : Type) : mvfunctor (tree.internal β) := . . .
            instance (β : Type) : mvqpf (tree.internal β) := . . .

        We can then define the constructors, destructors, recursor, and so on:
            def tree.nil (α β : Type) : tree α β := . . .

            def tree.cons (α β : Type) (x : α) (xs : β → tree α β) : tree α β := . . .

            def tree.cases_on {α β : Type} {C : tree α β → Sort u_1} (n : tree α β) :
              C (tree.nil α β) →
              (Π (a : α) (a_1 : β → tree α β), C (tree.cons α β a a_1)) →
              C n := . . .

            def tree.rec {α β X : Type} : X → (α → (β → X) → X) → tree α β → X := . . .

        If we replace data by codata, we get the corresponding coinductive type. It has same
        constructors and destructors, but, instead, the following corecursor and bisimulation principle:
            def tree'.corec :
              Π (α β α_1 : Type), (α_1 → shape α β α_1) → α_1 → tree' α β := . . .

            def tree'.bisim : ∀ (α β : Type) (r : tree' α β → tree' α β → Prop),
              (∀ (x y : tree' α β),
                  r x y → mvfunctor.liftr (typevec.rel_last dαe r) (mvqpf.cofix.dest x)
                (mvqpf.cofix.dest y)) →
              ∀ (x y : tree' α β), r x y → x = y := . . .

        Our work on the compiler is still in progress: we do not yet handle nested data types in the
        specification of the shape or present lifted predicates and relations in a user-friendly way. We
        also intend to write an equation compiler to support more natural ways to define functions.

            7   Conclusions and related work
        We have shown that the representation of data types as quotients of polynomial functors
        is natural, and facilitates important data type constructions. Surprisingly, the bulk of
        our formalization deals with constructions that are intuitively straightforward, like the
        representations of multivariate W and M types as polynomial functors as described in
        Section 4. It is notable that, with this infrastructure, our constructions of the initial algebras
        and final coalgebras require only a few hundred lines of code.
            Other theorem provers such as Coq [26] and Agda1 support coinductive types and
        corecursion by extending the trusted kernel. Here we have followed Isabelle’s approach by
        constructing such data types explictly, without extending the axiomatic framework. We made
        use of a quotient construction that is given axiomatically in Lean, though other libraries,
        including Isabelle’s, take a definitional approach to quotients as well [17, 27, 29]. Tassi


        1
            https://agda.readthedocs.io/en/latest/language/coinduction.html
J. Avigad, M. Carneiro, and S. Hudon                                                                 17:17


has recently developed methods for generating induction principles and other theorems to
support the use of inductive types in Coq [40]. In a sense, this serves to recover some of the
benefits of the more modular approaches given by BNFs and QPFs.
    Abbot et al. [2] have considered quotients of polynomial functors by equivalence with
respect to sets of permutations of the indices associated to each shape, and they have shown
that these have nice computational properties. Such quotients are special cases of QPFs.
Polynomial functors are closely related to species [30], but, as noted by Yorgey [41, Section 8],
the precise relationship between polynomial functors and species is not yet well understood.
    There are a number of ways that our work can be extended. Our constructions currently
yield nondependent types and nondependent recursion and corecursion principles, so an
obvious task is to work out and formalize the semantics of indexed inductive and coinductive
data types. To that end, work by Altenkirch et al. [7] on indexed polynomial functors provides
a good starting point. We are grateful to an anonymous referee for pointing out that there
is nothing special about fin(n) in the definition of mvfunctor in Section 4, and so replacing
fin(n) by an arbitrary index type I is an easy first step towards handling families of types.
The latter would also require generalizing our constructions to handle functors on categories
other than the category of types (in this case, categories of indexed families). The paper by
Blanchette et al. [16] shows how to achieve nonuniform forms of recursion and corecursion
with BNFs, which can be seen as a step towards handling such dependencies. Dependent
families would provide us with a shortcut to defining mutual inductive and coinductive
definitions, currently handled by Isabelle’s BNF package but not ours. Blanchette et al. [14]
have shown that restricting morphisms to permutations can be used to model data types
with binders.
    We have not dealt with the computational interpretation of corecursion or code extraction
at all. Even though most of our formalization is constructive, the defining equations for
corecursion do not correspond to computational reductions in our underlying definitions.
Firsov and Stump [23] show how to model inductive types in a computational type theory
extending the calculus of constructions with implicit products, heterogeneous equality, and
intersection types. It would be interesting to know whether coinductive types can be modeled
in a similar way. Blanchette et al. [13] provide a nice overview of various approaches to
computational intepretation of corecursion, and Basold and Geuvers [10, 11] provide a
computational analysis of dependent versions of a type theory with both recursion and
corecursion. We are hopeful that quotients of polynomial functors can provide insight into
the semantics of such a system.


     References
 1   Michael Gordon Abbott, Thorsten Altenkirch, and Neil Ghani. Categories of containers. In
     Andrew D. Gordon, editor, Foundations of Software Science and Computational Structures
     (FOSSACS) 2003, pages 23–38. Springer, 2003. doi:10.1007/3-540-36576-1_2.
 2   Michael Gordon Abbott, Thorsten Altenkirch, Neil Ghani, and Conor McBride. Constructing
     polymorphic programs with quotient types. In Dexter Kozen and Carron Shankland, editors,
     Mathematics of Program Construction (MPC) 2004, pages 2–15. Springer, 2004. doi:10.1007/
     978-3-540-27764-4_2.
 3   Peter Aczel. Non-well-founded sets. Stanford University, Center for the Study of Language
     and Information, Stanford, CA, 1988.
 4   Peter Aczel and Nax Mendler. A final coalgebra theorem. In Category theory and computer
     science, pages 357–365. Springer, Berlin, 1989. doi:10.1007/BFb0018361.
 5   Jiri Adámek and H.-E. Porst. On tree coalgebras and coalgebra presentations. Theoret.
     Comput. Sci., 311(1-3):257–283, 2004. doi:10.1016/S0304-3975(03)00378-5.




                                                                                                    ITP 2019
17:18   Data types as quotients of polynomial functors


         6   Jiří Adámek, Stefan Milius, and Lawrence S. Moss. Fixed points of functors. J. Log. Algebr.
             Methods Program., 95:41–81, 2018. doi:10.1016/j.jlamp.2017.11.003.
         7   Thorsten Altenkirch, Neil Ghani, Peter Hancock, Conor McBride, and Peter Morris. Indexed
             containers. J. Funct. Programming, 25:e5, 41, 2015. doi:10.1017/S095679681500009X.
         8   Jeremy Avigad, Soonho Kong, and Leonardo de Moura. Theorem proving in Lean. Online
             documentation. URL: https://leanprover.github.io/theorem_proving_in_lean/.
         9   Michael Barr. Terminal coalgebras in well-founded set theory. Theoret. Comput. Sci., 114(2):299–
             315, 1993. doi:10.1016/0304-3975(93)90076-6.
        10   Henning Basold. Mixed Inductive-Coinductive Reasoning Types, Programs and Logic. PhD
             thesis, Radboud Universiteit Nijmegen, 2018.
        11   Henning Basold and Herman Geuvers. Type theory based on dependent inductive and
             coinductive types. In Martin Grohe, Eric Koskinen, and Natarajan Shankar, editors, Logic in
             Computer Science (LICS) 2016, pages 327–336. ACM, 2016. doi:10.1145/2933575.2934514.
        12   Julian Biendarra, Jasmin Christian Blanchette, Aymeric Bouzy, Martin Desharnais, Mathias
             Fleury, Johannes Hölzl, Ondrej Kuncar, Andreas Lochbihler, Fabian Meier, Lorenz Panny,
             Andrei Popescu, Christian Sternagel, René Thiemann, and Dmitriy Traytel. Foundational
             (co)datatypes and (co)recursion for higher-order logic. In Clare Dixon and Marcelo Finger,
             editors, Frontiers of Combining Systems (FroCoS) 2017, pages 3–21. Springer, 2017. doi:
             10.1007/978-3-319-66167-4_1.
        13   Jasmin Christian Blanchette, Aymeric Bouzy, Andreas Lochbihler, Andrei Popescu, and
             Dmitriy Traytel. Friends with benefits: Implementing corecursion in foundational proof
             assistants. In Hongseok Yang, editor, Programming Languages and Systems (ESOP) 2017,
             pages 111–140. Springer, 2017. doi:10.1007/978-3-662-54434-1_5.
        14   Jasmin Christian Blanchette, Lorenzo Gheri, Andrei Popescu, and Dmitriy Traytel. Bindings
             as bounded natural functors. PACMPL, 3(POPL):22:1–22:34, 2019. doi:10.1145/3290335.
        15   Jasmin Christian Blanchette, Johannes Hölzl, Andreas Lochbihler, Lorenz Panny, Andrei
             Popescu, and Dmitriy Traytel. Truly modular (co)datatypes for Isabelle/HOL. In Gerwin
             Klein and Ruben Gamboa, editors, Interactive Theorem Proving (ITP) 2014, pages 93–110.
             Springer, 2014. doi:10.1007/978-3-319-08970-6_7.
        16   Jasmin Christian Blanchette, Fabian Meier, Andrei Popescu, and Dmitriy Traytel. Foundational
             nonuniform (co)datatypes for higher-order logic. In Logic in Computer Science (LICS) 2017,
             pages 1–12. IEEE Computer Society, 2017. doi:10.1109/LICS.2017.8005071.
        17   Cyril Cohen. Pragmatic quotient types in Coq. In Sandrine Blazy, Christine Paulin-Mohring,
             and David Pichardie, editors, Interactive Theorem Proving (ITP) 2013, pages 213–228. Springer,
             2013. doi:10.1007/978-3-642-39634-2\_17.
        18   Robert L. Constable, Stuart F. Allen, Mark Bromley, Rance Cleaveland, J. F. Cremer, R. W.
             Harper, Douglas J. Howe, Todd B. Knoblock, N. P. Mendler, Prakash Panangaden, James T.
             Sasaki, and Scott F. Smith. Implementing mathematics with the Nuprl proof development
             system. Prentice Hall, 1986. URL: http://dl.acm.org/citation.cfm?id=10510.
        19   Leonardo Mendonça de Moura, Soonho Kong, Jeremy Avigad, Floris van Doorn, and Jakob von
             Raumer. The Lean theorem prover (system description). In Amy P. Felty and Aart Middeldorp,
             editors, Conference on Automated Deduction (CADE) 2015, pages 378–388. Springer, 2015.
             doi:10.1007/978-3-319-21401-6_26.
        20   Richard Dedekind. Was sind und was sollen die Zahlen? Vieweg, Braunschweig, 1888.
             Translated by Wooster Beman as “The nature and meaning of numbers” in Essays on the
             theory of numbers, Open Court, Chicago, 1901; reprinted by Dover, New York, 1963.
        21   Peter Dybjer. Inductive families. Formal Asp. Comput., 6(4):440–465, 1994. doi:10.1007/
             BF01211308.
        22   Gabriel Ebner, Sebastian Ullrich, Jared Roesch, Jeremy Avigad, and Leonardo de Moura. A
             metaprogramming framework for formal verification. PACMPL, 1(ICFP):34:1–34:29, 2017.
             doi:10.1145/3110278.
J. Avigad, M. Carneiro, and S. Hudon                                                                   17:19


23   Denis Firsov and Aaron Stump. Generic derivation of induction for impredicative encodings in
     Cedille. In June Andronick and Amy P. Felty, editors, Certified Programs and Proofs (CPP)
     2018, pages 215–227. ACM, 2018. doi:10.1145/3167087.
24   Gottlob Frege. Grundgesetze der Arithmetik. H. Pohle, Jena, Volume 1, 1893, Volume 2, 1903.
25   Nicola Gambino and Martin Hyland. Wellfounded trees and dependent polynomial functors. In
     Stefano Berardi, Mario Coppo, and Ferruccio Damiani, editors, Types for Proofs and Programs
     (TYPES) 2003, pages 210–225. Springer, 2003. doi:10.1007/978-3-540-24849-1_14.
26   Eduardo Giménez. Codifying guarded definitions with recursive schemes. In Peter Dybjer,
     Bengt Nordström, and Jan M. Smith, editors, Types for Proofs and Programs (TYPES) 1994,
     pages 39–59. Springer, 1994. doi:10.1007/3-540-60579-7_3.
27   Martin Hofmann. A simple model for quotient types. In Mariangiola Dezani-Ciancaglini and
     Gordon D. Plotkin, editors, Typed Lambda Calculi and Applications (TLCA) 1995, pages
     216–234. Springer, 1995. doi:10.1007/BFb0014055.
28   Johannes Hölzl, Andreas Lochbihler, and Dmitriy Traytel. A formalized hierarchy of
     probabilistic system types (proof pearl). In Christian Urban and Xingyuan Zhang, ed-
     itors, Interactive Theorem Proving (ITP) 2015, pages 203–220. Springer, 2015. doi:
     10.1007/978-3-319-22102-1_13.
29   Peter V. Homeier. A design structure for higher order quotients. In Joe Hurd and Thomas F.
     Melham, editors, Theorem Proving in Higher Order Logics (TPHOLs) 2005, pages 130–146.
     Springer, 2005. doi:10.1007/11541868\_9.
30   André Joyal. Une théorie combinatoire des séries formelles. Adv. in Math., 42(1):1–82, 1981.
     doi:10.1016/0001-8708(81)90052-9.
31   Bronisław Knaster. Un théorème sur les fonctions d’ensembles. Ann. Soc. Polon. Math.,
     6:133–134, 1928.
32   Georg Kreisel. Generalized inductive definitions. Stanford Report on the Foundations of
     Analysis (mimeographed), CH. III, Stanford, 1963.
33   Alexander Kurz and Jiri Velebil. Relation lifting, a survey. J. Log. Algebr. Meth. Program.,
     85(4):475–499, 2016. doi:10.1016/j.jlamp.2015.08.002.
34   Per Martin-Löf. An intuitionistic theory of types: predicative part. In Logic Colloquium 1973,
     pages 73–118. North-Holland, Amsterdam, 1975.
35   Tobias Nipkow, Lawrence C. Paulson, and Markus Wenzel. Isabelle/HOL. A proof assistant
     for higher-order logic. Springer Verlag, Berlin, 2002.
36   Jan J. M. M. Rutten. Relators and metric bisimulations. Electr. Notes Theor. Comput. Sci.,
     11:252–258, 1998. doi:10.1016/S1571-0661(04)00063-5.
37   Jan J. M. M. Rutten. Universal coalgebra: a theory of systems. Theoret. Comput. Sci.,
     249(1):3–80, 2000. doi:10.1016/S0304-3975(00)00056-6.
38   Sam Staton. Relating coalgebraic notions of bisimulation. In Alexander Kurz, Marina Lenisa,
     and Andrzej Tarlecki, editors, Algebra and Coalgebra in Computer Science (CALCO) 2009,
     pages 191–205. Springer, 2009. doi:10.1007/978-3-642-03741-2_14.
39   Alfred Tarski. A lattice-theoretical fixpoint theorem and its applications. Pacific J. Math.,
     5:285–309, 1955. URL: http://projecteuclid.org/euclid.pjm/1103044538.
40   Enrico Tassi. Deriving proved equality tests in Coq-elpi: Stronger induction principles for
     containers in Coq. This Proceedings, 2019.
41   Brent A. Yorgey. Species and functors and types, oh my! In Jeremy Gibbons, editor,
     Proceedings of the 3rd ACM SIGPLAN Symposium on Haskell, pages 147–158. ACM, 2010.
     doi:10.1145/1863523.1863542.




                                                                                                      ITP 2019