Semantical Analysis of Contextual Types

We describe a category-theoretic semantics for a simply typed variant of Cocon, a contextual modal type theory where the box modality mediates between the weak function space that is used to represent higher-order abstract syntax (HOAS) trees and the strong function space that describes (recursive) computations about them. What makes Cocon different from standard type theories is the presence of first-class contexts and contextual objects to describe syntax trees that are closed with respect to a given context of assumptions. Following M. Hofmann’s work, we use a presheaf model to characterise HOAS trees. Surprisingly, this model already provides the necessary structure to also model Cocon. In particular, we can capture the contextual objects of Cocon using a comonad \documentclass[12pt]{minimal} \usepackage{amsmath} \usepackage{wasysym} \usepackage{amsfonts} \usepackage{amssymb} \usepackage{amsbsy} \usepackage{mathrsfs} \usepackage{upgreek} \setlength{\oddsidemargin}{-69pt} \begin{document}$$\flat $$\end{document}♭ that restricts presheaves to their closed elements. This gives a simple semantic characterisation of the invariants of contextual types (e.g. substitution invariance) and identifies Cocon as a type-theoretic syntax of presheaf models. We express our category-theoretic constructions by using a modal internal type theory that is implemented in Agda-Flat.


Introduction
A fundamental question when defining, implementing, and working with languages and logics is: How do we represent and analyse syntactic structures? Higher-order abstract syntax [19] (or lambda-tree syntax [17]) provides a deceptively simple answer to this question. The basic idea to represent syntactic structures is to map uniformly binding structures in our object language (OL) to the function space in a meta-language thereby inheriting α-renaming and capture-avoiding substitution. In the logical framework LF [10], for example, we can define a small functional programming language consisting of functions, function application, and let-expressions using a type tm as follows: lam : (tm → tm) → tm. letv: tm → (tm → tm) → tm. app : tm → tm → tm.
However, we not only want to just construct HOAS trees, but also to analyse them and to select sub-trees. This is challenging, as sub-trees are context sensitive. For example, the term letv (app x y) λw.app w y only makes sense in a context x:tm,y:tm. Moreover, one cannot simply extend LF to allow syntax analysis. If one simply added a recursion combinator to LF, then it could be used to define many functions M: tm → tm for which lam M would not represent an object-level syntax term [12].
Contextual types [18,20] offer a type-theoretic solution to these problems by reifying the typing judgement, i.e. that letv (app x y) λw.app w y has type tm in the context x:tm,y:tm, as a contextual type x:tm, y:tm tm . The contextual type x:tm, y:tm tm describes a set of terms of type tm that may contain variables x and y. In particular, the contextual object x, y letv (app x y) λw.app w y has the given contextual type. By abstracting over contexts and treating contexts as first-class, we can now recursively analyse HOAS trees [20,25,21]. Recently, [23] further generalised these ideas and presented a contextual modal type theory, Cocon, where we can mix HOAS trees and computations, i.e. we can use (recursive) computations to analyse and traverse (contextual) HOAS trees and we can embed computations within HOAS trees. This line of work provides a syntactic perspective to the question of how to represent and analyse syntactic structures with binders, as it focuses on decidability of type checking and normalisation. However, its semantics remains not well-understood. What is the semantic meaning of a contextual type? Can we semantically justify the given induction principles? What is the semantics of a first-class context?
While a number of closely related categorical models of abstract syntax with bindings [12,8,9] were proposed around 2000, the relationship of these models to concrete type-theoretic languages for computing with HOAS structures was teneous. In this paper, we give a category-theoretic semantics for Cocon (for simply-typed HOAS). This provides semantic perspective of contextual types and first-class contexts. Maybe surprisingly, the presheaf model introduced by Hofmann [12] already provides the necessary structure to also model contextual modal type theory. Besides the standard structure of this model, we only need two additional concepts: a -modality and a cartesian closed universe of representables. For simplicity and lack of space, we focus on the special case of Cocon where the HOAS trees are simply-typed. Concentrating on the simply-typed setting allows us to introduce the main idea without the additional complexity that type dependencies bring with them. We outline the dependently-typed case in Sec. 6.
Our work provides a semantic foundation to Cocon and can serve as a starting point to investigate connections to similar work. First, our work connects Cocon to other work on internal languages for presheaf categories with a -modality, such as spatial type theory [27] or crisp type theory [16]. Second, it may help to understand the relations of Cocon to type theories that use a modality for metaprogramming and intensional recursion, such as [15]. While Cocon is built on the same general ideas, a main difference seems to be that Cocon distinguishes between HOAS trees and computations, even though it allows mixed use of them. We hope to clarify the relation by providing a semantical perspective.

