A Programming Language for Virtual
Double Theories

Virtual Workshop on Double Categories · November 5, 2026

Bryce Goldman

Topos Institute

Introduction

\[ % https://tex.stackexchange.com/a/269194 \newcommand{\proto}{\mathrel{\mkern3mu\vcenter{\hbox{$\scriptstyle+$}}\mkern-13mu{\to}}} \]

Outline

  1. Introduction (you are here)
  1. A Type Theory for Virtual Double Categories
  1. A Domain-Specific Language for Virtual Double Theories
  1. Future Work
  1. Maybe questions? Who knows what the world will look like in 35 minutes

Presentations of Theories

We are often interested in presenting (first-order, algebraic, etc.) theories by some small collection of operation symbols and relations between them.

Definition:

  • The signature of a theory is the collection of operation symbols.

  • The axioms of a theory are the equalities or formulas relating those symbols.

Idea:

  • The signature is an interface.

  • The axioms are a description of the interface’s behavior.

A model of a theory is a concrete interpretation of the symbols in the signature which satisfy the axioms.

Double Theories

In categorical logic we are interested in viewing theories themselves as categorical structures.

Idea: many theories can be expressed as double categories; their models are naturally valued in categories (Lambert and Patterson 2024).

These can likewise be presented via a signature and axioms:

  • The signature declares the generating objects, tight morphisms, proarrows, and cells of the double category.
  • The axioms impose equalities on the components of the double category.

Virtual Double Categories

Our double theories will be virtual, meaning they are represented as virtual double categories.

Like ordinary double categories the tight direction is still a (strict) category. Cells map from a path of (zero or more) proarrows, into a single proarrow:

Virtual Double Categories (Cont.)

Tight composition is defined for compatible cells.

Loose composition and loose units are additional universal properties that a VDC may or may not have. For now we will ignore these, but be emotionally prepared for them to show up in some examples later.

Fibrational VDCs

Our VDCs will be fibrational, meaning they admit restrictions.

Given a proarrow \(P : X' \proto Y'\) and tight morphisms \({f : X \to X'},\) \({g : Y \to Y'},\) there is a cartesian cell

We say that \(P(f;g)\) is the restriction of \(P\) along \(f\) and \(g\).

Virtual Double Theories in Software

There is a mechanical procedure for constructing a type theory over the internal languages of models of a virtual double theory (Lynch and Patterson 2026).

Example: there is a simple presentation for the double theory of database schemas consisting of a single proarrow. This induces a type theory for the internal language of databases over a given schema.

CatColab, the Topos Institute’s a scientific modeling ecosystem, uses this idea to implement a uniform type system across many application domains.

Goal: develop a domain-specific programming language (DSL) for specifying virtual double theories, so that users can work with any the categorical logic in CatColab.

We want to prevent the user from specifying a malformed theory, so we will use a type theory for VDCs to eliminate bugs.

A Type Theory for VDCs

FVDblTT

Our type theory is an extension of FVDblTT (Nasu 2025), which proposes a type theory for reasoning in the internal language of cartesian fibrational virtual double categories. Our setup differs in a few ways, in order to more readily facilitate our software implementation for (finitely presented) virtual double theories:

  1. We permit cells in the signature to map out of arbitrary proarrows (including restrictions). This generalization is necessary to specify certain theories in categorical logic, such as the theory of adjunctions we will see as an example later.
  1. Our type theory for terms is unary, since we do not require our VDCs to be cartesian.
  1. The syntax and judgments of our type theory are adjusted slightly to translate more directly into a mechanical type-checking procedure.

Judgments

Judgment Notation
\(\mathrm{Type}\) \(X \text{ ty}\)
\(\mathrm{Context}\) \(\Gamma \text{ ctx}\)
\(\mathrm{Term}\) \(\Gamma \vdash s : X\)
\(\mathrm{Protype}\) \(\Gamma_0 , \Gamma_1 \vdash \underline{P} \text{ proty}\)
\(\mathrm{Boundary}\) \(\Gamma_0, \dots, \Gamma_n \mid \underline{P}_1, \dots, \underline{P}_n \to \underline{Q}\)
\(\mathrm{Procontext}\) \(\Gamma_0, \dots, \Gamma_n \mid p_1 : \underline{P}_1, \dots, p_n : \underline{P}_n \text{ proctx}\)
\(\mathrm{Substitution}\) \(\overline{\Gamma} \mid \Omega \vdash \{s_0, \dots, s_n\}(\tau_1, \dots, \tau_n) : (\underline{P}_1, \dots, \underline{P}_n)\)
\(\mathrm{Proterm}\) \(\overline{\Gamma} \mid \Omega \vdash \tau : \underline{P}\)

(Here \(\overline{\Gamma}\) is shorthand for \(\Gamma_0, \dots, \Gamma_n,\) and \(\Omega\) for \(p_1 : \underline{P}_1, \dots, p_n : \underline{P}_n\).)

Signature

The signature \(\Sigma\) of a virtual double category consists of:

  1. a set of object symbols \(\mathcal{T}_\Sigma.\)
  1. a set of function symbols \(\mathcal{F}_\Sigma(X, Y)\) for each pair \(X, Y \in \mathcal{T}_\Sigma.\)
  1. a set of proarrow symbols \(\mathcal{P}_\Sigma(X, Y)\) for each pair \(X, Y \in \mathcal{T}_\Sigma.\)
  1. a set of cell symbols \(\mathcal{C}_\Sigma,\) each of which is associated with a boundary specifying its arity, domain, and codomain.

Types and Term Contexts

Types are merely object symbols:

\[ \frac{X \in \mathcal{T}_\Sigma}{X \text{ ty}} \]


Term contexts are unary, consisting of exactly one variable binding:

\[ \frac{X \text{ ty}}{(x : X) \text{ ctx}} \]

Terms

Terms are typed by term contexts. The type theory for terms forms a (cut-free) unary type theory for categories (Shulman 2016):

\[ \frac{X \text{ ty}}{x : X \vdash x : X} \]


\[\frac{\Gamma \vdash s : X \quad f \in \mathcal{F}_\Sigma(X, Y)}{\Gamma \vdash f(s) : Y} \]

Pointful Syntax

Given morphisms \[ X \xrightarrow{f} Y \xrightarrow{g} Z \xrightarrow{h} W \] the composite \(h \circ (g \circ f) = (h \circ g) \circ f\) has the unique representation (up to \(\alpha\)-equivalence) \[ x : X \vdash h(g(f(x))) : W. \]

The identity at \(X\) is represented by \[ x : X \vdash x : X. \]

Protypes

Each proarrow symbol in \(\mathcal{P}_\Sigma\) gives rise to a dependent family of “protypes”:

\[ \frac{\Gamma_0 \vdash s : X \quad \Gamma_1 \vdash t : Y \quad P \in \mathcal{P}_\Sigma(X, Y)}{\Gamma_0, \Gamma_1 \vdash P(s, t) \text{ proty}} \]

(We abbreviate \(P(s, t)\) by \(\underline{P}\) when \(s\) and \(t\) are not relevant.)

Recall that \(s\) and \(t\) represent tight morphisms. The protype \(P(s, t)\) represents the restriction of the proarrow \(P\) along \(s\) and \(t.\)

Cell Boundaries

Recall: each cell symbol \(\alpha \in \mathcal{C}_\Sigma\) is associated with a boundary. These are judgments of the form \[ \frac{\begin{matrix}x_{i - 1} : X_{i - 1}, x_i : X_i \vdash \underline{P}_i \text{ proty} \quad (i = 1, \dots, n) \\ x_0 : X_0, x_n : X_n \vdash \underline{Q} \text{ proty}\end{matrix}}{\alpha : (x_0 : X_0, \dots, x_n : X_n \mid \underline{P}_1, \dots, \underline{P}_n) \to \underline{Q}} \]

We say that \(\alpha\) has arity \(n\), with domain \(\underline{P}_1, \dots, \underline{P}_n\) and codomain \(\underline{Q}.\)

Procontexts

The “procontext” that a cell (“proterm”) is typed in represents a path of zero or more proarrows:

These are formed inductively, as a sequence of protypes with contexts matching at common junctures:

\[ \frac{\Gamma \text{ ctx}}{\Gamma \mid \cdot \text{ proctx}} \hspace{2em} \frac{\overline{\Gamma}_L, \Gamma \mid \Omega \text{ proctx} \quad \Gamma, \Gamma_R \vdash \underline{P} \text{ proty}}{\overline{\Gamma}_L, \Gamma, \Gamma_R \mid \Omega, p : \underline{P} \text{ proctx}} \]

Note: both components of procontexts are ordered. The proterm component is also linear, meaning that each proterm variable must be used exactly once.

Proterms

Types and terms represented objects and (tight) morphisms of the VDC.


Proarrows behave like objects with a source and target—these should correspond to types (“protypes”) with a certain kind of dependency, as we’ve seen.


Cells are like \(n\)-ary maps between proarrows, so these should be terms (“proterms”) constructed as trees of cell symbols. Like the syntax for terms, our syntax for proterms will be pointful.

Proterms: Identity Cells

The (tight) identity cell on a proarrow \(P\) is represented by the typing judgment for a proterm variable: \[ \frac{\Gamma_0, \Gamma_1 \vdash \underline{P} \text{ proty}}{\Gamma_0, \Gamma_1 \mid p : \underline{P} \vdash p : \underline{P}} \]

Like the variables in the unary type theory for terms, these are the leaves of proterm typing derivations.

Proterms: Restriction Cells

Note: a proterm variable \(p : P(f(x), g(y))\) simultaneously represents the identity on \(P(f;g)\) and the cartesian cell

In this way the syntax of the language normalizes the fibrational structure of a virtual equipment.

Proterms: Substitutions

We represent the input to an \(n\)-ary cell as a sequence of proterms of length \(n\) which have compatible boundary terms (tight morphisms): \[ \frac{\Gamma_0 \vdash s_0 : X_0}{\Gamma_0 \mid \cdot \vdash \{s_0\}() : ()} \]

Proterms: Cell Composition

Cell generators are applied to substitutions of the correct form:

Note that the term arguments \(s_0, \dots, s_n\) allow the domain protypes to be restricted. The idea is that a protype \(P(f(x), g(y))\) should be thought of as a “subtype” of \(P(x', y'),\) for example.

Examples: Identity Cell

\[ x : X, y : Y \mid p : P(x, y) \vdash p : P(x, y) \]

Examples: Cell Generator

\[ \frac{\begin{matrix}\alpha : (x : X, y : Y \mid P(x, y)) \to M(f(x), g(y)) \\ x : X, y : Y \mid p : P(x, y) \vdash \{x, y\}(p) : (P(x, y)) \end{matrix}}{x : X, y : Y \mid p : P(x, y) \vdash \alpha\{x, y\}(p) : M(f(x), g(y))} \]

Examples: Cell Composite

Examples: Nullary Cell

Examples: Restricted Domain

A DSL for Virtual Double Theories

Surface Syntax: Objects and Arrows

Objects

obj X       -- declares an object symbol X
obj [Y, Z]  -- declares object symbols Y, Z

Tight Morphisms

-- function symbol declarations
fun f : X -> Y
fun g : Y -> Z

Proarrows

-- proarrow symbol declarations
pro P : X => Y
pro Q : Y => Z
pro R : X => Z

Surface Syntax: Cells

Cells

-- declares a unary cell α from P to Q with source 
-- arrow f and target arrow g
cell α : [x : X, y : Y] | [P[x, y]] -> Q[f(x), g(y)]

-- declares a globular binary cell β from [P, R] to Q
cell β : [x : X, y : Y, z : Z] | [P[x, y], Q[y, z]] -> R[x, z]

Proarrow Isomorphisms

-- provides an isomorphism between the proarrows P(g; id) and Q(id; g)
iso [y0 : Y, y1 : Y] ⊢ [p2q, q2p] : P[g(y0), y1] <=> Q(y0, g(y1))

Surface Syntax: Axioms

Axioms

-- declares a proterm axiom making a globular cell γ : P => P idempotent
axiom [x : X, y : Y] | [p : P[x, y]] ⊢ γ [γ [p]] ≡ γ [p]


Proarrow isomorphisms are syntactic sugar for a pair of cell declarations and a pair of axioms making them inverses.

--  the previous isomorphism induces the following axioms:
axiom [y0 : Y, y1 : Y] | [_p0 : P[g(y0), y1]] ⊢ q2p[p2q[_p0]] ≡ _p0
axiom [y0 : Y, y1 : Y] | [_p1 : Q[y0, g(y1)]] ⊢ p2q[q2p[_p1]] ≡ _p1

Examples: Theory of Promonads

The theory of promonads is a unital VDC with an object \(X\), a proarrow \({P : X \proto X}\) such that the loose composite \(P \odot P\) is defined and is equal to \(P\), and a virtual cell \(\theta\):

subject to the following axioms:

Examples: Theory of Promonads (Cont.)

We can specify this theory in our DSL via

obj X
pro P : X => X
cell θ : [x : X] -> P[x, x]
cell comp : [x0 : X, x1 : X, x2 : X] | [P[x0, x1], P[x1, x2]] -> P[x0, x2]

axiom [x0 : X, x1 : X] | [p : P[x0, x1]] ⊢ comp[θ(x0), p] ≡ p
axiom [x0 : X, x1 : X] | [p : P[x0, x1]] ⊢ comp[p, θ(x1)] ≡ p

Examples: Theory of Adjunctions

One presentation for the theory of adjunctions is specified by a pair of objects \(X, Y\) and tight morphisms \({f : X \to Y}\) (the left adjoint) and \({g : Y \to X}\) (the right adjoint), together with inverse cells

where \(\mathrm{id}\) denotes the loose unit and \(1\) denotes the tight unit.

Examples: Theory of Adjunctions (Cont.)

We can describe this theory in our programming language with

obj [X, Y]
fun f : X -> Y
fun g : Y -> X
pro idX : X => X 
pro idY : Y => Y  

and cells

-- inverse cells 
cell l2r : [x : X, y : Y] | [l : idY[f(x), y]] -> idX[x, g(y)]
cell r2l : [x : X, y : Y] | [r : idX[x, g(y)]] -> idY[f(x), y]

-- axioms making the cells inverses
axiom [x : X, y : Y] | [l : idY[f(x), y]] ⊢ r2l[l2r[l]] ≡ l
axiom [x : X, y : Y] | [r : idX[x, g(y)]] ⊢ l2r[r2l[r]] ≡ r

or we can use the syntactic sugar for isocells and simply write

-- simultaneously declares the cells l2r and r2l along with the axioms making them inverses
iso  [x : X, y : Y] ⊢ [l2r, r2l] : idY[f(x), y] <=> idX[x, g(y)]

Demo(This is where Bryce will do The Demo™)

(if he is not already doing The Demo™ you should politely remind him to do The Demo™)

Future Work

Loose Units and Composites

In the two example theories we needed to use both loose units and loose composites. For illustrative purposes we defined these manually, but ideally they should be primitives in the language.


Problem: loose units and composites satisfy universal properties, which impose a huge number of axioms.


Goal: capture these axioms with the language’s operational semantics, so that applying the universal properties becomes a normalization procedure.


This is hard. :(

Modalities

Many theories use modalities (read: well-behaved double monads). For instance, one can give a presentation of the theory of monoidal categories using the list modality, replacing the monoidal identity and binary tensor product with a single tight morphism \[ \otimes : \mathrm{List}(X) \to X. \]

Idea: take the closure of the generators under modal application, and introduce primitive cells for the monad unit and multiplication.

Problem: the monad laws demand some computational mechanism to handle equalities of tight morphisms, which induce equalities of (pro)types. Judgmental equalities between types famously make type-checking hard.

Thanks for listening!


References

CatColab Development Team. 2026. CatColab. V. v0.6.1. GitHub, released. https://github.com/ToposInstitute/CatColab.
Cruttwell, G. S. H., and Michael A. Shulman. 2010. A Unified Framework for Generalized Multicategories. https://arxiv.org/abs/0907.2460.
Lambert, Michael, and Evan Patterson. 2024. “Cartesian Double Theories: A Double-Categorical Framework for Categorical Doctrines.” Advances in Mathematics 444 (May): 109630. https://doi.org/10.1016/j.aim.2024.109630.
Li, Runming, Harrison Grodin, and Robert Harper. 2026. Directed Proof-Relevant Logical Relations in Simplicial HoTT. https://arxiv.org/abs/2607.08154.
Lynch, Owen. 2026. Fnotation. GitHub, released. https://github.com/ToposInstitute/fnotation.
Lynch, Owen, and Evan Patterson. 2026. “DoubleTT.” Topos Institute, January. https://next.catcolab.org/rfc/0002.
Nasu, Hayato. 2025. An Internal Logic of Virtual Double Categories. https://arxiv.org/abs/2410.06792.
Nelson, Greg. 1980. “Techniques for Program Verification.” PhD thesis, Stanford University.
Nelson, Greg, and Derek C. Oppen. 1980. “Fast Decision Procedures Based on Congruence Closure.” J. ACM (New York, NY, USA) 27 (2): 356–64. https://doi.org/10.1145/322186.322198.
Patterson, Evan. 2026. “Internal Languages for Models.” Topos Institute, April. https://next.catcolab.org/rfc/0004.
Petersen, Leaf, Robert Harper, Karl Crary, and Frank Pfenning. 2003. “A Type Theory for Memory Allocation and Data Layout.” SIGPLAN Not. (New York, NY, USA) 38 (1): 172–84. https://doi.org/10.1145/640128.604147.
Polakow, Jeff, and Frank Pfenning. 2001. “Ordered Linear Logic and Applications.” https://dl.acm.org/doi/10.5555/935673.
Shulman, Michael A. 2016. Categorical Logic from a Categorical Point of View. https://mikeshulman.github.io/catlog/catlog.pdf.
Topos Institute. 2026. “CatColab.” Topos Institute. https://topos.institute/work/catcolab/.