A unifying framework for continuity and complexity in higher types
Thomas Powell

TL;DR
This paper introduces a unified framework for analyzing higher-order computation concepts like termination, continuity, and complexity in functional languages, providing new methods for extracting moduli and characterizing complexity.
Contribution
It develops a parametrised monadic translation that unifies various notions in higher types and offers concrete instantiations for analyzing continuity and complexity.
Findings
Unified scheme for higher-order notions
Method for extracting moduli of continuity
Characterization of bar recursion complexity
Abstract
We set up a parametrised monadic translation for a class of call-by-value functional languages, and prove a corresponding soundness theorem. We then present a series of concrete instantiations of our translation, demonstrating that a number of fundamental notions concerning higher-order computation, including termination, continuity and complexity, can all be subsumed into our framework. Our main goal is to provide a unifying scheme which brings together several concepts which are often treated separately in the literature. However, as a by-product, we also obtain (i) a method for extracting moduli of continuity for closed functionals of type definable in (extensions of) System T, and (ii) a characterisation of the time complexity of bar recursion.
Peer Reviews
No public reviews on file for this paper yet. If you reviewed it on a platform where reviews are public (OpenReview, ICLR, NeurIPS, ICML), you can paste yours below so the community can read it here.
Videos
No videos yet. Explain this paper in a talk, walkthrough, or lecture? Add one.
\lmcsdoi
16317 \lmcsheadingLABEL:LastPageSep. 05, 2019Sep. 09, 2020
A unifying framework for continuity and complexity in higher types
Thomas Powell
Department of Computer Science, University of Bath, Bath, BA2 7AY, United Kingdom
Abstract.
We set up a parametrised monadic translation for a class of call-by-value functional languages, and prove a corresponding soundness theorem. We then present a series of concrete instantiations of our translation, demonstrating that a number of fundamental notions concerning higher-order computation, including termination, continuity and complexity, can all be subsumed into our framework. Our main goal is to provide a unifying scheme which brings together several concepts which are often treated separately in the literature. However, as a by-product, we also obtain (i) a method for extracting moduli of continuity for closed functionals of type in (extensions of) System T, and (ii) a characterisation of the time complexity of bar recursion.
Key words and phrases:
functional languages, logical relations, denotational semantics, bar recursion
1. Introduction
Monads are a fundamental tool for analysing functional programs [23, 39]. They allow us to capture information about a program’s execution, such as its computational complexity, and similarly enable us to reason about intensional aspects of higher-order functionals, such as continuity properties enjoyed by terms of System T.
This paper comprises a general study of monads and their application to higher-order functional languages, with an emphasis on languages which pertain to proof theory and program extraction. We focus on a simple yet powerful technique frequently encountered in the literature, which can be roughly described as follows:
- (1)
set up a mapping which transforms terms of type in some pure functional language into terms of type in some monadic metalanguage, 2. (2)
establish a logical relation between and , 3. (3)
appeal to induction over the structure of terms to prove that for all terms of type .
We explore an abstract translation of this kind, which maps a higher-order call-by-value target language into a metalanguage based on the writer monad . Our mapping will actually be the composition of a syntactic monadic translation together with a standard denotational semantics , and we define a general logical relation on which comprises a monadic part together with a semantic bounding relation .
Our first main result is to establish a general soundness theorem for , which identifies a set of abstract conditions that guarantee that for all terms of our target language. We then demonstrate that this combination of a monadic and bounding component is rich enough to express a variety of fundamental concepts from the theory of higher-order computation, including majorizability (in the sense of Howard [16]), continuity (on the Baire space) and several notions of time complexity.
In the case of continuity, we focus on terms of type level 2 that induce functionals . It is well known that functionals of this sort that are definable as closed terms of Gödel’s System T are continuous in the sense that their output is determined by a finite part of their input. Moreover, explicit moduli of continuity can be defined within System T itself. In recent years there has been a renewed interest in syntactic approaches to continuity which provide explicit moduli of continuity, and several new proofs of the continuity of System T definable functionals have been given, including [8, 12, 14] and most recently [17, 29, 40]. We provide another proof of this fact via our abstract framework, which applies not just to System T but to arbitrary languages that satisfy the relevant conditions.
We then show that by adjusting the parameters of our translation, we are able to characterise the time complexity, or cost, of terms in our programming language. Here, we crucially consider the cost of a higher-order term to be a higher-order object itself. Though the analysis of higher-order complexity via higher-order cost expressions dates back to the 1980s and has been widely researched since (e.g. [1, 30, 34, 37]), our general bounding relation allows us to also approach complexity along the lines of Danner et al. [9, 10], where datatypes are assigned abstract sizes and the translation seeks to provide upper bounds on the cost of programs.
The main significance of our work lies in our development an abstract semantics for reasoning about intensional properties of higher-order functionals, which encompasses a number of somewhat disparate concepts, ranging from majorizability, which is of fundamental importance to the proof mining program (Section 4.3), to the static cost analysis of functional programs (Section 6). This effort towards unification is not just of theoretical interest, but could potentially inform those working on the formalization of monadic translations111For example, in the case of continuity, both [12] and [40] have been formalised in Agda, while bounded complexity as set out in [10] comes with a Coq implementation.
A second novelty is that we focus not only on variants of Gödel’s System T, but also more complex forms of recursion such as Spector’s bar recursion [35]. Recursion of this kind is rarely treated in the context of static analysis, but has great importance in proof theory and particularly the area of program extraction, where it is used to give a computational interpretation to the axiom of countable choice. We carry out what is, to the best of our knowledge, the first static cost analysis of bar recursion as functional programs, and in doing so we hope more generally to provide another illustration of how monads enable us to better understand structures from proof theory.
2. A higher-order functional language
We start by outlining our target language, to which our monadic translation will be applied. This will be a standard call-by-value typed functional language, where for now we do not specify what our datatypes or function symbols will be. Rather we take these as parameters, and consider a number of concrete instantiations of the language later on.
Types and terms of the language are outlined in Figure 1. Types are built from a base set of datatypes , and a single rule which allows for the construction of function types. Terms are then built in the usual way via lambda abstraction and function application from a countable set of variables for each type together with a set of constructor terms and a set of function symbols . Each constructor term is assigned some type , where the are datatypes and is the arity of . Similarly, each function symbol is assigned a type , where now the are arbitrary and is a specified arity of . Formal typing rules for terms are included, though we often just write or where this is unambiguous and the context is not necessary. A closed term is a term without any free variables, or alternatively one typeable as .
In order to specify the operational semantics of our language, we introduce standard notions of patterns and values, which are defined as in Figure 2. Note that values are always closed terms - in the third clause this is ensured by the typing restriction that has no free variables other than . We also need the notion of a substitution, and later that of a value environment. For and we write to denote the term obtained by substituting all free occurrences of in by (with the usual restrictions on free variables in ). This is formally definable by induction on the structure of . For a term with , a value environment is a mapping which assigns each variable a value of type . We denote by the closed term .
A big step operational semantics for our language is given in Figure 3.
Note that reductions are of the form where is a closed term and a value of the same type. We often omit the typing on when there is no risk of ambiguity. Reductions follow the usual rules for the call-by-value lambda calculus, together with a set of defining rules for each function symbol of the form
[TABLE]
where are patterns, and is a term whose free variables are contained in those of . We assume that the rules defining each function symbol are complete and orthogonal, by which we mean that for each of arity and any values of the appropriate type, there is exactly one rule such that for a suitable environment . Note that for any closed term , at most one rule in Figure 3 is applicable, and thus a simple induction over derivations proves that if and then .
Remark 1**.**
A more traditional presentation of our target language would have been to instead take the formation rule
[TABLE]
as primitive, together with an analogous rule for the constructors. Then values would simply be terms of the form (for ) or , and the semantics would be altered accordingly. However, we have instead chosen to take the function symbols as primitive, as it is slightly more convenient for the purposes of setting up our monadic translation.
We now give some concrete instantiations of our parametrised language, all of which will play a role later.
2.1. Gödel’s System T (simple variant)
A call-by-value variant of System T is obtained in our setting by defining , and
[TABLE]
where the recursor has defining equations
[TABLE]
We write for the numeral representation of . In this language, one can show by induction on the size of that the only values of type are indeed those of the form , a fact which we will freely use throughout. The operational semantics of can be concisely expressed via the following derived rules:
[TABLE]
2.2. Gödel’s System T (list based variant)
A slightly richer (but computationally equivalent) version of System T is obtained by defining , and
[TABLE]
where have type and has type . We adopt the usual convention of writing instead of , and similarly for the operator symbols, and in addition we write for . For we write . Again, a simple induction over the size of values establishes that any is of the form for some . Along with the usual defining equation for the fold function:
[TABLE]
which gives rise to the derived rules
[TABLE]
we can incorporate basic operators into our language by defining each of them explicitly via a countable set of rules e.g. for and so on, which then satisfy operational rules . We define and in an analogous fashion so that
[TABLE]
where denotes the length of .
2.3. Spector’s bar recursion
The final language we consider here is an extension of the list language in Section 2.2 with Spector’s bar recursor of lowest type, originally introduced in [35] (but see e.g. [24] for a more modern introduction). This is a form of backward recursion over wellfounded trees, where for this particular variant, wellfoundedness is typically ensured by appealing to some form of continuity on the parameters of the recursion. In a simple equational calculus it would be given by the defining equation
[TABLE]
where the output type is as indicated, and the input parameters have type , and and respectively. In addition, we have and is defined by for and otherwise [math]. Bar recursion will primarily play a role in Sections 4.2 and 6.2, where we focus on termination and complexity, respectively. For now, we simply give the main definitions we will need later. We first need to add three additional function symbols
[TABLE]
where
[TABLE]
which have defining equations
[TABLE]
It is not difficult to show that the operational semantics in this case give rise to the following derived rules for (here we eliminate the intermediate steps involving )
[TABLE]
Remark 2**.**
The above formulation of bar recursion as a rewrite system is inspired by Berger [5], which in turn uses a trick due to Vogel [38]. There bar recursion is considered in its general form, where the type of and the output can be arbitrary. Though such a generalisation can easily be incorporated here by encoding lists of type as objects of type , for us bar recursion plays a predominantly illustrative role, and so for simplicity we restrict ourselves to the recursor of base type.
3. The main soundness theorem
In this section we present our main framework, first setting up our monadic translation and the associated logical relation, before proving that the translation is sound with respect to the relation. This soundness result, given as Theorem 4, is just an instance of the General Theorem of Logical Relations for our particular relation. As mentioned right at the beginning, our translation is actually the composition of a syntactic translation into a monadic metalanguage and a standard denotational semantics. We outline each of these in turn.
3.1. The monadic metalanguage
The metalanguage is defined similarly to our target language. However, here we only specify types and terms, which will then be assigned a denotational semantics in the next section. The monadic language is summarised in Figure 4.
Types are constructed from a special type together with base types for all datatypes of the target language, and now allow both function types and cartesian product types. We extend the mapping on datatypes of the target language to arbitrary types by defining
[TABLE]
Terms now include a symbol resp. for each constructor resp. function symbol in the target language, whose types are indicated in Figure 4. Together with the usual term forming rules of the lambda calculus (now with pairing and projection to account for the product), we have three nonstandard rules for forming terms of type : a constant , a unary operation and a ternary operation . The meaning of these will become clearer later on.
For the first step of our translation, we assign to each in the target language a term in the metalanguage as indicated in Figure 5, where for , we define . Here we also use the following shorthand: for we define
[TABLE]
and similarly for the iterated version .
3.2. A denotational semantics for the metalanguage
We assign our metalanguage a denotational semantics as specified in Figure 6. We assign sets and to the base types and respectively, for each . We leave open the precise meaning of the function space for now. In what follows we will typically work in total models, where function spaces will either be the full set-theoretic function space, or the space of continuous functions from to in the sense of Kleene [19] or Kreisel [22]
Terms of the metalanguage are assigned an interpretation in the usual way, where is an environment mapping each to some . We assume that we have chosen suitable interpretations , for each and respectively. Terms of type are interpreted via a triple .
3.3. The logical relation
Let be a type of our target language. We denote the set of all closed terms of type by , and the set of all values by . We now suppose that we are given a pair of relations
[TABLE]
where ranges over all types in our target language and over all datatypes. We will generalise to arbitrary types via the inductive clause
[TABLE]
where the relation on is defined by
[TABLE]
where in what follows we often abbreviate the inner conjunction as . In the remainder of this section we seek to establish conditions under which the translation is sound with respect to , by which we mean the following: {defi}
Given a value environment for in our target language and some denotational environment for , we write if for all . We say that is sound w.r.t. if for all in our target language, we have
[TABLE]
for all .
We start by focusing on the monadic part of our relation. {defi}
We say that is compatible with if the following rules are satisfied:
[TABLE]
Lemma 3**.**
Suppose that is compatible with . For and , define
[TABLE]
Then whenever and then .
Proof 3.1**.**
We have and for some , and thus , or in other words for some . Thus by Definition 3.3 we have , which is just .
{defi}
We say that our interpretations for the constructor terms are compatible with if for all constructor symbols we have whenever for all and values .
Theorem 4**.**
Suppose that is compatible with and the are compatible with . Suppose in addition that for all function symbols we have whenever for all and values . Then is sound w.r.t. .
Proof 3.2**.**
We use induction on the structure of terms to prove that whenever . For variables, follows from the fact that and . For constructor symbols, suppose that . Then we have , and since it remains to show that for we have
[TABLE]
Continuing this way for we must ultimately show that
[TABLE]
which follows from the fact that is compatible with . This argument is easily adapted to show that , using the main assumption of the theorem.
For function application, by the induction hypothesis we have and . Thus by Lemma 3 we have
[TABLE]
where the last equality follows from unwinding definitions. In remains to deal with abstraction. Suppose that . We need to show that
[TABLE]
for . But since this reduces to showing that for any we have
[TABLE]
for some . Because implies , by the induction hypothesis we have
[TABLE]
for some , and thus the result follows from Definition 3.3.
This concludes the first main part of the article, where we introduce our target language and establish a sound monadic translation which acts on it. Up to this point everything has been fairly standard: The first component of our translation into the monadic metalanguage is a simple call-by-value monadic translation using the writer monad. Theorem 4 is then a confirmation that the logical relation defined on terms of our target language and denotations of our metalanguage acts as it should. We now move onto the applications, where we show that Theorem 4, though simple, is surprisingly versatile.
4. Some simple applications for
Before we move on to our main applications of the translation, we demonstrate that in the simple case where is a terminal object, thus collapsing the monadic part of the translation, our soundness theorem can still be related to a number of key concepts in the literature. In each of the examples that follow, we define
[TABLE]
Note that in this case, are uniquely defined as just constant functions, and are compatible with since the conditions of Definition 3.3 follow from the definition of in Figure 3.
4.1. Reducibility predicates
Let’s first consider the case where in addition to we have for all datatypes, and thus for all types of the metalanguage - where here we implicitly use the isomorphisms and . We define
[TABLE]
Now let us write and . Then it is easy to show that
[TABLE]
and therefore and act as reducibility predicates. Moreover, whatever our constant symbols are, the are trivially compatible with . Thus the following result follows directly from our abstract soundness theorem.
Theorem 5**.**
Suppose that all function symbols in our target language satisfy
[TABLE]
for all values of the appropriate type. Then for any closed term there exists some value such that .
The above result confirms that termination of our target language as a whole follows from termination of the function symbols. As a simple application, we prove that our call-by-value version of System T (Section 2.1) terminates.
Corollary 6**.**
System T is terminating.
Proof 4.1**.**
We need to show that for any of the appropriate type and numeral we have
[TABLE]
(note that trivially holds). We do this by induction on , using the derived rules for the recursor given in Section 2.1. For we have and since holds by assumption it follows that . Now for the induction step, we assume that for some , which means that for some satisfying . Since implies that for some with , we then have , which means that for some with . Finally, by the derived rule for the recursor, we have and thus , and we’re done.
For the usual formulation of System T as an equational calculus, the above result roughly corresponds to the fact that any inner-most, left-most sequence of reductions terminates in some normal form (cf. Troelstra [36, Theorem 2.2.6]). It readily generalises to functional languages with more complex datatypes and other forms of wellfounded recursion. However, for languages involving bar recursion, such as that presented in Section 2.3, termination requires us to make use of our bounding component .
4.2. Termination via denotational semantics
We now instantiate so that it mimics the logical relation used in Plotkin’s famous adequacy proof for PCF [27], and demonstrate that this allows us to prove termination of bar recursion. The key here is to interpret our metalanguage in a continuous model, and then appeal to properties of the model in order to establish termination. Our approach closely follows Berger [4, 5], who sets up a more general framework in which strong normalization of higher-order rewrite systems can be proven using domain theoretic means.
We work with the instance of our target language given in Example 2.3, which contains two datatypes and . We define as before, but now let and . In addition, we interpret the function space in our denotational model as the space of all total continuous functionals from to . Thus our metalanguage is interpreted in the standard model of total continuous functionals over base types and , which has various presentations in the literature: Via limit spaces (Scarpellini [31]), encodings or neighbourhoods (Kleene/Kreisel [19, 22]) or as the extensional collapse of the partial continuous functionals (Ershov [11]).
We first observe that for any type in our target language, is isomorphic to the usual (non-monadic) denotational semantics of that type, since
[TABLE]
and thus we can ignore the monadic part of our translation. We define our logical relation as in Section 4.1, but now with a semantic component as follows:
[TABLE]
and as such, takes the following simplified form:
[TABLE]
Interpreting the constructor symbols in the obvious way i.e.
[TABLE]
it is clear that these interpretations are compatible with . In addition, we interpret the operator function symbols of our target language in the usual way, where in particular i.e.
[TABLE]
Finally, for bar recursion we let
[TABLE]
Note that is just the traditional defining equation of bar recursion, and is known to be an object of as originally proven by Scarpellini [31]. We now prove that the program is terminating.
Lemma 7**.**
Whenever , , and , we have
[TABLE]
Proof 4.2**.**
Assuming the hypotheses of the lemma throughout, we first claim that for all , whenever
[TABLE]
for all then . There are two cases to consider:
- •
Case 1: . Then since and we have and thus for . Since in addition and thus it follows that for , and thus by the first derived rule given in Section 2.3 we have for .
- •
Case 2: . By the same reasoning, we have for . Now, by our assumption we have
[TABLE]
for any , and since iff it follows that
[TABLE]
Using in addition that it is not hard to show that
[TABLE]
and thus for . Thus by the second derived rule we have for .
Combining cases we obtain , which proves the claim. We now come to the crucial part of the proof in which we utilise properties of the model to establish termination of bar recursive programs. Suppose that for some it is not the case that . Then using our claim (in its contrapositive form) together with dependent choice on a metalevel (which is permitted in ) there is an infinite sequence of numbers such that
[TABLE]
for all , where denotes the initial segment of of length . But it can be shown using a standard continuity argument (cf. [31]) that for any that there exists some such that
[TABLE]
and thus by an identical argument to the first case above (note that only Case 2 appeals to the assumption ) we have
[TABLE]
a contradiction. Thus for all .
This establishes the requirement of Theorem 4 for the functional symbol . A simple adaptation of Lemma 7 can be used to to show that the same condition holds for the auxiliary term together with a suitably defined , while a straightforward induction achieves the same for , the details of which we also omit. As a result, Theorem 4 yields the following:
Theorem 8**.**
For all closed terms in the bar recursive target language of Section 2.3 we have for some .
The above theorem represents a normalization result for bar recursion, where for illustrative purpose we only consider the bar recursor of lowest type. Strong normalization of bar recursion (of arbitrary type) was first established by [38], and then (without infinite terms) in [6]. Our approach, which also replaces infinite terms by appealing to the construction of choice sequences in the model, has been explored in much more detail by Berger [4, 5], where also normalization results for variants of bar recursion (including the so-called BBC functional [2] and open recursion [3]) are established. One crucial difference is that we work in a total model instead of a partial model, and it is open whether or not we can extend our framework (which works in total models) to incorporate other forms of recursion such as those mentioned above.
Remark 9**.**
A well known result of Schwichtenberg [33] asserts that bar recursion of lowest type when applied to primitive recursive parameters is actually definable within System T (a generalisation of which has been more recently presented in [26]). Thus our bar recursive language as presented here would technically also be definable in System T, and as such a detour through the continuous functionals is not strictly necessary in order to prove termination. However, as already pointed out in Remark 2, we could readily extend our language to include bar recursion of arbitrary type, and the termination proof given as Lemma 7 would generalise accordingly. We also note that our approach is modular, and thus any extension of our bar recursive language with new function symbols which can be given a suitable interpretation is also terminating as a whole.
4.3. Majorizability
Our final simple application for the case will be an adaptation of Howard’s majorizability relation [16] to higher-order rewrite systems. Majorizability is an extension of the usual ordering on to functionals of arbitrary finite type. In addition to forming the basis for interesting models of higher-order calculi, majorizability plays an essential role in the proof mining program, where it is used in conjunction with Gödel’s functional interpretation to form the monotone functional interpretation (introduced in [20]), which is crucial for interpreting forms of compactness related to the binary König’s lemma (for a detailed background on majorizability and its use in proof mining, see [21]). For simplicity we work over a target language with a single base type with . We define
[TABLE]
In this case, the logical relation is just a variant of the usual majorizability relation at all finite type, which in an equational setting is defined as follows (cf. [16] or [21, Definition 3.34])
[TABLE]
We compare this to our relation, which is based on the same idea but now phrased in terms of our programming language, and can be expanded as follows:
[TABLE]
To illustrate this correspondence further, note that in an equational calculus we would have
[TABLE]
whereas in our setting this would be rendered as
[TABLE]
In fact, we can prove the following key lemma, which is analogous to [21, Lemma 3.35 (iii)]:
Lemma 10**.**
Suppose that for . Then
[TABLE]
Proof 4.3**.**
Induction on . For this is just the definition of , and for the induction step we have
[TABLE]
where for the last step we use , which follows directly from the operational semantics of the language.
The following lemma is analogous to [21, Lemma 3.66].
Lemma 11**.**
Suppose that for and that for all . Then for
[TABLE]
Proof 4.4**.**
By Lemma 10 we have that is equivalent to
[TABLE]
and the result then follows by a straightforward induction on .
Now, supposing for example that we work in an instance of our language, as in Section 2.1, where there are just two constructor symbols and , which we interpret in the usual way as and so that they are compatible with . In this case our main soundness theorem becomes
Theorem 12**.**
If for all function symbols of our language there is a suitably defined satisfying whenever for all and values , then any term has an interpretation which majorizes it, in the sense that implies . In particular, whenever and , we have with .
Corollary 13**.**
Any term in System T has an interpretation which majorizes it.
Proof 4.5**.**
We just need to interpret the recursor, to which end we define by
[TABLE]
then it’s easy to show that whenever , and then
[TABLE]
using induction on . Then by Lemma 11 it follows that
[TABLE]
and thus defining it follows that for we have .
Corollary 13 is closely related to classic results of Howard [16] and Bezem [7] which show that various type structures of majorizable functionals are a model of System T. This also holds more generally for bar recursion, and we conjecture that a variant of Theorem 12 dealing with as defined in Section 2.3 can be proven within our framework, though we do not attempt to work out the details here. The most important property of our Theorem 12 is that it can be extended in a uniform way to a number of different programming languages.
5. Extracting moduli of continuity for functional languages
We now utilise the monadic part of our soundness theorem for the first time, to present a simple framework in which we can extract moduli of continuity from those functionals of type level which are definable by a term in our target language.
That all type level functionals definable in System T have a modulus of continuity also definable in T was apparently first presented by Kreisel in lectures from 1971/72, and early proofs can be found in e.g. [32] and [36] (Theorem 2.3.9). The approach presented here is more closely connected to recent work, where continuity and the extraction of corresponding moduli are established by appealing to monads and effects (e.g. [8, 12, 14, 17, 29, 40], though this list is by no means exhaustive). A related monadic translation in all finite types due to the present author, but using the state monad and working in an equational setting, is also the basis for [28].
Our main motivation in studying continuity lies not in the fact that this result is new or surprising in itself, but in demonstrating that it fits elegantly into our uniform framework, which can, moreover, be readily extended to other languages and forms of recursion.
5.1. The languages , and
We illustrate our approach by working in a target language with a single datatype and the usual constructors and , and assume that we have fixed some collection of function symbols . We call this base language , and observe that our simple variant of System T outlined in Section 2.1 is an instance of , which we later label as .
Now, to an arbitrary function we associate a variant (resp. ) of our base language, whose function symbols are the same as those of but now extended to include an oracle whose defining equations are given by
[TABLE]
for each , where here denotes the numeral representation of . Note that for any two functions the languages and have the same terms, and so differ only in the operational semantics of . We clearly distinguish the operational semantics of from that of by using to denote the big-step relation of the latter, which also includes the derived rule .
5.2. The monadic translation
We now define as usual, but this time set . Fixing some , we define the logical relation on terms of via and
[TABLE]
where
[TABLE]
Finally, our denotational semantics of the monadic metalanguage arising from , which is also parametrised by , is defined by firstly instantiating our monadic components as
[TABLE]
and interpreting our constructors in the obvious way. We assume that for each function symbol we have an interpretation which is independent of , and as such, this parameter only plays a role in the interpretation of the oracle function symbol , whereby we set to be
[TABLE]
If we are working in either the full set theoretic model or a continuous model , everything up until now is well defined. As before, it is clear that the interpretation of the constructors is compatible with , and we also have the following:
Lemma 14**.**
The tuple is compatible with .
Proof 5.1**.**
We deal with each rule in turn. We have for any values and parameter , and so is true for any , and in particular .
If then and whenever then . But then in , and since is just we have , and so also in .
Finally, if , and , then we have , and and thus . Now suppose that . Then we have for , and thus , and and therefore . This establishes .
Our main soundness theorem gives rise in this case to the following continuity theorem.
Theorem 15**.**
Suppose that for all non-oracle function symbols of in the base language and any we have whenever . Let be a closed term of . Then we have
[TABLE]
for .
Proof 5.2**.**
By assumption the translation is sound with respect to for the function symbols of (i.e. the non-oracle function symbols of ) so to verify soundness of the extended language it remains to check the oracle symbol . But for any we have
[TABLE]
and thus . Therefore it follows that for any closed in we have . In particular, for , setting we obtain for . But this just means that , which is exactly what we want to show.
Corollary 16**.**
Theorem 15 holds for (i.e. System T as defined in Section 2.1).
Proof 5.3**.**
We need to find a suitable interpretation of the recursors independent of , to which end we define by
[TABLE]
where is as defined in Lemma 3. Then using Lemma 3 together with induction it is straightforward to show that for any parameter , whenever and then .
To see this, note that for the base case we have , and since for any it’s also the case that this implies that and thus .
For the induction step, by we have and by the induction hypothesis . Therefore by Lemma 3 we have
[TABLE]
which implies that for . But since by our operational semantics implies for any , it follows that and hence .
5.3. Continuity of functionals definable in System T
We now use the main theorem above to prove a more traditional formulation of the continuity of System T functionals, namely that any set-theoretic object which is definable in System T is continuous in the following sense:
[TABLE]
where we write if for all . We first set up a connection between and the usual formulation of System T as subset of the set theoretic type structure . {defi}
For each in our target language we define the usual semantic interpretation in as follows: and , and on terms:
[TABLE]
This interpretation then eliminates any difference between our formulation of System T as a call-by-value language and those based on equational calculi: An object of is definable in System T precisely when it is of the form for some closed term in . We now extend the above definition to incorporate our oracle symbol. {defi} For each and in , we define by extending the clauses of Definition 5.3 with
[TABLE]
It is easy to prove that if is a term of which does not contain , then it is also a term of and moreover for any .
We now need a result which confirms that the pure interpretation can be related to the semantic part of .
Lemma 17**.**
Define the auxiliary logical relation on as follows:
[TABLE]
We write if for all . Then for any and in , if then we have .
Proof 5.4**.**
A simple induction on terms. For variables this follows directly. For abstraction, if then
[TABLE]
and thus . For application, since and we have . For the constants the result is trivial, and for the recursor we must show that
[TABLE]
for all , which is a simple induction appealing to a variant of the argument used for application. Finally, for the oracle symbol, we must show that
[TABLE]
for any , which is the case by definition.
Corollary 18**.**
Suppose is a closed term of . Then for any we have .
Proof 5.5**.**
If is a closed term of then in particular it can be viewed as a term of which does not contain , and as such we have . Since by definition, by Lemma 17 we have and thus
[TABLE]
and we are done.
Theorem 19**.**
Suppose that is definable in System T. Then
[TABLE]
where is defined by
[TABLE]
for some closed term representing .
Proof 5.6**.**
If is definable in System T, there is some closed term of such that for all we have . Observing that
[TABLE]
we have implies that . Thus by Theorem 15, which by Corollary 16 applies to , we have and for , and by Corollary 18 we have . Now, by Theorem 15 again, we have where . But by uniqueness of derivations in , we therefore have and therefore and thus .
We also note that the term is, in turn, constructed using only basic operations of the lambda calculus, cartesian product and list operations, together with primitive recursion, and can thus also be defined in some suitable variant of System T.
This section demonstrates how our main result on continuity (Theorem 15) can be reformulated in terms of continuity of functionals . It goes without saying that our approach throughout this section could be extended to other systems, such as extensions of System T with bar recursion, though we don’t go through any of the details here.
6. A denotational cost semantics
In our final application, we show how various denotational complexity semantics of functional languages can be re-obtained in a uniform way in our setting. As mentioned in the introduction, the static cost analysis of functional programs dates back to at least the 1980s [30, 34], and has been explored more recently in a generalised categorical setting [37] and from the perspective of automating the analysis of synthesised programs [1], though naturally these papers constitute just a few representative examples of the very diverse literature on complexity in higher types.
A distinguishing feature shared by each of the works mentioned above is that they view the complexity of a higher-order functional as a higher-order object in its own right, namely a cost functional which not only tracks the number of steps it takes for a higher-order term to reduce to a normal form , but encodes information about the cost of evaluating for any input , and so on. The synthesis of cost functionals from higher-order programs in this sense is readily accomplished in our setting by instantiating the monadic part of our translation as a simple step counting operation. In particular, the result of our translation is an object which is always given as recursive equation in our model which reflects the syntactic structure of the original term . This recursive equation can then be solved to give a closed form expression for the cost of evaluating (see Example 6.1 for an illustration of this in the case of Spector’s search functional).
However, we also show that different choices of our semantic component lead to interesting characterisations of complexity. In particular, by combining the aforementioned cost operation with a form of majorizability similar to that discussed in Section 4.3, we obtain in a uniform way the bounded cost semantics explored recently by Danner et al. in [9, 10].
On top of all this, we apply our translation not just to variants of System T, as is often the case in the literature, but to bar recursive extensions, for which soundness of our cost analysis requires us to appeal to semantic continuity principles as in Section 4.2.
6.1. Exact cost expressions for call-by-value languages
We begin by defining what we mean by the cost of a closed term in our parametrised target language. We do this using annotated big step relations for , where intuitively, iff in rewrite steps. We define this formally in Figure 7.
Throughout this section our main illustrative example will be our list based variant of System T from Section 2.2, together with its bar recursive extension from Section 2.3. As such, we formulate our soundness theorem (Theorem 20) in terms of an arbitrary target language over datatypes and with constructors , and , noting that both of the aforementioned languages follow as simple instances of this. Our monadic translation for exact costs is based on setting with and , and we define our logical relation via
[TABLE]
and thus becomes
[TABLE]
For our denotational semantics of terms, we define the monadic components by
[TABLE]
and interpret our constructors in the obvious way, so that the interpretations are in particular compatible with . Note that it is clear from the definition of cost that is compatible with . Thus our main soundness proof (Theorem 4) results in the following characterisation of costs in higher types.
Theorem 20**.**
Suppose that for each function symbol in our target language there is a suitable interpretation such that whenever . Then for any closed we have
[TABLE]
for some value .
It is relatively straightforward to apply the metatheorem above to the full list based variant of System T, and even its extension with bar recursion. For our basic operators, we have e.g. and , and so on. {defi} For and define .
Lemma 21**.**
- (1)
We have for any , and , where is defined by
[TABLE] 2. (2)
We have for any , , and . where is defined by
[TABLE]
for .
Proof 6.1**.**
Part (a) is a simple induction on the length of , observing that the derived rules for give rise to the following cost rules:
[TABLE]
For part (b), we work in the continuous model as in Section 4.2 and follows the same strategy as the proof of Lemma 7. By keeping track of costs we see that that the derived operational semantics of bar recursion give rise to the following derived cost rules:
[TABLE]
To formally derive each of these rules involves a careful analysis of the defining rules of the bar recursor constants, along with the cost semantics as set out in Figure 7. For the first, note that from the defining equation
[TABLE]
we can infer from . Now if it follows that , since this involves the reduction of two elementary operations, and thus follows from . Putting this all together we obtain
[TABLE]
and from the defining equation
[TABLE]
we derive . The second derived rule is established in a similar manner. Now, continuing with the main proof, we first note that \mathtt{ext}\;\mathbf{a}\lhd_{{\rm Nature}\to{\rm Nature}}\mathop{\hbox to0.0pt{\lambda\hss}\mkern 2.0mu\raisebox{1.18399pt}{\lambda}}i.(1,\hat{a}_{i}), and thus since it follows that v_{1}(\mathtt{ext}\;\mathbf{a})\blacktriangleleft_{\rm Nature}\omega(\mathop{\hbox to0.0pt{\lambda\hss}\mkern 2.0mu\raisebox{1.18399pt}{\lambda}}i.(1,\hat{a}_{i})) and thus with
[TABLE]
As in Lemma 7, we now assume inductively that
[TABLE]
for some fixed and all , and seek to establish . There are two cases to deal with.
- •
Case 1: . Observing that from we have for , it follows that where .
- •
Case 2: . By our assumption we have
[TABLE]
for and thus
[TABLE]
from which we can infer
[TABLE]
Since we then have and thus by Lemma 3 it follows that
[TABLE]
for (c_{1},n)=ha\circ(0,\mathop{\hbox to0.0pt{\lambda\hss}\mkern 2.0mu\raisebox{1.18399pt}{\lambda}}n\;.\;1\mathbin{{+}\mspace{-8.0mu}{+}}\overline{\mathtt{bar}}(\omega,g,h,a::n)). Therefore by the second derived rule we have where (4+c_{0}+c_{1},n)=(4+c_{0})\mathbin{{+}\mspace{-8.0mu}{+}}ha\circ(0,\mathop{\hbox to0.0pt{\lambda\hss}\mkern 2.0mu\raisebox{1.18399pt}{\lambda}}n\;.\;1\mathbin{{+}\mspace{-8.0mu}{+}}\overline{\mathtt{bar}}(\omega,g,h,a::n)).
Putting both cases together we see that holds whenever holds. We now suppose as in Lemma 7 that it is not the case that , and construct an infinite sequence on the metalevel such that
[TABLE]
for all . This time we apply a continuity argument to and the sequence \beta:=\mathop{\hbox to0.0pt{\lambda\hss}\mkern 2.0mu\raisebox{1.18399pt}{\lambda}}i.(1,(a\ast b)_{i}), by which there exists some such that
[TABLE]
for all . In particular setting we have
[TABLE]
Thus for input Case 1 applies and we have
[TABLE]
a contradiction. Therefore it must be the case that for all , which completes the proof.
Corollary 22**.**
Let be a closed term definable in System T plus bar recursion (in the sense of Section 2.3). Then for some value .
{exa}
Consider the so-called Spector search functional given by
[TABLE]
This functional was introduced by Howard in [15], though he attributes it to Kreisel. The idea is that forms a bound on how far we need to look to find some such that , confirming that such an can be computed using bar recursion.
The search functional can be defined in our target language via the closed term
[TABLE]
Then given and , it is not too difficult to work out that
[TABLE]
where is defined as
[TABLE]
Unwinding the defining equations of we obtain
[TABLE]
We now solve the complexity component of these equations to find a closed form expression for the complexity of the search functional. For any function and define by
[TABLE]
We now consider . In the case that we have
[TABLE]
and otherwise we have
[TABLE]
Putting these together we obtain
[TABLE]
We can then use this to expand until we reach a point such that . More precisely, if is the first such point, we have
[TABLE]
This then forms a closed expression for the cost of evaluating whenever and . Note that this cost expression would be formally defined using the Spector search function itself, just as the cost expression for primitive recursion is also a primitive recursive functional.
6.2. Bounded costs
In the final part of the paper, we show how we can modify our denotational cost semantics to provide upper bounds on the cost of derivations, along the lines of [10], which is generalised to a richer language with recursion over arbitrary datatypes in [9]. The main motivation for looking for upper bounds (rather than a precise measure of complexity) is that it allows us to abstract away certain parts of the program (for instance, treating all number inputs as the same) and thereby obtain simplified expressions for the cost of programs. We now no longer denote a numeral by the corresponding natural number , but assign all numerals a uniform size . Lists are then interpreted by a single natural number that represents an upper bound on their length. In this way, we sacrifice precision for a simplified upper bound on the cost of running a program.
To be more precise, while we still have we alter the semantic side of our denotational semantics by setting , and adapt our logical relation so that
[TABLE]
and thus becomes
[TABLE]
It is easy to see that , and as defined in Section 6.1 is also compatible with our new definition of . However, this time we must interpret our constructors differently: We set and , so that for all , and for lists we define and , so that for all . In this way, we ensure that our constructors are compatible with , which then gives rise to the following metatheorem:
Theorem 23**.**
Suppose that each function symbol of our target language is interpreted by some suitable which satisfies whenever . Then for any closed we have
[TABLE]
and some value .
We now demonstrate how this metatheorem can be applied to our list based variant of System T. In order to do this we need to generalise the usual maximum operator between two natural numbers to arbitrary types. {defi}
For types of our target language, define inductively by
[TABLE]
Lemma 24**.**
For all types , if then and for any .
Proof 6.2**.**
Induction on types. We only prove because the other way round is identical. For base types implies , but since then we have . Similarly for lists: implies and thus .
For function types, suppose that , which means that for any we have for some with and . But and by the induction hypothesis , and since were arbitrary we have .
Lemma 25**.**
We have for any , and with , where is defined by
[TABLE]
Proof 6.3**.**
Induction on . If then we must have , and since we have and thus .
For there are two possibilities. Either and as before, and since and (by Lemma 24) we’re done. Otherwise . By the induction hypothesis we have , and since and thus we have (by Lemma 3) which is just
[TABLE]
for , and therefore
[TABLE]
Thus follows from another application of Lemma 24, and we’re done.
As a result of the above lemma, we obtain soundness of the translation for our list based variant of System T, which is analogous to Corollary 3 of [10]:
Corollary 26**.**
Let be a closed term of our list-based variant of System T. Then for some value and .
Naturally, our approach can also be applied to arbitrary rewrite systems whose function symbols have a suitable interpretation, such as forms of recursion over more general data structures, as in [9]. Though the usual formulation of bar recursion does not have a bounded semantics of this kind, we could consider finite variants along the lines of [13, 25].
7. Conclusion
We have introduced a general monadic translation acting on higher-order functional languages, which combines both a monadic component and a semantic component, where the latter could play the role of a normal denotational semantics, or alternatively something more interesting, such a variant of the majorizability relation. Applications of our translation included a proof that functionals of type level two expressible by closed terms in our language are continuous, together with various denotational cost semantics for functional languages. The emphasis throughout was less on obtaining new results, and more on demonstrating that ideas from a range of different areas - from proof theory to static program analysis - can be brought together under the same framework. Nevertheless, as a side product we presented for the first time a cost analysis of Spector’s variant of bar recursion.
So far, our work only applies to functional languages whose function symbols give rise to terminating computations. An obvious next step would be to incorporate partiality into our setting, allowing us to reason about potentially non-terminating computations. In the context of normalization via denotational semantics (discussed here in Section 4.2), this has been explored in more generality by Berger [5], where a term is shown to be strongly normalizing if , where now represents a so-called strict denotational semantics. This approach also appeals to the notion of a stratified rewrite system, where function symbols are labelled with natural numbers in order to track the number of times they can be rewritten. A similar extension of Danner et al’s complexity framework to arbitrary PCF programs is given in [18]. It would be interesting to see if an approach along these lines, using stratified rewrite systems together with a partial denotational semantics, could be used to extend our framework to arbitrary PCF programs, without requiring the user to first prove that function symbols have a suitable interpretation.
There is also, naturally, the prospect of working with other monads and modelling other evaluation strategies, such as parallel computation. However, our simple call-by-value framework based on the writer monad is already rich enough to reason about extensional properties such as majorizability and continuity, and in addition allows us to characterise a variety of cost measures for higher order functional programs.
Acknowledgment
I am extremely grateful to the anonymous referee for their insightful comments and careful reading of the paper, which led to a much improved final version.
The reference list from the paper itself. Each links out to its DOI / PubMed record.
- 1[1] R. Benzinger. Automated higher-order complexity analysis. Theoretical Computer Science , 318(1-2):79–103, 2004.
- 2[2] S. Berardi, M. Bezem, and T. Coquand. On the computational content of the axiom of choice. Journal of Symbolic Logic , 63(2):600–622, 1998.
- 3[3] U. Berger. A computational interpretation of open induction. In Proceedings of Logic in Computer Science (LICS ’04) , pages 326–334. IEEE Computer Society, 2004.
- 4[4] U. Berger. Strong normalization for applied lambda calculi. Logical Methods in Computer Science , 1(2):1–14, 2005.
- 5[5] U. Berger. Continuous semantics for strong normalization. Mathematical Structures in Computer Science , 16:751–762, 2006.
- 6[6] M. Bezem. Strong normalization of barrecursive terms without using infinite terms. Archiv für mathematische Logik und Grundlagenforschung , 25:175–181, 1985.
- 7[7] M. Bezem. Strongly majorizable functionals of finite type: A model for bar recursion containing discontinuous functionals. Journal of Symbolic Logic , 50:652–660, 1985.
- 8[8] Thierry Coquand and Guilhem Jaber. A computational interpretation of forcing in type theory. In P. Dybjer, S. Lindström, E. Palmgren, and G. Sundholm, editors, Epistemology versus Ontology , volume 27 of Logic, Epistemology, and the Unity of Science , pages 203–213. Springer, 2012.