Presheaves for Higher-Order Abstract Syntax
Our work begins with the presheaf models for HOAS of [12,8]. The key idea of those approaches is to integrate substitution-invariance in the computational universe in a controlled way. For the representation of abstract syntax, one wants to allow only substitution-invariant constructions. For example, lam M represents an object-level abstraction if and only if M is a function that uses its argument in a substitutioninvariant way. For computation with abstract syntax, on the other hand, one wants to allow non-substitution-invariant constructions too. Presheaf categories allow one to choose the desired amount of substitution-invariance.
Let D be a small category. The presheaf category D is defined to be the category Set D op . Its objects are functors F : D op → Set, which are also called presheaves. Such a functor F is given by a set F (Ψ ) for each object Ψ of D together with a function F (σ) : F (Φ) → F (Ψ ) for any object Φ and σ : Ψ → Φ in D, subject to the functor laws. The intuition is that F defines sets of elements in various D-contexts, together with a D-substitution action. A morphism f : F → G is a natural transformation, which is a family of functions f Ψ : F (Ψ ) → G(Ψ ) for any Ψ . This family of functions must be natural, i.e. commute with substitution For the purposes of modelling higher-order abstract syntax, D will typically be the term model of some domain-level lambda-calculus. By domain-level, we mean the calculus that serves as the meta-level for object-language encodings. It is the calculus that contains constants like lam and app from the Introduction. We call it domain-level to avoid possible confusion between different meta-levels later. For simplicity, let us for now use a simply-typed lambda-calculus with functions and products as the domain language. It is sufficient to encode the example from the Introduction and allows us to explain the main idea underlying our approach.
The term model of the simply-typed domain-level lambda-calculus forms a cartesian closed category D. The objects of D are contexts x 1 : A 1 , . . . , x n : A n of simple types. We use Φ and Ψ to range over such contexts. A morphism from x 1 : A 1 , . . . , x n : A n to x 1 : B 1 , . . . , x m : B m is a tuple (t 1 , . . . , t m ) of terms x 1 : A 1 , . . . , x n : A n t i : B i for i = 1, . . . , m. A morphism of type Ψ → Φ in D thus amounts to a (domain-level) substitution that provides a (domain-level) term in context Ψ for each of the variables in Φ. Terms are identified up to αβηequality. One may achieve this by using a de Bruijn encoding, for example, but the specific encoding is not important for this paper. The terminal object is the empty context, which we denote by 1, and the product Φ×Ψ is defined by context concatenation. It is not hard to see that any object x 1 : A 1 , . . . , x n : A n is isomorphic to an object that is given by a context with a single variable, namely x 1 : (A 1 × · · · × A n ). This is to say that contexts can be identified with product types. In view of this isomorphism, we shall allow ourselves to consider the objects of D also as types and vice versa. The category D is cartesian closed, the exponential of Φ and Ψ being given by the function type Φ → Ψ (where the objects are considered as types).
The presheaf category D is a computational universe that both embeds the term model D and that can represent computations about it. Note that we cannot just enrich D with terms for computations if we want to use HOAS. In a simply-typed lambda-calculus with just the constant terms app: tm → tm → tm and lam: (tm → tm) → tm, each term of type tm represents an object-level term. This would not be the true anymore, if we were to allow computations in the domain language, since one could define M to be something like (λx. if x represents an object-level application then M1 else M2) for distinct M1 and M2. In this case, lam M would not represent an object-level term anymore. If we want to preserve a bijection between the object-level terms and their representations in the domain-language, we cannot allow case-distinction over whether a term represents an object-level an application.
The category D unites syntax with computations by allowing one to enforce various degrees of substitution-invariance. By choosing objects with different substitution actions, one can control the required amount of substitution-invariance.
In one extreme, a set S can be represented by the constant presheaf ∆S with ∆S(Ψ ) = S and ∆S(σ) = id for all Ψ and σ. The substitution action is trivial. As a consequence, a morphism ∆S → ∆T amounts to a function from set S to set T , since the trivial choice of the substitution action makes the naturality condition vacuous.
The Yoneda embedding represents the other extreme. For any object Φ of D, the presheaf y(Φ) : D op → Set is defined by y(Φ)(Ψ ) = D(Ψ, Φ), which is the set of morphisms from Ψ to Φ in D. The functor action is pre-composition. The presheaf y(Φ) should be understood as the type of all domain-level substitutions with codomain Φ. An important example is Tm := y(tm). In this case, Tm(Ψ ) is the set of all morphisms of type Ψ → tm in D. By the definition of D, these correspond to domain-level terms of type tm in context Ψ . In this way, the presheaf Tm represents the domain-level terms of type tm.
The Yoneda embedding does in fact embed D into D fully and faithfully. The Yoneda embedding becomes a functor y : D → D if one defines the morphism action to be post-composition. This means that y maps a morphism σ : Ψ → Φ in D to the natural transformation y(σ) : y(Ψ ) → y(Φ) that is defined by post-composing with σ. This definition makes y into a functor y : D → D that is moreover full and faithful: its action on morphisms is a bijection from D(Ψ, Φ) to D(y(Ψ ), y(Φ)) for any Ψ and Φ. This is because a natural transformation f : y(Ψ ) → y(Φ) is, by naturality, uniquely determined by f Ψ (id), where id ∈ D(Ψ, Ψ ) = y(Ψ )(Ψ ), and f Ψ (id) is an element of y(Φ)(Ψ ) = D(Ψ, Φ).
Since D embeds into D fully and faithfully, the term model of the domain language is available in D. Consider for example Tm = y(tm). Since y is full and faithful, the morphisms from Tm to Tm in D are in one-to-one correspondence with the morphisms from tm to tm in D. These, in turn, are defined to be substitutions and correspond to simply-typed (domain-level) lambda terms with one free variable. This shows that substitution invariance cuts down the morphisms from Tm to Tm in D just as much as one would like for HOAS encodings.
But D contains not just a term model of the domain language. It can also represent computations about the domain-level syntax and computations that are not substitution-invariant. For example, arbitrary functions on terms can be represented as morphisms from the constant presheaf ∆(Tm(1)) to Tm. Recall that 1 is the empty context, so that Tm(1) is the set D(1, tm), by definition, which is isomorphic to the set of closed domain-level terms of type tm. The morphisms from ∆(Tm(1)) to Tm in D correspond to arbitrary functions from closed terms to closed terms, without any restriction of substitution invariance.
The restriction to the constant presheaf of closed terms can be generalised to arbitrary presheaves. Define a functor : D → D by letting F be the constant presheaf ∆(F (1)), i.e. F (Ψ ) = F (1) and F (σ) = id. Thus, restricts any presheaf to the set of its closed elements. The functor defines a comonad where the counit ε F : F → F is the obvious inclusion and the comultiplication ν F : F → F is the identity. The latter means that the comonad is idempotent.

Internal Language
To explain how D models higher-order abstract syntax and contextual types, we need to expose more of its structure. Most of this structure is standard. Defining it directly in terms of functors and natural transformations is somewhat laborious and the technical details may obscure the basic idea of our approach.
We therefore use the internal type theory of D as a meta-language for working with its structure. The structure of D furnishes a model of a dependent type theory that supports dependent products, dependent sums and extensional identity types, among others, in a standard way [11]. We use Agda notation for the types and terms of this internal type theory. We write (x: S) → T for a dependent function type and write x: S.m and m n for the associated lambda-abstractions and applications. As usual, we will sometimes also write S → T for (x: S) → T if x does not appear in T . However, to make it easier to distinguish the function spaces at various levels, we will write (x: S) → T by default even when x does not appear in T . We use let x = m in n as an abbreviation for ( x: T.n) m, as usual. For two terms m: T and n: T , we write m = T n or just m = n for the associated identity type. Our notation is similar to Agda's, since the internal type theory can be seen as a fragment of Agda's type theory. Agda has been useful as a tool for type-checking our constructions in the internal type theory [1].
In the spirit of Martin-Löf type theory, we will define basic types and terms successively as they are needed. In the Agda development this corresponds to postulating constants that are justified by the interpretation in D. In the following sections, we will expose the structure of D step by step until we have enough to interpret contextual types.
While much of the structure of D can be captured by adding rules and constants to standard Martin-Löf type theory, for the comonad such a formulation would not be very satisfactory. The issues are discussed by Shulman [27, p.7], for example. To obtain a more satisfactory syntax for the comonad, we refine the internal type theory into a modal type theory in which appears as a necessity modality. This approach goes back to [3,4,6] and is also used by recent work of Shulman [27], Licata et al. [16] and others on working with the -modality in type theory. Agda has recently gained support for such a -modality [29].
We summarise here the typing rules for the -modality which we will rely on. To control the modality, one uses two kinds of variables. In addition to standard variables x: T , one has a second kind of so-called crisp variables x::T . Typing judgements have the form ∆ | Θ m: T , where ∆ collects the crisp variables and Θ collects the ordinary variables. In essence, a crisp variable x::T represents an assumption of the form x: T . The syntactic distinction is useful, since it leads to a type theory that is well-behaved with respect to substitution, see [6,27].
The typing rules are closely related to those in modal type systems [6,18], where ∆ is the typing context for modal (global) assumptions and Θ for (local) assumptions, and type systems for linear logic [4], where ∆ is the typing context for non-linear assumptions and Θ for linear assumptions.

From Presheaves to Contextual Types
Armed with the internal type theory, we can now explore the structure of D.

A Universe of Representables
For our purposes, the main feature of D is that it embeds D fully and faithfully via the Yoneda embedding. In the type theory for D, we may capture this embedding by means of a Tarski-style universe. Such a universe is defined by a type of codes for types together with a decoding function that maps codes to actual types. The type of codes Obj represents the set of objects of D in the internal type theory of D. We have seen above that any set can be represented as a presheaf with trivial substitution action, and Obj is one such example. Particular objects of D then appear as terms of type Obj. The cartesian closed structure of D gives us terms unit, times, arrow for the terminal object 1, finite products × and the exponential (function type). We also have a term for the domain-level type tm. Subsequently, we sometimes talk about objects of D when we intend to describe terms of type Obj (and vice versa). The morphisms of D could similarly be encoded as a constant presheaf with many term constants, but this is in fact not necessary. Instead, we can use the Yoneda embedding as a function that decodes elements of Obj into actual types.
x: Obj El x type The function El is almost direct syntax for the Yoneda embedding. The interpretation in D is such that, for any object A of D, the type El A is interpreted by the presheaf y(A). Such a presheaf is called representable. One can think of El A as the type of all morphisms of type Ψ → A in D for arbitrary Ψ . Recall from above that a morphism of type Ψ → A in D amounts to a domain-level term of type A that may refer to variables in Ψ . In this sense, one should think of El A as a type of domain-level terms of type A, both closed and open ones.
We get all morphisms of D, and no more, in this way, since the Yoneda embedding is full and faithful, recall Sec. 2. In our case, this means that the type (x: El A) → El B represents the morphisms of type A → B in D. Any closed term of type (x : El A) → El B corresponds to such a morphism and vice versa. This is because the naturality requirements in D enforce substitution-invariance, as outlined in Sec. 2. The type (x : El A) → El B thus does not represent arbitrary functions from terms of type A to terms of type B, but only substitution-invariant ones. If a function of this type maps a domain-level variable x: A (encoded as an element of El A) to some term M : B (encoded as an element of El B), then it must map any other N : We note that the type dependency in El is easy to work with. A term of type (a: Obj) → (b: Obj) → (x: El a) → El b corresponds to a family of terms (x: El A) → El B indexed by objects A and B in D. This is because Obj is just a set, so that the naturality constraints of D are vacuous for functions out of Obj.
To summarise, we get access to D in the internal type theory of D simply by considering the Yoneda embedding as the decoding function El of a universeá la Tarski. Since is consists of the representable presheaves, we call it the universe of representables. The following lemmas state that the embedding preserves terminal object, binary products and the exponential.

Higher-Order Abstract Syntax
The last lemma in the previous section states that El A → El B is isomorphic to El (arrow A B). This is particularly useful to lift HOAS-encodings from D to D. For instance, the domain-level term constant lam: (tm → tm) → tm gives rise to an element of El (arrow (arrow tm tm) tm). But this type is isomorphic to (El tm → El tm) → El tm, by the lemma. This means that the higher-order abstract syntax constants lift to D: app : (m: El tm) → (n: El tm) → El tm lam : (m: (El tm → El tm)) → El tm Once one recognises El A as y(A), the adequacy of this higher-order abstract syntax encoding lifts from D to D as in [12]. For example, an argument M to lam has type El tm → El tm, which is isomorphic to El (arrow tm tm). But this type represents (open) domain-level terms t : tm → tm. The term lam M : El tm then represents the domain-level term lam t : tm, so it just lifts the domain-level.

Closed Objects
One should think of T as the type of 'closed' elements of T . In particular, (El A) represents morphisms of type 1 → A in D, recall the definition of from Sec. 2 and that El A corresponds to yA. In the term model D, the morphisms 1 → A correspond to closed domain-language terms of type A. Thus, while El A represents both open and closed domain-level terms, (El A) represents only the closed ones.
This applies also to the type El A → El B. We have seen above that El A → El B is isomorphic to El (arrow A B) and may therefore be thought of as containing the terms of type B with a distinguished variable of type A. But, these terms may contain other free domain language variables. The type (El A → El B), on the other hand, contains only terms of type B that may contain (at most) one variable of type A.
Restricting to closed object with the modality is useful because it disables substitution-invariance. For example, the internal type theory for D justifies a function is-lam : (x: (El tm)) → bool that returns true if and only if the argument represents a domain language lambda abstraction. We shall define it in the next section. Such a function cannot be defined with type El tm → bool, since it would not be invariant under substitution. Its argument ranges over terms that may be open; which particularly includes domain-level variables. The function would have to return false for them, since a domain-level variable is not a lambdaabstraction. But after substituting a lambda-abstraction for the variable, it would have to return true, so it could not be substitution-invariant.
We note that the type Obj consists only of closed elements and that Obj and Obj happen to be definitionally equal types (an isomorphism would suffice, but equality is more convenient).

Contextual Objects
Using function types and the modality, it is now possible to work with contextual objects that represent domain level terms in a certain context, much like in [20,21]. A contextual type Ψ A is a boxed function type of the form (El Ψ → El A). It represents domain-level terms of type A with variables from Ψ . Here, we consider the domain-level context Ψ as a term that encodes it. The interpretation will make this precise. For example, domain-level terms with up to two free variables now appear as terms of type (El ((times (times unit tm) tm) → El tm), as the following example illustrates.
box ( u: El ((times (times unit tm) tm). let The context variables x 1 and x 2 are bound at the meta level. This representation integrates substitution as usual. For example, given crisp variables m::El (times c tm) → tm and n::El c → tm for contextual terms, the term box ( u: El c. m (pair u (n u))) represents substitution of n for the last variable in the context of m.
For working with contextual objects, it is convenient to lift the constants app and lam to contextual types. A contextual type for domain-level variables (as opposed to arbitrary terms) can be defined by restricting the function space in (El Ψ → El A) to consist only of projections. Projections are functions of the form snd • fst k , where we write fst k for the k-fold iteration fst • · · · • fst. Let us write S → v T for the subtype of S → T consisting only of projections. The contextual type (El Ψ → v El A) is then a subtype of (El Ψ → El A).
With these definitions, we can express a primitive recursion scheme for contextual types. We write it in its general form where the result type A can possibly depend on x. This is only relevant for the dependently typed case; in the simply typed case, the only dependency is on c. Then, D justifies a term rec : X var → X app → X lam → (c: Obj) → (x: (El c → El tm)) → A c x such that the following equations are valid.
rec t var t app t lam c x = t var c x if x: (El c → v El tm) rec t var t app t lam c (app s t) = t app c s t rec t var t app t lam c (lam s) = t lam c s Proof (outline). To outline the proof idea, note first that a function of type (c: Obj) → (x: (El c → El tm)) → A c x in D, corresponds to an inhabitant of A Φ t for each concrete object Φ of D and each inhabitant t : (El Φ → El tm). This is because naturality constraints for boxed types are vacuous (and Obj = Obj). Next, note that inhabitants of (El Φ → El tm) correspond to domain-level terms of type tm in context Φ up to αβη-equality. We can perform a case-distinction on whether it is a variable, abstraction or application and depending on the result use t var , t app or t lam to define the required inhabitant of A Φ t.
As a simple example for rec, we can define the function is-lam discussed above by rec ( c, x. false) ( c, x, y, r x , r y . false) ( c, x, r x . true).

Simple Contextual Modal Type Theory
We have outlined informally how the internal dependent type theory of D can model contextual types. In this section, we make this precise by giving the interpretation of Cocon [23], a contextual modal type theory where we can work with contextual HOAS trees and computations about them, into D. We will focus here on a simply-typed version of Cocon where we use a simply-typed domain-language with constants app and lam and also only allow computations about HOAS trees, but do not consider, for example, universes. Concentrating on a stripped down, simply-typed version of Cocon allows us to focus on the essential aspects, namely how to interpret domain-level contexts and domain-level contextual objects and types semantically. The generalisation to a dependently typed domain-level such as LF in Sec. 6 will be conceptually straightforward, although more technical. Handling universes is an orthogonal issue (see also [16]).
We first define our simply-typed domain-level with the type tm the term constants lam and app (see Fig. 1). Following Cocon, we allow computations to be embedded into domain-level terms via unboxing. The intuition is that if a program t promises to compute a value of type x:tm, y:tm tm , then we can embed t directly into a domain-level object writing lam λx.lam λy.app t x, unboxing t. Domain-level objects (resp. types) can be packaged together with their domainlevel context to form a contextual object (resp. type). Domain-level contexts are formed as usual, but may contain context variables to describe a yet unknown prefix. Last, we include domain-level substitutions that allow us to move between domain-level contexts. The compound substitution σ, M extends the substitution σ with domain Ψ to a substitution with domain Ψ , x, where M replaces x. Following [18,23], we do not store the domain (like Ψ ) in the substitution, it can always be recovered before applying the substitution. We also include weakening substitution, written as wk Ψ , to describe the weakening of the domain Ψ to Ψ, − − → x:A. Weakening substitutions are necessary, as they allow us to express the weakening of a context variable ψ. Identity is a special form of the wk Ψ substitution, which follows immediately from the typing rule of wk Ψ . Composition is admissible.
We summarise the typing rules for domain-level terms and types in Fig. 2. We also include typing rules for domain-level contexts. Note that since we restrict ourselves to a simply-typed domain-level, we simply check that A is a well-formed type. We defer the reduction and expansion rules to the appendix and only remark here that equality for domain-level terms and substitution is modulo βη. In particular, Φ N σ reduces to [σ]N .
In our grammar, we distinguish between the contextual type Ψ A and the more restricted contextual type Φ v A which characterises only variables of type A from the domain-level context Φ. We give here two sample typing rules for Φ v A which are the ones used most in practice to illustrate the main idea. We embed contextual objects into computations via the modality. Computation-level types include boxed contextual types, Φ A , and function types, written as (y :τ 1 ) ⇒ τ 2 . We overload the function space and allow as domain of discourse both computation-level types and the schema ctx of domain-level context, although only in the latter case y can occur in τ 2 . We use fn y ⇒ t to introduce functions of both kinds. We also overload function application t s to eliminate function types (y : τ 1 ) ⇒ τ 2 and (y : ctx) ⇒ τ 2 , although in the latter case s stands for a domain-level context. We separate domain-level contexts from contextual objects, as we do not allow functions that return a domain-level context.
The recursor is written as rec I B Ψ t. Here, t describes a term of type Ψ tm that we recurse over and B describes the different branches that we can take  depending on the value computed by t. As is common when we have dependencies, we annotate the recursor with the typing invariant I. Here, we consider only the recursor over domain-level terms of type tm. Hence, we annotate it with I = (ψ : ctx) ⇒ (y : ψ tm ) ⇒ τ . To check that the recursor rec I B Ψ t has type [Ψ/ψ]τ , we check that each of the three branches has the specified type I. In the base case, we may assume in addition to ψ : ctx that we have a variable p : ψ v tm and check that the body has the appropriate type. If we encounter a contextual object built with the domain-level constant app, then we choose the branch b app . We assume ψ: ctx, m: ψ tm , n: ψ tm , as well as f n and f m which stand for the recursive calls on m and n respectively. We then check that the body t app is well-typed. If we encounter a domain object built with the domain-level constant lam, then we choose the branch b lam . We assume ψ: ctx and m: ψ, x:tm tm together with the recursive call f m on m in the extended LF context ψ, x:tm. We then check that the body t lam is well-typed. The typing rules for computations are given in Fig. 3. We omit the reduction rules here and refer the interested reader to the appendix.

Interpretation
We now give an interpretation of simply-typed Cocon in a presheaf model with a cartesian closed universe of representables. Let us first extend the internal dependent type theory with the constant tm for modelling the domain-level type constant tm and with the constants app : El tm → El tm → El tm and lam : (El tm → Γ C : T Contextual object C has contextual type T Γ t : τ Term t has computation type τ y :τ ∈ Γ Γ y :τ We can now translate domain-level and computation-level types of Cocon into the internal dependent type theory for D. We do so by interpreting the domainlevel terms, types, substitutions, and contexts (see Fig. 4). All translations are on well-typed terms and types. Domain-level types are interpreted as the terms of type Obj in the internal dependent type theory that represent them. Domain-level contexts are also interpreted as terms of type Obj by Γ Ψ : ctx . For example, a domain-level context x:tm, y:tm is interpreted as times (times unit tm) tm : Obj. A domain-level substitution with domain Ψ and codomain Φ becomes a term of type El e that is parameterised by an element u: El e, where e = Γ Φ : ctx and e = Γ Ψ : ctx . As e is some product, for example times (times unit tm) tm, the domain-level substitution is translated into an n-ary tuple. A weakening substitution Γ ; Ψ, x:tm wk Ψ : Ψ is interpreted as fst u where u: El (times e tm) and e = Γ Ψ : ctx . More generally, when we weaken a context Ψ by n declarations, i.e. − − → x:A, we interpret wk Ψ as fst n u.
A well-typed domain-level term, Γ ; Ψ M : A, is mapped to an object of type El A that depends on u:El Γ Ψ : ctx .
Hence the translation of a well-typed domain-level term is indexed by u that stands for the term-level interpretation of a domain-level context Φ. Initially, u is simply a variable. However, when we translate Γ ; Φ λx.M : A → B given u: El e where Γ Ψ : ctx = e, we need to recursively translate M in the extended domain-level context Ψ, x:A and hence we also need to build a term pair u x that inhabits El (times e A ). The translation of Γ ; Φ, x:A M : A will return a term e that may contain x. However, note that x will eventually be bound in arrow-i ( x:El A . e) When we translate a variable x where Φ = Φ 0 , x:A, y k :A k , . . . , y 1 :A 1 , we return fst k (snd u). We translate Γ ; Φ t σ : A directly using let box-construct where the domain-level substitution σ is simply translated into a pair. As the computation t has the contextual type Ψ tm its translation will be of type (El e → El tm) where e = Γ Ψ : ctx . Hence we simply can extract a function x:(El e → El tm) using let box construct and pass to it the interpretation of σ. The translation of domain-level applications and domain-level constants app and lam is straightforward.
The interpretation of a contextual types Ψ A makes explicit the fact that they correspond to functions El e → El A where e = Γ Ψ : ctx (see Fig. 5). Consequently, the corresponding contextual object ( Φ M ) is interpreted as a function. Similarly, Ψ v A is mapped to the restricted function space denoted by → v , which describes functions with bodies that only contain projections. Last, we give the interpretation of computation-level types, contexts and terms (see Fig. 6). It is mostly straightforward, as we simply map T to T and C is simply interpreted as boxed term.
The interpretation of the recursor is also straightforward now (see Fig. 7). In Lemma 4, we expressed a primitive recursion scheme in our internal type theory and defined a term rec together with its type. We now interpret every branch of our recursor in the computation-level as a function of the required type in our internal type theory. While this is somewhat tedious, it is straightforward.
We can now show that all well-typed domain-level and computation-level objects are translated into well-typed constructions in our internal type theory. As a consequence, we can show that equality in Cocon is equivalent to the corresponding equivalence in our internal type theoretic interpretation.

Presheaves on a Small Category with Attributes
To explain the core of our approach as simply as possible, we have concentrated on a simply-typed domain language. In the remaining space, we outline how our approach generalises to dependent domain languages like LF. We follow the same approach as above. We start from a term model D of the domain language and then interpret contextual types in the presheaf category D.
In the simply-typed case above, D was a small cartesian closed category. In the dependent case, D is a small Category with Attributes. Categories with attributes (CwAs) [11] are a general notion of model for dependent type theories that is suitable for modelling dependent domain languages like LF.
With this change, we follow essentially the same approach as above. The main difference is that the universe of representables now makes available the CwAstructure of D instead of the cartesian closed structure. The following section outlines this in analogy to Sec. 4.1.

Yoneda CwA
In a Yoneda CwA we again have a type for the objects of D, which we now denote Ctx. In the term model for LF, these would be the LF contexts. The type Ty c represents (possibly dependent) LF types in context c. Contexts can be built with the constants nil and cons. c: Ctx El c type The type El c has the same interpretation as before and is essentially just the Yoneda embedding. The morphisms c → d of the CwA D thus appear as functions of type El c → El d.
The axioms of a CwA can be stated using terms and equations in the internal language of D. For example, substitution on types and context projection morphisms are given by the following constants. The other components of a CwA are added similarly and the CwA-axioms [11] are expressed in terms of equations for these constants.
The inhabitants of a type can then be captured by the dependent type With these definitions, we can represent dependent contextual types much like the simply-typed ones. Recall that we had interpreted Φ A by El Φ → El A where both Φ and A were terms of type Obj. In the dependent case, A may depend on Φ. The interpretation of Φ is a term Φ : Ctx, much as before. The interpretation of A takes the dependency into account: u: El Φ A u : Ty u. The interpretation of the contextual type Φ A will then be: It may be interesting to note that (u: El c) → I a u is isomorphic to the type of sections of p : El (cons c a) → El c.
Object-level term constants in LF can be lifted using I. Consider, for example, an encoding of the simply-typed lambda-calculus in LF. It represents only welltyped terms by means of the constants app : Πa, b: ty. tm (arr a b) → tm a → tm b and lam : Πa, b: ty. (tm a → tm b) → tm (arr a b). Therein, the type tm of objectlevel terms is dependent on an object-level type ty, which may be built using a constant o : ty for a base type and a constant arr : ty → ty → ty for function types. This encoding lifts to the Yoneda CwA as in simply-typed case: Here, Γ abbreviates c: Ctx, u: (El c) and ∆ abbreviates Γ, a, b: (I ty u). Notice how lam uses higher-order abstract syntax at the meta level. With these definitions, the interpretation of Cocon is essentially just as before. For working with the dependencies in a Yoneda CwA, we found it very useful to type-check our definitions in Agda, see our sources [1].

Conclusion
We have given a rational reconstruction of contextual type theory in presheaf models of higher-order abstract syntax. This provides a semantical way of understanding the invariants of contextual types independently of the algorithmic details of type checking. At the same time, we identify the contextual modal type theory, Cocon, which is known to be normalising, as a syntax for presheaf models of HOAS. By accounting for the Yoneda embedding with a universeá la Tarski, we obtain a manageable way of constructing contextual types in the model, especially in the dependent case. While various forms of universes are being studied in the context of functor categories, e.g. [2,16], we are not aware of previous uses of presheaves over CwAs or similar.
In future work, one may consider using the model as a way of compiling contextual types, by implementing the semantics. In another direction, it may be interesting to apply the syntax of contextual types to other presheaf categories. We also hope that the model will help to guide the further development of Cocon. Acknowledgements. We thank the anonymous reviewers for helpful feedback.