1 Introduction
The primitive operations associated with certain data types can be separated into constructors and destructors. For example, over the natural numbers, the successor (or increment) function and the constant 0 are constructors, whereas the predecessor (or decrement) function and equalszero test are destructors. Over strings on some fixed alphabet $\Sigma$ , the cons function, which prepends a given character onto a given string, is a constructor, as is the constant naming the empty string. On the other hand, the head function, which isolates the first character of a given string, and the tail function, which deletes it, are destructors, as is the relation which tests whether a string is empty. Similarly, one can define constructors and destructors for trees, heaps, nested lists, and all sorts of other common data types.
A consfree program over any one of these data types is a program in which no constructors occur. For example, consider the following consfree natural number program, which decides whether its input is even:
In other words, to check whether a given number is even, we return “true” if it is equal to zero, return “false” if it is equal to one, and otherwise subtract two and recurse. (Here, $\mathtt{n}\mathtt{2}$ abbreviates $\mathtt{n}\mathtt{1\!\!1}$ .) This program is clearly consfree, as 0 and $+\mathtt{1}$ do not occur within.
Consfree programs clearly do not form a Turing complete language. Given their somewhat severe limitations, it is perhaps surprising that consfree programs retain significant computational power: by a seminal result of Neil Jones (Reference Jones1999), consfree string programs in a simple firstorder functional language capture exactly the class P of polynomialtime relations. In other words, every language in P is decided by some consfree program, and every language decided by a consfree program is in P. Moreover, if we restrict our attention to tailrecursive programs, we capture the class L of logarithmicspace relations in exactly the same sense.
Consfree programs, however, fail to capture the functional versions of any complexity class, e.g., the classes FP and FL of polynomialtime and logarithmicspace functions respectively. Indeed, they cannot even define the simplest function which increases the size of the input. To remedy this deficiency, we introduce the notion of an read/writefactorizable program. Such programs extend the destructonly (or readonly) variables of consfree programs with constructonly (or writeonly) variables. For example, the following addition program is RWfactorizable:
Here $\mathtt{n}$ is a readonly variable of type R, $\mathtt{m}$ is a writeonly variable of type W, and $\mathtt{add}:R \times W \to W$ . Similarly, we can define a string concatenation function of type $R \times W \to W$ by
where $\mathtt{x}$ is a readonly variable of type R, $\mathtt{w}$ is a writeonly variable of type W, $\mathtt{null} : R \to 2$ tests whether readonly string is empty, $\mathtt{cons} : \Sigma \times W \to W$ prepends a character in the alphabet $\Sigma$ to a writeonly string, $\mathtt{hd} : R \to \Sigma$ is the head function, and $\mathtt{tl} : R \to R$ is the tail function.
Consider the problem of programming a RWfactorizable identity function of type $R \to W$ . Notice that the trivial program $\mathtt{id}(\mathtt{x}) = \mathtt{x}$ cannot be consistently typed as $R \to W$ ; instead, we have to destruct the input and construct it again. Over strings, this would look something like $\mathtt{id}(\mathtt{x}) = \mathtt{cat}(\mathtt{x},\mathtt{nil})$ . This shows that information can flow from R values to W values; however, the reverse is not possible.
Finally, let us try to define the base2 exponential function $n \mapsto 2^n$ . The program
is not RWfactorizable, because $\mathtt{double}:R \to W$ , and $\mathtt{exp}$ cannot be welltyped, as its output must agree with both the input and output of $\mathtt{double}$ . However,
is a perfectly legitimate RWfactorizable definition of $n \mapsto 2^n$ , with $\mathtt{f} : R \times W \to W$ .
1.1 Our contribution
The central results of this paper are that

RWfactorizable string programs of type $R \to W$ which are nonnested capture exactly the class FP of polynomialtime functions, and

RWfactorizable strings programs of type $R \to W$ which are tailrecursive capture exactly the class FL of logarithmicspace functions.
In other words, the passage from consfree to RWfactorizable programs is exactly what allows us to extend the results of Jones (Reference Jones1999) from relational to functional classes. The purpose of the nonnested stipulation is to exclude nested recursive programs like leap from line (1), whose outputs can have length exponential in the length of the inputs.^{ Footnote 1 }
A foundational lesson of implicit computational complexity going back to Bellantoni & Cook (Reference Bellantoni and Cook1992) is that any Turingcomplete programming language must allow for the same piece of data to be both read and written. Our results illustrate this phenomenon in a particularly clear way.^{ Footnote 2 }
A natural question to ask about RWfactorizable programs is how to (syntactically) compose them, i.e., produce a program which computes the sequential composition of two given programs. Naive attempts fail: you cannot stick an output of type W directly into an input of type R. So the problem is nontrivial; however, we solve it at the end of this paper.
Both the capturing and composition results utilize the same technical device, namely bitlength computability of a function, which is introduced in this paper. This essentially means computability by two consfree programs, one computing the bits, the other the length, of a given function on each input. Our results suggest that this idea might have some “legs” and be worthy of further study in its own right.
1.2 Organization of this paper
In Section 2, we review some technical background. We then introduce RWfactorizable programs over strings, our main object of study, in Section 3. In Section 4, we introduce bitlength programs, a dialect of consfree programs, and define bitlength computability in Section 5. That section also states that FL and FP are captured by pairs of bitlength programs; a sketch of the proofs is postponed to Appendix B.
Sections 6 defines a compiling function from RWfactorizable to (pairs of) bitlength programs; Section 7 defines a compiling function in the other direction. These two sections establish the equivalence of the two models of computation and thus prove our desired capturing results for RWfactorizable programs. Section 8 treats syntactic composition of bitlength programs and hence of RWfactorizable programs by proxy. Finally in Section 9, we discuss further directions for research.
The beating technical heart of this paper consists of four program transformations in Section 6, two in Section 7, and one in Section 8. Some of these are simple and others more intricate, but each transformation implements a conceptually simple idea which we outline at the top of its respective section. We advise that the reader read these first before diving into the details.
We develop most transformations according to a common template: first describing a transformation of types, then of variables and values, then of terms and programs, and finally proving correctness. In the interests of space, we postpone all the proofs of correctness to Appendix A.
1.3 Related work
The present paper falls squarely into a long tradition of characterizing complexity classes by function algebras, programming languages, and related models of computation, a topic known as implicit computational complexity (ICC). ICC has been an area of interest since, at least, the 1960s (Cobham, 1965), with a resurgence in the last 30 years since the groundbreaking work of Bellantoni & Cook (Reference Bellantoni and Cook1992). There are multiple approaches to ICC, see, e.g., the survey (Hofmann, Reference Hofmann2000) for early developments pre2000, and Dal Lago (Reference Dal Lago2022) for a recent survey about methods involving higherorder programs. Recently, implicit characterizations have been furnished for complexity classes using different modes of computation, or using different modes of computation as a means of characterizing standard complexity classes; in particular, this includes probabilistic computation (Lago & Toldin, Reference Lago and Toldin2015; Lago et al., Reference Lago, Kahle, Oitavem, Tallinn, Bonchi and Puglisi2021), reversible computation (Kristiansen, Reference Kristiansen2022), parallel computation (Baillot & Ghyselen, Reference Baillot and Ghyselen2022), and higherorder complexity (Hainry et al., Reference Hainry, Kapron, Marion and Péchoux2022).
Many of these results are obtained by imposing a type system on a base programming language, as we do in this paper. Of the multitude of different flavors of implicit characterizations, we briefly review the most wellknown ones with connections to our work:

Data ramification. By this, we mean factoring the base data into two or more copies, and restricting how we can access or modify data in each copy. (Our approach of RWfactorization falls into this broad category.) The most common of these is the normal/safe factorization, which underlies many of the foundational papers in the field, e.g., Bellantoni & Cook (Reference Bellantoni and Cook1992), Leivant (Reference Leivant1995), and has a wide variety of applications. Our work is distinguished from these by our use of a generalpurpose programming language with flexible recursive definitions, rather than function algebras based off of primitive recursion. There are other instances of data ramification, for example the secure information flow of Marion (Reference Marion2011), which partitions data into “higher” and “lower” security tiers. This bears resemblance to W and Rdata respectively, but ultimately yields different results: highersecurity data does allow a limited amount of destruction, and FP is characterized by a class of tailrecursive programs. Still, this is perhaps the characterization closest to our own in spirit.

Linearity. By linearity we mean (very roughly) restricting the reuse of variables or primitive operations, e.g., controlling the number of times a constructor can occur in the righthand side of a recursive definition. Approaches to ICC based on linear logic include prooftheoretic approaches like light linear logic (Girard, Reference Girard1998) and soft linear logic (Lafont, Reference Lafont2004), as well as the typebased approach of nonsizeincreasing computation (Hofmann, Reference Hofmann2002). From a practical perspective, they seem to yield more intensionally expressive languages than safe primitive recursion and have been applied to, e.g., cryptographic protocols (Baillot et al,. Reference Baillot, Barthe and Lago2019). There does not seem to be any real technical connection between our work and this approach, except perhaps that our “nonnested” restriction of RWfactorizable programs carries a whiff of a linear typing discipline.

Restricted termination. This is (roughly) the study of measures or bounds on programs or computation states, such that only those programs having execution that terminates within the bound, are part of the characterization. This is a flourishing field, both for traditional programs (Bonfante et al., Reference Bonfante, Marion and Moyen2011; Aubert et al., Reference Aubert, Seiller, Rubiano and Rusch2022) and for nondeterministic models such as term rewriting systems (Avanzini et al., Reference Avanzini, Eguchi and Moser2011, Reference Avanzini, Eguchi and Moser2015; Avanzini & Moser, Reference Avanzini and Moser2016). The approach of the present paper does not use restricted termination in any technical sense, and the characterizations we provide are not reliant on termination; there is, however, a tenuous connection in the sense that we use programs with very restricted ability to construct data structures, and this might be amenable to analysis by methods devised for ICC using restricted termination.

Consfree programs. This is the particular line of inquiry which the present paper belongs to. Jones (Reference Jones1999) was the first to observe that eschewing constructors yields a simple method of capturing polynomialtime and logarithmicspace relations. This paradigm has since been extended to obtain many capturing results in a variety of contexts, e.g., higher types (Jones, Reference Jones2001), nondeterminism (Bonfante, Reference Bonfante2006), simultaneous higher types and nondeterminism (Kop & Simonsen, Reference Kop and Simonsen2017), treelike data (BenAmram & Petersen, Reference BenAmram, Petersen, Larsen, Skyum and Winskel1998), term rewriting systems (de Carvalho & Simonsen, 2014; Czajka, Reference Czajka2018), and consfree time complexity classes (Bhaskar et al., Reference Bhaskar, Kop and Simonsen2022; Jones et al., Reference Jones, Kop, Bhaskar, Simonsen, Fribourg and Heizmann2020). The present paper is the first to consider computability of function classes.
2 Preliminaries
We assume a basic familiarity with syntax and semantics of firstorder functional programming languages, Turing machines, the Turing machine complexity classes P (polynomial time) and L (logarithmic space), and their functional variants FP and FL. Note that when defining a functional space class, the space bound only applies to the work tapes and not the output tape. Hence, the length of the output of function in FL may in general grow polynomially in the length of the input.
Following the settheoretic convention, we identify any natural number n with its set of predecessors $\{0,1,\dots,n1\}$ and we denote the set of all natural numbers by $\omega$ . Therefore, $1 = \{0\}$ , $2 = \{0,1\}$ , and $1^n$ and $2^n$ are the sets of unary and binary strings of length n, respectively. We also identify 0 and 1 with $\bot$ (false) and $\top$ (true), respectively, so 2 is also the set of boolean values.
We denote the set of all finite unary and binary strings by $1^\star$ and $2^\star,$ respectively, following the convention in computer science.^{ Footnote 3 } The empty string is denoted $\varepsilon$ ; its underlying alphabet must be inferred from context. The head of a string is its first character, and its tail is the remainder. The head and tail of $\varepsilon$ are undefined. If x is a string, then $x$ is its length.
We typically use lowercase Latin letters such as m,n,u,v,w,x,y for variables that range over “type0 objects” such as natural numbers and strings. By, e.g., a “nary relation on strings,” we mean a subset of $(2^\star)^n$ . We use capital Latin letters, e.g., P,Q,X,Y, for variable that range over relations, and f,g,h for variables that range over functions. We use lowercase Greek letters for variables that range over types. We use typewriter script for program syntax.
A partial function $f : X \rightharpoonup Y$ is a function $f : X' \to Y$ for some $X' \subseteq X$ ; X’ is the domain of convergence of f. If x is in the domain of convergence of f, we write $f(x) \downarrow$ , otherwise $f(x) \uparrow$ , and say that f “converges” or “diverges” on x, respectively. Partial functions converge strictly, meaning that $f(g(x)) \downarrow$ implies, in particular, that $g(x) \downarrow$ . For two partial functions $f,f':X \rightharpoonup Y$ , we say that $f' \sqsubseteq f$ in case $f'(x) = y \implies f(x) = y$ for all $(x,y) \in X \times Y$ . Finally, note that by “partial function” we do mean a possibly total function, otherwise we will say properly partial.
The semantics of a program p is the partial function denoted by $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}$ . A program p computes a partial function f in case $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}$ is identical to f as a partial function. A program p accepts a set X in case X is the domain of convergence of $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}$ . Finally, a booleanvalued program p decides a set X if it computes the characteristic function of X.
A partial function computed by a program may in general have a dependent type. Given a type $\alpha$ and family of types $\beta(x)$ indexed by $x : \alpha$ , we will refer to the dependent sum type $\sum_{x : \alpha} \beta(x)$ and the dependent product type $\prod_{x : \alpha} \beta(x)$ . (When $\beta$ does not depend on x, these reduce to $\alpha\times\beta$ and $\alpha \to \beta$ respectively.) The language of dependent types provides an elegant formulation for counting modules, but we do not use the machinery of dependent types in any essential way.
A note on functional complexity. Suppose that $f : 2^\star \to 2^\star$ is contained in the class FP of polynomialtime computable functions. Consider the function $f_\ell : 2^\star \to 1^\star$ defined by $f_\ell (x) = f(x)$ , i.e., the length of f(x). Then, $f_\ell$ is also in FP; take, for example, any Turing machine computing f in polynomial time and identify all the characters of its output alphabet. Similarly, consider the function $f_b : 2^\star \times 1^\star \to 2$ defined by $f_b(x,i) = \big( f(x) \big)_i$ , meaning the $i^{\mathrm{th}}$ bit of f(x), for any $x \in 2^\star$ and $i < f(x)$ . This relation is computable in polynomial time as well: on input (x,i), write f(x) on a work tape and extract the $i{\mathrm{th}}$ bit.^{ Footnote 4 }
All this is to say, roughly speaking, that if a function of type $2^\star \to 2^\star$ is computable in polynomial time, then so is its length function and its bits relation. We note that the converse implication is valid too. In other words, if $f_\ell$ and $f_b$ are both computable in polynomial time, then we can compute f in polynomial time by concatenating the bits $f_b(x,i)$ for each $i < f_\ell(x)$ .
In other words, we have reduced the notion of polynomialtime computability of functions of type $2^\star \to 2^\star$ to polynomialtime computability of relations and of functions $2^\star \to 1^\star$ . What do we gain from this? We get some characterization of polynomialtime computability of functions $2^\star \to 2^\star$ in terms of consfree programs. (Consfree programs can handle data of type $1^\star$ with counting modules, a device for reckoning with natural number quantities bounded by a polynomial in the length of the input.) So the polynomialtime computability of $f : 2^\star \to 2^\star$ may be witnessed by two consfree programs: one with string input and counting module output computing the length and another with string and counting module input and boolean outputs, computing the bits. We shall elaborate on this later.
The observations we have made about polynomial time apply respectively to logarithmic space and tailrecursive consfree programs. The proof is slightly different: notice that if $f : 2^\star \to 2^\star$ is in FL, then we cannot compute $f_b(x,i)$ by writing f(x) on a work tape, because it will be too long, in general. However, there is a wellknown trick in space complexity to circumvent this, viz., replacing the writeonly output tape by a work tape that records only the position of the head. Similarly, when computing f(x) using $f_b$ and $f_\ell$ , we compute $f_\ell(x)$ in binary, which compresses it enough to stick it on a work tape.
We compile these observations into an official and easily referenced theorem.
Theorem 1. A function $f:2^\star \to 2^\star$ is computable in polynomial time, respectively, logarithmic space, iff there are functions $f_\ell : 2^\star \to 1^\star$ and $f_b : 2^\star \times 1^\star \to 2$ computing the length and bits of f which are computable in polynomial time, respectively logarithmic space.
3 RWfactorizable programs
Let us work over the set $2^\star$ of binary strings. Consider the following set of string primitives^{ Footnote 5 }

$\mathtt{hd}$ , denoting the head function, of type $2^\star \rightharpoonup 2$ ,

$\mathtt{tl}$ , the tail function, of type $2^\star \rightharpoonup 2$

$\mathtt{null}$ , the empty test, of type $2^\star \to 2$

$\mathtt{nil}$ , a constant naming the empty string, of type $2^\star$ , and

$\mathtt{cons}$ , a binary function prepending a given character onto a given string, of type $2 \times 2^\star \to 2$ .
Now, consider two separate copies of $2^\star$ , viz., R, whose strings are readonly, and W, whose strings are writeonly. Then, we may retype these primitives, replacing each occurrence of $2^\star$ by either R or W as follows:
Note that this typing is consistent with strings in R being “readonly” and strings in W being “writeonly.”
From these primitives, we construct a simple firstorder programming language. First we define the types, then terms, of our programming language, then we define the programs themselves; finally, we equip these programs with an environmentbased bigstep semantics.
Definition 1. The three atomic types are 2, R, and W, denoting the type of booleans, readonly strings, and writeonly strings, respectively. A product type is any expression of the form $\tau_0 \times \dots \times \tau_{n1}$ , for $n \ge 0$ , where each $\tau_i$ is either 2 or R. (W is excluded from product formation.) When $n=0$ , the product is empty. We extend the type constructor $\times$ to apply to product types by
A function type symbol is an expression of one of the following forms
where $\beta$ and $\alpha$ are product types, and $\alpha$ is nonempty.
Definition 2. For each product type $\alpha$ , fix an infinite set $\mathtt{Var}_\alpha$ of variables of type $\alpha$ . For each product type $\beta$ , fix infinite sets $\mathtt{RFsymb}_{\beta \to W}$ and $\mathtt{RFsymb}_{\beta \times W \to W}$ of function symbols of type $\beta \to W$ and $\beta \times W \to W,$ respectively; similarly define $\mathtt{RFsymb}_{\beta \to \alpha}$ for each pair or product types $(\alpha,\beta)$ .
By a variable, we mean any member of any $\mathtt{Var}_\alpha$ , or the symbol $\mathtt{w}$ , which is the sole variable of type W. By a recursive function symbol, we mean any member of one of the sets $\mathtt{RFsymb}_{\beta \to W}$ or $\mathtt{RFsymb}_{\beta \times W \to W}$ , for any $\beta, W$ .
Definition 3. An RW term is any expression that can be derived according to the inference rules in Figure 1.
It is straightforward to show that any RW term has a unique derivation from these inference rules, and that if an RW term contains any subterm of type W, it must itself have type W.
Notice that we restrict the way that W terms can occur: there is only one variable of type W and recursive function symbols of output type W have at most one W input. This restriction, which we may refer to as the Wthinness of RW terms, does not ultimately limit the expressive power of the resulting language. Roughly speaking, this is because a W datum is a sort of black box: no information can flow out of it and it cannot affect the shape of a computation. Think of it as a writeonly output tape of a Turing machine: a single writeonly output tape suffices.
Definition 4 We identify a few important properties of RW terms.

An RW term is explicit if it contains no occurrence of a recursive function symbol.

An RW term is consfree if it is not of type W; equivalently, if it does not contain any subterm of type W.

An RW term is nonnested in case it contains no occurrence of a recursion function symbol of type W inside another occurrence of a recursive function symbol of type W. More precisely, in any application of the bottommost rule of Figure 1, the second hypothesis S must be explicit.

An RW term is tailrecursive in case there is no occurrence of a recursive function symbol inside any other occurrence of a recursive function symbol, or any primitive call, or in the if clause of any $\mathtt{if}\ /\ \mathtt{then}\ /\ \mathtt{else}\ $ term. More precisely, in any application of a rule in the second row of Figure 1, or any application of the three recursive function calls at the bottom of 1, the terms in the hypotheses must be explicit; when forming $\mathtt{if}\ T_0\ \mathtt{then}\ T_1\ \mathtt{else}\ T_2$ , $T_0$ must be explicit.
Remark 1. Notice that every tailrecursive term is also nonnested. Tail recursive RWfactorizable programs will end up capturing FL and nonnested programs will end up capturing FP; the program leap of Section 1 is witness to the necessity of this restriction.
Notice also that to be nonnested we only forbid nested recursive calls of output type W. (Surprisingly, we can always eliminate nested recursive calls in the purely consfree part of a program, though we will not need this result in the present paper.)
Remark 2. We will actually silently use a slightly more general formulation of tail recursion. Notice that tail recursion affords more flexibility to calls to the primitives over recursive calls. For example, it is perfectly legal to write phrases such as $\mathtt{hd}( \mathtt{tl}( \dots ))$ but not $\mathtt{hd}(\mathtt{f}( \dots ))$ , in a tailrecursive program.
However, consider a transformation $T \mapsto T^\diamond$ on terms that uses the recursive functions of a previously defined tailrecursive program $p^ \unicode{x2020}$ . In arguing that $T \mapsto T^\diamond$ preserves tail recursion, it suffices to treat calls to the recursive functions of $p^ \unicode{x2020}$ like calls to the primitives as opposed to other recursive calls.^{ Footnote 6 }
Definition 5. An RWfactorizable program consists of a finite list of distinct recursive function symbols $(\mathtt{f}_0,\dots,\mathtt{f}_k)$ and a definition for each one, which takes one of the following two forms:
where $T_i$ is a RWterm, $\mathtt{x}_i$ is a variable, and every recursive function symbol that occurs in $T_i$ must be one of $(\mathtt{f}_0,\dots,\mathtt{f}_k)$ . Furthermore

If the definition of $\mathtt{f}_i$ is of the form $\mathtt{f}_i(\mathtt{x}_i,\mathtt{w}) = T_i$ , then $\mathtt{f}_i(\mathtt{x}_i,\mathtt{w})$ must be a wellformed RW term of the same type as $T_i$ , and the only variables that may occur in $T_i$ are $\mathtt{x}_i$ and $\mathtt{w}$ .

If the definition of $\mathtt{f}_i$ is of the form $\mathtt{f}_i(\mathtt{x}_i) = T_i$ , then $\mathtt{f}_i(\mathtt{x}_i)$ must be a wellformed RW term of the same type as $T_i$ , and the only variable that may occur in $T_i$ is $\mathtt{x}_i$ .
The head (term) of a program is the lefthand side of its first line, e.g., $\mathtt{f}_0(\mathtt{x}_0)$ or $\mathtt{f}_0(\mathtt{x}_0,\mathtt{w})$ . A program is consfree in case all terms occurring within are consfree.
Remark 3 Any RWfactorizable program can be split into a “purely consfree part” and a “Wpart.” The purely consfree part consists of all recursive function symbols of output type other than W and their definitions. This part is a selfcontained “subprogram”: it does not contain any recursive function calls of type W, and its semantics is independent of the rest of the program. The W part of the program consists of all recursive function symbols of output type W and their definitions. It lies on top of the purely consfree part, using it as a black box.
We equip programs with a standard, callbyvalue, environmentbased bigstep semantics. By a value, we mean an element of the domain of some type, and by an environment, we mean a finite function mapping variables to values.
Definition 6. For a program p, term T, value v of the same type as T, and environment $\rho$ , we define the relation $\rho \vdash_p T \to v$ according to the inference rules in Figure 2. We typically suppress the subscript p from $\vdash$ for legibility.
Definition 7 Given a program p, define $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = v$ iff there is a derivation of $[\mathtt{x} = x] \vdash_p \mathtt{f}_0(\mathtt{x}) \to v$ , where $\mathtt{f}_0(\mathtt{x})$ is the head of p. (If the head of p is of the form $\mathtt{f}_0(\mathtt{x},\mathtt{w})$ , then $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x,w) = v$ iff there is a derivation of $[\mathtt{x} = x, \mathtt{w} = w] \vdash_p \mathtt{f}_0(\mathtt{x},\mathtt{w}) \to v$ .) Since p is deterministic, $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}$ is easily seen to be a partial function.
Note that the relation $\vdash_p$ is independent of the head of p; it is only when defining $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}$ that we care what the head is.^{ Footnote 7 } Aside from specifying the head, neither $\vdash_p$ nor $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}$ is sensitive to the particular order of the recursive function symbols in a program; it is only because of overwhelming programming intuition that we say a list instead of a set of function symbols.
In subsequent sections, we will define programs by extending previously defined programs with additional recursive function symbols and their definitions. This simply means: take the old program, forget what its head is, add new lines to the program—we don’t care in what order—and pick a new head according to the definition at hand. If q is the old program and p the new one, notice that $\vdash_p$ extends $\vdash_q$ .
4 Bitlength programs
In this section, we construct a dialect of consfree programs and use them to define function computability in the manner sketched in Section 2. In other words, two programs are needed to witness the computability of a function $f:2^\star \to 2^\star$ in polynomial time: one that computes the bits of f and the other that computes the length. Hence, we call these programs (rather unimaginatively) bitlength (or BL) programs.
The bitlength dialect differs from the standard consfree language in two ways. The first difference is to replace Rdata with string indices as follows. Imagine a consfree program with a single string input. Then any string constructed during computation will be a suffix of that input. Instead, we might as well consider indices of the input string. Instead of querying the head of the various string suffixes, we query the bit of the input string at the given index.
The second difference is that counting modules—a type of natural numbers with magnitude bounded polynomially in the length of the input—are treated as a separate data type, a dependent type which varies with the length of the input string, as opposed to syntactic sugar.
Each of these modifications confers an advantage. Replacing R values by string indices lends a sort of extensional compositionality to bitlength programs that RWfactorizable programs lack. Meaning, the pair of programs computing a function transforms the same type of information about the input (its bits and length, given by the index primitives) into the same type of information about the output (its bits and length, given by the two programs). Moreover, a careful treatment of counting modules allows for cleaner representation strings in $1^\star$ . (The relevance of unary strings to computation of functions was discussed in Section 2.)
We note that the original paper (Jones, Reference Jones1999) contains a language called $\mathtt{CM}$ for counter machine, which was used as a technical tool in the proofs of the main results of that paper. A variant, $\mathtt{CM}^\mathit{recpoly}$ , is basically identical to our bitlength language. However, our presentation is different enough to justify a separate treatment. For one, CM and its variants are imperative instead of functional. Secondly, indices and counting modules are conflated in CM, whereas we treat them as different types. A glossary between the present paper and (Jones, Reference Jones1999) can be found in Table 1. ^{ Footnote 8 }
As for RW programs, we explain bitlength programs first by discussing types, then terms, then programs, and finally semantics.
Definition 8. For any $n \in \omega$ , the counting module C(n) is a data type whose domain is the set $n = \{0,1,\dots,n1\}$ , and whose primitives consist of constants naming the maximum ( $n  1$ ), minimum (0), and 1, plus operations of addition, subtraction, and comparison and equality tests. Addition and subtraction “top out” and “bottom out” at the maximum and minimum element, respectively.
Definition 9. For any string $x \in 2^\star$ , the set of indices I(x) is a data type whose domain is $x + 1 = \{0,1,\dots,x\}$ , and whose primitives consist of constants naming the maximum ( $x$ ), minimum (0), predecessor (which decrements the index), equality to zero, and bit (which returns the bit of the input at the given index).
Remark 4. We index strings such that the leftmost character has index the length of the string, and the rightmost character has index 1. That is, for any string x, $x = x_{x}x_{x1} \dots x_2 x_1$ . The bit $x_0$ is undefined. This funny indexing makes the compiling between bitlength and consfree programs cleaner, as identifying indices with suffixes identifies $\mathtt{tl}$ with the predecessor function.
Notice that C and I are dependent types; namely, they are families of types indexed by some other value (natural numbers or binary strings). Now we introduce program syntax.
Definition 10. There are three atomic type symbols, 2, I, and C, denoting the type of booleans, indices, and counting modules respectively. A BLtype symbol is any expression of the form $\tau_0 \times \dots \times \tau_{n1}$ , for $n \ge 0$ , where each $\tau_i$ is an atomic type symbol. When $n=0$ , the product is empty, and when $n=1$ , we recover the atomic type symbols. A BLfunction type symbol is an expression of the form $\beta \to \alpha$ , where $\beta$ and $\alpha$ are product types, and $\alpha$ is nonempty.
Definition 11. For a BLtype symbol $\alpha$ , we write $\alpha(x,n)$ to denote the type obtained by specializing each coordinate of $\alpha$ to x or n as appropriate. (Similarly for BLfunction types.)
Remark 5. In the context of a single computation of a bitlength program, x and n will be fixed. Therefore, it is fine to type variables by type symbols, like 2, I, C, $2 \times I \times C$ , etc., since we do not have multiple instantiations of these types in a single computation. In contrast, values have types like I(x), $I(x) \times C(n)$ , etc., where x is a string and n a number.
Definition 12. Fix an infinite set $\mathtt{Var}_\alpha$ of variables of type $\alpha$ , for each BLtype $\alpha$ , and an infinite set $\mathtt{RFsymb}_{\beta \to \alpha}$ of BLfunction symbols of type $\beta \to \alpha$ , for each function type $\beta \to \alpha$ . Then, a bitlength term is any expression which can be derived according to the inference rules in Figure 3.
Definition 13. A bitlength term is explicit in case it contains no occurrence of a recursive function symbol. It is tailrecursive in case no recursive function symbol occurs inside any other recursive call, primitive call, or if clause. (We are not concerned with nonnested bitlength terms.)
Definition 14. A bitlength program is a finite list of lines of the form $\mathtt{f}_i(\mathtt{x}_i) = T_i$ , for $0 \le i \le k$ , where $\mathtt{x}_i$ is a variable whose type agrees with the domain of $\mathtt{f}$ , and the type of $T_i$ agrees with the codomain of $\mathtt{f}_i$ . In addition, the only variable that occurs in $T_i$ must be $\mathtt{x}_i$ , and the only recursive function symbols that occur in $T_i$ must be one of $(\mathtt{f}_0,\dots,\mathtt{f}_k)$ .
Definition 15. For any bitlength program p, input string $x \in 2^\star$ , seed $n \in \omega$ , term T of type $\alpha$ , environment $\rho$ binding the free variables of T, and value v of type $\alpha(x,n)$ , we define the relation
according to the inference rules in Figure 4. Note that there is at most one v satisfying the above relation for each x, n, $\rho$ , p, and T, which means that p is deterministic.
Remark 6. Note the extra two parameters x and n in the definition of semantics of bitlength programs. These may be viewed as analogous to a global variable if you’re a programmer or the structure on the lefthand side of the satisfiability relation if you’re a logician. Without them, the function symbols $\mathtt{max}$ , $+$ , and $\mathtt{bit}$ are ill defined.
Definition 16. For any program p and function $\lambda : \omega \to \omega$ , we define the relation $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x,y) = w$ by
where $\mathtt{f}_0(\mathtt{x}_0) = T_0$ is the head of p. By the determinism of p, $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda$ is a partial function.
Note that the string variable x becomes the first argument of $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda$ . Therefore, if we want to compute a function which has a single string input by a bitlength program, the head of that program must be nullary, i.e., have zero inputs.
Definition 17. Fix a string x, natural number n, and program p, and let $\rho \vdash T \to v$ mean $x,n,\rho \vdash_p T \to v$ . A collision is an occurrence of an inference rule of the form
such that $\min\{v+w,n\} = n$ , in a derivation formed from the inference rules in Figure 4. We say a derivation of $\rho \vdash T \to v$ is collisionfree in case it contains no collisions.
Informally, a collision occurs when an addition operation attempts to overstep (or even meet) the maximum integer bound n in a derivation. The nice thing about collisionfree derivations is that they are oblivious to this bound.
Lemma 1. If $x,n,\rho\vdash_p T \to v$ by a collisionfree derivation and $n' \ge n$ , then $x,n',\rho \vdash_p T \to v$ .
Proof. Notice that in the inference rules of Figure 4, a collision is the only instance in which the conclusion depends on n. Hence if we take a collisionfree derivation and increase n, it is still a valid derivation.
Remark 7. As a consequence of Lemma 1, if $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x,y) =w$ by a collisionfree derivation and $\lambda(n) \le \lambda'(n)$ for all $n \in \omega$ , then $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_{\lambda'}(x,y) = w$ .
Finally, let us discuss the type of the partial function computed $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda$ by a bitlength program p, which will in general be a dependent product type. Suppose the recursive function symbol $\mathtt{f}_0$ in the head of program p has type $\beta \to \alpha$ . Then, the type of $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda$ is
We identify two important special cases. When $\beta$ is the empty tuple and $\alpha = C$ , then
On the other hand, when $\alpha = 2$ and $\beta = C$ , then
(Note that when both $\beta$ is empty and $\alpha =2$ , then $ \mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda : 2^\star \to 2$ .)
5 Bitlength computability of functions
The following theorem is a restatement of the theorems $\mathtt{TM}^\mathit{ptime} \equiv \mathtt{CM}^\mathit{recpoly}$ and $\mathtt{TM}^\mathit{logspace} \equiv \mathtt{CM}^\mathit{poly}$ from Jones (Reference Jones1999).
Theorem. Let f be any function of type $2^\star \to 2$ . Then, the following are equivalent:

f is computable in polynomial time.

There is a polynomially bounded function $\lambda : \omega \to \omega$ and bitlength program p such that $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x) = f(x)$ , without collisions, for any $x \in 2^\star$ .
We get an analogous result by replacing FP with FL and “bitlength program” with “tailrecursive bitlength program” throughout.
We use the following extension of this theorem. The basic observation is that the simulations of Turing machines by programs can be augmented by counting modules that keep track of the lengths of tapes or what comes to the same thing, unary strings. So the simulation extends to Turing machines which return unary strings as output. We sketch the proof in Appendix B.
Theorem 2. For any function $f : 2^\star \to 1^\star$ , the following are equivalent:

f is computable in polynomial time.

There is a polynomially bounded function $\lambda : \omega \to \omega$ and a bitlength program p such that $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x) = f(x)$ , without collisions, for any $x \in 2^\star$ .
For any function $f : 2^\star \times 1^\star \to 2$ and polynomially bounded function $\pi : \omega \to \omega$ , the following are equivalent:

There is a polynomialtime computable function $g : 2^\star \times 1^\star \to 2$ such that $g(x,y) = f(x,y)$ for any string $x \in 2^\star$ and $y \le \pi(x)$ .

There is a polynomially bounded function $\lambda : \omega \to \omega$ and a bitlength program p such that $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x,y) = f(x,y)$ , without collisions, for any $x \in 2^\star$ and $y \le \pi(x)$ .
Moreover, we get an analogous result by replacing FP with FL and “bitlength program” with “tailrecursive bitlength program” throughout.
Note that the recursive function symbol $\mathtt{f}_0$ in the head of the program p should have type C if $f : 2^\star \to 1^\star$ and type $C \to 2$ if $f : 2^\star \times 1^\star \to 2$ .
Combining Theorems 1 and 2, we are able to show the fundamental property of bitlength programs; namely that a function is computable in polynomial time iff there is a pair of bitlength programs computing the length and bits of f, respectively. Similarly, a function is computable in logarithmic space iff there is a pair of tailrecursive bitlength programs computing the length and bits of f respectively.
Theorem 3. For any function $f : 2^\star \to 2^\star$ , f is computable in polynomial time if and only if there is a polynomially bounded function $\lambda : \omega \to \omega$ such that $f(x) < \lambda(x)$ for all $x \in 2^\star$ and a pair of bitlength programs p and q such that
without collisions, for all $x \in 2^\star$ , and additionally for any $i < f(x)$ ,
without collisions, where $\big( f(x) \big)_i$ is the $i\mathrm{th}$ bit of f(x).
Furthermore, we get the analogous result for logarithmic space by requiring that p and q be tailrecursive.
Proof We go through the proof in the polynomialtime case; the proof for the logarithmicspace case is verbatim, replacing “program” by “tailrecursive program” throughout.
Suppose $f : 2^\star \to 2^\star$ is computable in polynomial time. By Theorem 1, there exist polynomialtime computable functions $f_\ell: 2^\star \to 1^\star$ and $f_b:2^\star \times 1^\star \to 2$ such that, for all $x \in 2^\star$ $f_\ell(x) = f(x)$ , and additionally for each $i < f(x)$ , $f_b(x,i) = \big( f(x) \big)_i$ . Let $\pi$ be a polynomially bounded function such that $f(x)< \pi(x)$ .
By Theorem 2 applied to $f_\ell,$ there is a polynomially bounded function $\lambda_1$ and a bitlength program q such that $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{q}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_{\lambda_1}(x) = f_\ell(x)$ , without collisions, for any string x. By Theorem 2 applied to $f_b$ , there is a polynomially bounded function $\lambda_2$ and a bitlength program p such that $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_{\lambda_2}(x,i) = f_b(x,i)$ , without collisions, for any string x and $i < \pi(x)$ . Let $\lambda$ be a polynomially bounded function dominating both $\lambda_1$ and $\lambda_2$ . By Remark 7 concerning collisionfree computation, we can replace $\lambda_1$ and $\lambda_2$ by $\lambda$ in the statements above. By definition of $f_\ell$ , $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{q}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x) = f(x)$ , for any string x. By definition of $f_b$ and since $\pi(x)$ dominates $f(x)$ , n the other direction, suppose we ha for any string x and $i < f(x)$ . This concludes the forward direction.
In the other direction, suppose we have a bound $\lambda$ and programs p and q satisfying the desired properties. Then by Theorem 2, the function $x \mapsto f(x) : 2^\star \to 1^\star$ is computable in polynomial time. Fix a polynomially bounded function $\pi$ such that $f(x) < \pi(x)$ . Then by Theorem 2 again, there is a function $g : 2^\star \times 1^\star \to 2$ , computable in polynomial time, such that $g(x,i) = \mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x,i)$ for every string x and $i < \pi(x)$ . (In particular, $g(x,i) = \big( f(x) \big)_i $ for every string x and $i < f(x)$ .) Finally, by applying Theorem 1 to $x \mapsto f(x)$ and g, we conclude that f is computable in polynomial time.
Theorem 3 suggests the following definition.
Definition 18. Let $f : 2^\star \to 2^\star$ , $\lambda : \omega \to \omega$ , p be a bitlength program whose head recursive function symbol has type $C \to 2$ , and q be a bitlength program whose head recursive function symbol has type C.
Then we say $(\lambda,p,q)$ properly computes f in case $\lambda$ is increasing, $f(x) < \lambda(x)$ for all $x \in 2^\star$ , $ \big( f(x) \big)_i = \mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda (x,i) $ without collisions.
Then, Theorem 3 can be succinctly restated as follows: membership in FP is equivalent to being properly computed by some triple $(\lambda,p,q)$ with polynomially bounded $\lambda$ , and membership in FL is equivalent to being properly computed by some triple $(\lambda,p,q)$ with polynomially bounded $\lambda$ and p and q tailrecursive.
6 Compiling RWfactorizable to bitlength programs
We now show how to compile an RWfactorizable program into a pair of bitlength programs that properly computes the same function. This consists of four program transformations:

1. The “dagger” transformation $ \unicode{x2020}$ , that translates the RWterms without W into the bitlength variant without counting modules. (So, substrings of the input string are reinterpreted as indices, $\mathtt{hd}$ is reinterpreted as $\mathtt{bit}$ , $\mathtt{tl}$ is reinterpreted as $\mathtt{P}$ , etc.)

2. The “diamond” transformation $\diamond$ that takes an RWterm T of type W into a bitlength term $T^\diamond$ of type 2, which detects whether T denotes a string built up from $\mathtt{w}$ or built up from $\mathtt{nil}$ .

3. A “length” transformation $\ell$ that takes an RWterm T of type W into a bitlength term $T^\ell$ of type C computing the length of T.

4. A “bit” transformation b that takes an RWterm T of type W into a bitlength term $T^b$ of type 2, which has an extra variable $\mathtt{c}$ and computes the bit of T at $\mathtt{c}$ .
Each of these transformations requires a translation of types, then terms and values, then programs, and finally a proof of correctness.^{ Footnote 9 } Moreover, we need to observe that each transformation preserves tail recursion. For that reason, this section is long, even though the main idea of each translation is easy to intuit:

The dagger transformation is straightforward, essentially amounting to a “renaming” of primitives.

Operationally, when we evaluate a RWterm T of type W into a value v according to an environment $\rho$ , v is constructed by starting with either the empty string $\varepsilon$ or the string $w = \rho(\mathtt{w})$ and $\mathtt{cons}$ ing various bits in front. The term $T^\diamond$ detects which of $\varepsilon$ or w v is “built up” from.

Suppose p is an RWfactorizable program that contains a recursive function symbol $\mathtt{f}$ of type $\beta \times W \to W$ . Suppose that $\rho \vdash_p \mathtt{f}(T,S) \to v$ , $\rho \vdash_p \mathtt{f}(T,\mathtt{nil}) \to u$ and $\rho \vdash_p S \to w$ . Then, there are two possibilities. Either $v = uw$ , in which case

• $v = u + w$ , and

• $v_i = w_i$ (if $i \le w$ ), and otherwise is $u_{i  w}$ .

Otherwise $v = u$ , in which case $v = u$ and $v_i = u_i$ . Which case we are in is given to us by the diamond transformation.
The rest of the section essentially consists of making these intuitions formal.
6.1 The dagger transformation
The types in an RWfactorizable program are 2, R, and W. The types in a bitlength program are 2, I, and C. We first define a map from Wfree types to bitlength types and then extend it to variables, recursive function symbols, terms, and programs.
Definition 19. Let $2^ \unicode{x2020} = 2$ and $R^ \unicode{x2020} = I$ , and extend this to product and function types coordinatewise.
Definition 20. For RW variables $\mathtt{x}$ not of type W and function symbols $\mathtt{f}$ not containing any type W, let $\mathtt{x} \mapsto \mathtt{x}^ \unicode{x2020}$ and $\mathtt{f} \mapsto \mathtt{f}^ \unicode{x2020}$ be a map from RWfactorizable variables and function symbols into bitlength variables and function symbols, so that for example, if $\mathtt{x}$ is of type $\tau$ , then $\mathtt{x}^ \unicode{x2020}$ is of type $\tau^ \unicode{x2020}$ . (We may assume these maps are injective.)
Definition 21. Define a map $T \mapsto T^ \unicode{x2020}$ from Wfree RWfactorizable terms to bitlength terms by:

If $T \equiv \mathtt{true}$ or $T \equiv \mathtt{false,}$ , then $T^ \unicode{x2020} \equiv T$ .

If $T \equiv \mathtt{x}$ , then $T^ \unicode{x2020} \equiv \mathtt{x}^ \unicode{x2020}$ .

If $T \equiv \mathtt{hd}(S)$ then $T^ \unicode{x2020} \equiv \mathtt{bit}(S^ \unicode{x2020})$ .

If $T \equiv \mathtt{tl}(S)$ then $T^ \unicode{x2020} \equiv \mathtt{P}(S^ \unicode{x2020})$ .

If $T \equiv \mathtt{null}(S)$ then $T^ \unicode{x2020} \equiv \mathtt{null}(S^ \unicode{x2020})$ .

If $T \equiv T_0 \oplus \dots \oplus T_{n1}$ then $T^ \unicode{x2020} \equiv T^ \unicode{x2020}_0 \oplus \dots \oplus T^ \unicode{x2020}_{n1}$ .

If $T \equiv S[i]$ then $T^ \unicode{x2020} \equiv S^ \unicode{x2020} [i]$ .

If $T \equiv \mathtt{if}\ T_0\ \mathtt{then}\ T_1\ \mathtt{else}\ T_2$ , then $T^ \unicode{x2020} \equiv \mathtt{if}\ T^ \unicode{x2020}_0\ \mathtt{then}\ T^ \unicode{x2020}_1\ \mathtt{else}\ T^ \unicode{x2020}_2$ .

If $T \equiv \mathtt{f}(S)$ then $T^ \unicode{x2020} \equiv \mathtt{f}^ \unicode{x2020}(S^ \unicode{x2020})$ .
Notice that this transformation trivially preserves tail recursion.
Definition 22. For a consfree program $p = (\mathtt{f}_i(\mathtt{x}_i) = T_i)_{0 \le i \le k}$ , let the bitlength program $p^ \unicode{x2020}$ be $ (\mathtt{f}^ \unicode{x2020}_i(\mathtt{x}_i^ \unicode{x2020}) = T^ \unicode{x2020}_i)_{0 \le i \le k}$ . Note that $p^ \unicode{x2020}$ is a wellformed program which is tailrecursive if p is.
Finally, we extend $ \unicode{x2020}$ to a map on values. Note that the type of the map $y \mapsto y^ \unicode{x2020} : R \to I(x)$ depends on an “ambient string” x of which y is a suffix.
Definition 23. For any $b \in 2$ , let $b^ \unicode{x2020} = b$ . For any string $x \in 2^\star$ and any nonempty suffix y of x, let $y^ \unicode{x2020} = y$ (as a member of I(x)). Furthermore,

Extend the map to tuples of data coordinatewise, i.e., if $v=(v_0,\dots,v_{n1})$ is a decomposition of v into atomic types, then $v^ \unicode{x2020} = (v_0^ \unicode{x2020},\dots,v_{n1}^ \unicode{x2020})$ . Note that $(u \circ v)^ \unicode{x2020} = u^ \unicode{x2020} \circ v^ \unicode{x2020}$ , where $\circ$ denotes concatenation.

For an environment $\rho$ , define the environment $\rho^ \unicode{x2020}$ by $\rho(\mathtt{x}) = v \iff \rho^ \unicode{x2020}(\mathtt{x}^ \unicode{x2020}) = v^ \unicode{x2020}$ . (By this, we mean that the domain of $\rho^ \unicode{x2020}$ is the $ \unicode{x2020}$ image of the domain of $\rho$ .)
Next, we prove correctness of the dagger translation.
Definition 24. Let $\rho$ be an RW environment, i.e., a partial, finite map from RW variables to RW data. For a string $x \in 2^\star$ , we say that $\rho$ is an xenvironment in case for every variable $\mathtt{x}$ of type R, $\rho(\mathtt{x})$ is a suffix of x, and similarly, for every variable $\mathtt{x}$ of product type $\tau_0 \times \dots \tau_{n1}$ , $\rho(\mathtt{x})[i]$ is a suffix of x whenever $\tau_i = R$ .
Remark 8. Suppose p is RWfactorizable program, $\rho$ is an xenvironment, T is a consfree term, and $\rho \vdash_p T \to v$ . Then, every R value that appears in the derivation of $\rho \vdash T \to v$ must also be a suffix of x.
The proof of the next lemma is postponed to Appendix A.
Lemma 2. Suppose p is a consfree program, x is a string, $\rho$ is an xenvironment. Then,
Example Consider the program p defined by
Then, $\mathtt{evt}$ and $\mathtt{odt}$ compute whether the number of occurrences of the character $\mathtt{true}$ in the string $\mathtt{y}$ is even or odd, respectively. The program $p^ \unicode{x2020}$ is defined by
Notice that $\mathtt{evt}^ \unicode{x2020}$ and $\mathtt{odt}^ \unicode{x2020}$ compute whether the number of occurrences of $\mathtt{true}$ with index at most $ \mathtt{y}^ \unicode{x2020}$ in the input string is even or odd respectively. Thus, if $\mathtt{y}$ is bound to a suffix y of some string x, then $\mathtt{evt}$ and $\mathtt{odt}$ behave the same on input y as $\mathtt{evt}^ \unicode{x2020}$ and $\mathtt{odt}^ \unicode{x2020}$ behave on input $y^ \unicode{x2020}$ (the index $y$ ) with global input x.
6.2 The diamond transformation
These next three transformations each extend the dagger transformation from pure consfree terms to terms of type W in different ways. In the diamond transformation, we will transform terms of type W into terms of type 2, the idea being that the transformed term will encode which of $\mathtt{nil}$ or $\mathtt{w}$ the original term is built up from.
Definition 25. . For each recursive function symbol $\mathtt{f} : \beta \times W \to W$ , let $\mathtt{f}^\diamond$ be a recursive function symbol of type $\beta^ \unicode{x2020} \to 2$ . (We may assume that the map $\mathtt{f} \mapsto \mathtt{f}^\diamond$ is injective.)
Definition 26. We define a transformation $T \mapsto T^\diamond$ from RW terms of type W to bitlength terms of type 2 as follows:

If $T \equiv \mathtt{w}$ , then $T^\diamond \equiv \mathtt{false,}$ .

If $T \equiv \mathtt{nil}$ , then $T^\diamond \equiv \mathtt{true}$ .

If $T \equiv \mathtt{if}\ T_0\ \mathtt{then}\ T_1\ \mathtt{else}\ T_2$ then $T^\diamond \equiv \mathtt{if}\ T_0^ \unicode{x2020}\ \mathtt{then}\ T_1^\diamond\ \mathtt{else}\ T_2^\diamond$ .

If $T \equiv \mathtt{f}(T')$ for some $\mathtt{f} : \beta \to W$ , then $T^\diamond \equiv \mathtt{true} $ .

If $T \equiv \mathtt{f}(T',S)$ for some $\mathtt{f} : \beta \times W \to W$ , then $T^\diamond \equiv \mathtt{if}\ S^\diamond\ \mathtt{then}\ \mathtt{true} \ \mathtt{else}\ \mathtt{f}^\diamond((T')^ \unicode{x2020})$

If $T \equiv \mathtt{cons}(T',S)$ then $T^\diamond \equiv S^\diamond$ .
Remark 9. This transformation transforms tailrecursive terms into tailrecursive terms. It never produces a primitive call, and the only things it puts inside recursive calls are outputs of the $ \unicode{x2020}$ transformation. The only way it possibly produces a nontailrecursive term is in the case $T \equiv \mathtt{f}(T',S)$ , when $S^\diamond$ goes in an if clause. But if T is tailrecursive, S is explicit, so $S^\diamond$ is explicit, hence contains no recursive function calls.
Definition 27. Given an RWfactorizable program p of type $R \to W$ , we define the bitlength program $p^\diamond$ by extending $p^ \unicode{x2020}$ as follows. For every function symbol $\mathtt{f}_i$ of type $ \beta \times W \to W$ with definition $\mathtt{f}_i(\mathtt{x}_i,\mathtt{w}) = T_i$ , we add a new line $ \mathtt{f}_i^\diamond(\mathtt{x}_i^ \unicode{x2020}) = T_i^\diamond. $ Note that $p^\diamond$ is tailrecursive if p is.
We ignore function symbols of type $\beta \to W$ . Also, we do not bother to specify a head, because we will only need $\vdash_{p^\diamond}$ , not $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p^\diamond}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}$ .
Note that $p^\diamond$ is a wellformed program: its recursive function symbols consist exactly of $\mathtt{f}_i^ \unicode{x2020}$ for $\mathtt{f}_i$ of type nonW and $\mathtt{f}_i^\diamond$ for $\mathtt{f}_i$ of type $\beta \times W \to W$ . For the latter, the term $\mathtt{f}_i^\diamond(\mathtt{x}_i^ \unicode{x2020})$ is wellformed and of the same type as $T_i^\diamond$ . The only variable that may occur in $T_i^\diamond$ is $\mathtt{x}_i^ \unicode{x2020}$ . Notice as well that $p^\diamond$ contains no terms of type C. Hence, when specifying a semantics, we do not need to give a natural number bound n on the upper end of the counting module. Suppose that p is an RWfactorizable program, T is an RW term, $x, v, v',w \in 2^\star$ , $\rho$ is an xenvironment, and $\mathtt{w}$ is not bound by $\rho$ .
Lemma 3. Suppose that $\rho,[\mathtt{w} = w] \vdash_p T \to v$ and $\rho,[\mathtt{w} = \varepsilon] \vdash_p T \to v'$ .^{ Footnote 10 } Then either

$x, \rho^ \unicode{x2020} \vdash_{p^\diamond} T^\diamond \to \top $ and $v = v'$ , or

$x, \rho^ \unicode{x2020} \vdash_{p^\diamond} T^\diamond \to \bot $ and $v = v'w$ .
(The proof is postponed to Appendix A.)
In particular, Lemma 3 implies that for any x, xenvironment $\rho$ , w, and term T, if there exists a v such that $\rho,[\mathtt{w} =w] \vdash T \to v$ , then there exists a boolean b such that $x,\rho^ \unicode{x2020} \vdash_{p^\diamond} T^\diamond \to b$ . We will silently use this fact in the remainder of this paper.
Example Consider the program $\mathit{id}$ defined by
which computes the identity function of type $R \to W$ . Both $\mathtt{id}$ and $\mathtt{cat}$ have output type W; note that $\mathtt{id}$ always builds its output from $\mathtt{nil}$ and $\mathtt{cat}$ always builds its output from the input $\mathtt{w}$ . Then,
We can see that $\mathtt{id}^\diamond$ and $\mathtt{cat}^\diamond$ compute the alwaystrue and alwaysfalse functions, respectively, as they ought to. Note that the dagger and diamond transformations produce Cfree BLterms. By contrast, the subsequent two transformations make crucial use of counting modules.
6.3 The length transformation
In the length transformation, we will be transforming terms of type W into terms of type C. Since the length of any W output of an RWfactorizable program is bounded by a polynomial in the length of the inputs, it makes sense to try to capture the length within a counting module.
Definition 28. For each recursive function symbol $\mathtt{f}$ of type $\beta \times W \to W$ or $\beta \to W$ , let $\mathtt{f}^\ell$ be a recursive function symbol of type $\beta^ \unicode{x2020} \to C$ . (We may assume that the map $\mathtt{f} \mapsto \mathtt{f}^\ell$ is injective.)
Definition 29. We define a transformation $T \mapsto T^\ell$ from RWterms of type W to bitlength terms of type C as follows:

If $T \equiv \mathtt{w}$ or $T \equiv \mathtt{nil}$ , then $T^\ell \equiv 0$ .

If $T \equiv \mathtt{if}\ T_0\ \mathtt{then}\ T_1\ \mathtt{else}\ T_2$ , then $T^\ell \equiv \mathtt{if}\ T^ \unicode{x2020}_0\ \mathtt{then}\ T_1^\ell\ \mathtt{else}\ T_2^\ell$ .

If $T \equiv \mathtt{f}(T')$ , then $T^\ell \equiv \mathtt{f}^\ell((T')^ \unicode{x2020})$ .

If $T \equiv \mathtt{f}(T',S)$ , where S has type W, then
$$ T^\ell \equiv \mathtt{if}\ \mathtt{f}^\diamond((T')^ \unicode{x2020})\ \mathtt{then}\ \mathtt{f}^\ell((T')^ \unicode{x2020})\ \mathtt{else}\ \mathtt{f}^\ell((T')^ \unicode{x2020}) + S^\ell.$$ 
If $T \equiv \mathtt{cons}(T',S)$ , then $T^\ell \equiv 1 + S^\ell$ .
Remark 10. This transformation does not preserve tail recursion, the problem being $\mathtt{f}^\ell((T')^ \unicode{x2020}) + S^\ell$ , where the recursive function symbol $\mathtt{f}^\ell$ occurs within the primitive $+$ . This can be fixed in a couple of ways. For one, we can observe that if T is tailrecursive then $T^\ell$ is linear recursive, which can always be transformed into an equivalent tailrecursive term (Greibach, 1975).
But there is an easier fix in this case: just give each $\mathtt{f}^\ell$ an extra input of type $\mathtt{c}$ , the idea being that the new $\mathtt{f}^\ell(T,\mathtt{c})$ is the old $\mathtt{f}^\ell(T) + \mathtt{c}$ . We have to change each recursive definition $\mathtt{f}^\ell(\mathtt{x}^ \unicode{x2020}) = T^\ell$ to $\mathtt{f}^\ell(\mathtt{x}^ \unicode{x2020},\mathtt{c}) = T^\ell + \mathtt{c}$ . Then $\mathtt{f}^\ell((T')^ \unicode{x2020}) + S^\ell$ becomes $\mathtt{f}^\ell((T')^ \unicode{x2020},S^\ell$ ), and this solves our problem.
Definition 30. Given an RWfactorizable program p of type $R \to W$ , we define the bitlength program $p^\ell$ by extending $p^\diamond$ by adding the following lines for each recursive function symbol of output type W:
Finally, add a new head $ \mathtt{h} = \mathtt{f}^\ell_0(\mathtt{max}) .$ The resulting program is $p^\ell$ ; it is tailrecursive if p is.
Let us check that $p^\ell$ is a welldefined bitlength program. In addition to $p^\diamond$ , it contains recursive function symbols $\mathtt{f}_i^\ell$ for $\mathtt{f}_i$ of output type W. If the only variables that may occur in $T_i$ are $\mathtt{x}_i$ and $\mathtt{w}$ , then the only variable that may occur in $T^\ell_i$ is $\mathtt{x}^ \unicode{x2020}_i$ , and the only recursive function symbols that may occur are the recursive function symbols listed above. Finally, the terms in each line are wellformed and the types of each recursive functions symbol and its definition agree. Finally, notice that since p has type $R \to W$ , $p^\ell$ has type C.
Definition 31. For a value v of type W, let $v^\ell = v$ .
Lemma 4. For every RWprogram p of type $R \to W$ , RW term T from p of type W, strings x, v, and w, natural number $n > v$ , and xenvironment $\rho$ binding $\mathtt{w}$ to w:
where $\delta = 0$ if $\rho^ \unicode{x2020} \vdash_\diamond T^\diamond \to \top $ or $\delta = w$ if $\rho^ \unicode{x2020} \vdash_\diamond T^\diamond \to \bot $ . Moreover, the derivation of the righthand side is collisionfree.
(The proof is postponed to Appendix A.)
Theorem 4. Suppose that p is an RWfactorizable program of type $ R \to W$ and suppose that $\lambda : \omega \to \omega$ satisfies
Then,
moreover, without collisions.
Proof Fix x and suppose that $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = w$ . Suppose $\mathtt{f}_0(\mathtt{x}_0)$ is the head of p. Then, $ [\mathtt{x}_0 = x] \vdash_p \mathtt{f}_0(\mathtt{x}_0) \to w, $ so by Lemma 4, since $\lambda(x) > w$ ,
by a collisionfree derivation. Therefore, since $x^ \unicode{x2020} = x$ (as a member of I(x)), and since $x$ is the denotation of $\mathtt{max}$ , we have
Since $\mathtt{f}_0(\mathtt{max})$ is precisely the head of $p^\ell$ , we have $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p^\ell}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda (x) = w$ , which is what we wanted to prove.
Examples. Consider again the program $\mathit{id}$ given by
Then,
which is semantically equivalent to
It’s now easy to see that for sufficiently large $\lambda$ , $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{\mathit{id}^\ell}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda (x) = x$ , as it ought to. (Recall that the head of $\mathit{id}^\ell$ is $\mathtt{id}^\ell(\mathtt{max})$ .)
Consider the following program $\mathit{leap}$ based off of modifying the program from line (1) in Section 1 to string data:
Then for any string x, $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{\mathit{leap}}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x)$ is a $2^{x}$ length string of only the character $\mathtt{true}$ . Now,
This is semantically equivalent to
which we can see correctly computes the base2 exponential of the length of the input string (given a sufficiently large counting module).
6.4 The bit transformation
In the bit transformation, we will transform terms of type W into terms of type 2, with an additional typeC input. The idea is that the transformed term encodes the bits of the original Wterm.
Definition 32. For each function symbol $\mathtt{f}$ of type $\beta \times W \to W$ or $\beta \to W$ , let $\mathtt{f}^b$ be a recursive function symbol of type $\beta^ \unicode{x2020} \times C \to 2$ . (We may assume that the map $\mathtt{f} \mapsto \mathtt{f}^b$ is injective.)
Definition 33. We define a transformation $T \mapsto T^b$ from RW terms of type W to bitlength terms of type 2 as follows. Here $\mathtt{c}$ is a fixed variable of type C.

If $T \equiv \mathtt{w}$ or $T \equiv \mathtt{nil}$ , then $T^b \equiv \mathtt{false,}$ .^{ Footnote 11 }

If $T \equiv \mathtt{if}\ T_0\ \mathtt{then}\ T_1\ \mathtt{else}\ T_2$ , then $T^b \equiv \mathtt{if}\ T_0^ \unicode{x2020}\ \mathtt{then}\ T_1^b\ \mathtt{else}\ T_2^b$ .

If $T \equiv \mathtt{f}(T')$ , then $T^b \equiv \mathtt{f}^b((T')^ \unicode{x2020},\mathtt{c})$

If $T \equiv \mathtt{f}(T',S)$ , where S has type W, then
$$ T^b \equiv \mathtt{if}\ \mathtt{f}^\diamond((T')^ \unicode{x2020})\ \mathtt{then}\ \mathtt{f}^b((T')^ \unicode{x2020},\mathtt{c})\ \mathtt{else}\ \mathtt{if}\ \mathtt{c} \le S^\ell\ \mathtt{then}\ S^b\ \mathtt{else}\ \mathtt{f}^b((T')^ \unicode{x2020},\mathtt{c}  S^\ell) .$$ 
If $T \equiv \mathtt{cons}(T',S)$ , then $T^b \equiv \mathtt{if}\ \mathtt{c} \le S^\ell\ \mathtt{then}\ S^b\ \mathtt{else}\ (T')^ \unicode{x2020}$ ,
Notice that the only variables that may occur in $T^b$ are $\mathtt{c}$ and $\mathtt{x}^ \unicode{x2020}$ for $\mathtt{x}$ which occur in T, and the only recursive function symbols that may occur are $\mathtt{f}^b$ for $\mathtt{f}$ of output type W, and $\mathtt{f}^ \unicode{x2020}$ for $\mathtt{f}$ of output type nonW, which occur in T.
Remark 11 Not only does this transformation preserve tailrecursive terms, but every term it produces is tailrecursive (as long as we regard previously defined subterms like $S^\ell$ and $\mathtt{f}^\diamond((T')^ \unicode{x2020})$ as explicit, as usual). No matter what T is, no $\mathtt{f}^b$ will occur inside anything other than a then or elseclause in $T^b$ .
Definition 34. Given an RWfactorizable program p of type $R \to W$ , we define the bitlength program $p^b$ by extending $p^\ell$ as follows
Finally, add a new head $ \mathtt{h}(\mathtt{c}) = \mathtt{f}^b_0(\mathtt{max},\mathtt{c}) .$ The resulting program is $p^b$ . It is tailrecursive if p is.
Let us check that for any RWfactorizable program p of type $R \to W$ , $p^b$ is a welldefined bitlength program. It contains the recursive function symbols $\mathtt{f}^b$ for $\mathtt{f}$ in p of type W, and $\mathtt{f}^ \unicode{x2020}$ for $\mathtt{f}$ in p of type nonW. Since the only variable that appears in T is $\mathtt{x}_i$ , the only variables that may appear in $T^b$ are $\mathtt{x}_i^ \unicode{x2020}$ and $\mathtt{c}$ . Finally, the types of $\mathtt{f}^b_i(\mathtt{x}^ \unicode{x2020},\mathtt{c})$ and $T_i$ agree.
Notice that $p^b$ contains $p^\ell$ , and hence $p^\diamond$ and $p^ \unicode{x2020}$ , as “subprograms.” Hence, the semantics of $p^b$ extends the semantics of the previous programs. We now prove its correctness; the proof is postponed to Appendix A.
Lemma 5. For every RW program p of type $R \to W$ , RW term T from p of type W, strings x, w and v, natural numbers $n > v$ and $1 \le c \le v  \delta$ , and xenvironment $\rho$ binding $\mathtt{w}$ to w,
where $\delta = 0$ if $\rho^ \unicode{x2020} \vdash_\diamond T^\diamond \to \top $ or $\delta = w$ if $\rho^ \unicode{x2020} \vdash_\diamond T^\diamond \to \bot $ .^{ Footnote 12 } Moreover, the computation on the righthand side is without collisions.
Theorem 5. Suppose that p is an RWfactorizable program of type $ R \to W$ and suppose that $\lambda : \omega \to \omega$ satisfies
Then,
without collisions.
Proof Fix x, v, and c such that $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = v$ and $1 \le c \le v $ . Suppose that $\mathtt{f}_0(\mathtt{x}_0)$ is the head of p, so that $[\mathtt{x}_0 = x] \vdash_p \mathtt{f}_0(\mathtt{x}_0) \to v$ . Therefore, $[\mathtt{x}_0 = x,\mathtt{w} = \varepsilon] \vdash_p \mathtt{f}_0(\mathtt{x}_0) \to v$ . By Lemma 5, since $\lambda(x) > v$ ,
without collisions. (Notice that $\delta = 0$ as $\mathtt{w}$ is bound to $\varepsilon$ .)
Since $x , \lambda(x) \vdash_{p^b} \mathtt{max} \to x$ and $x = x^ \unicode{x2020}$ , we have
But since the head of $\mathtt{h}(\mathtt{c})$ is defined to be $\mathtt{f}_0^b(\mathtt{max},\mathtt{c})$ , this implies $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p^b}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x,c) = v_c$ , which is exactly what we wanted to show.
Theorems 4 and 5 immediately imply the following result, the statement of correctness for the translation from RWfactorizable to bitlength programs.
Theorem 6. Let $f:2^\star \to 2^\star$ be a function, $\lambda : \omega \to \omega$ satisfy $\lambda(x) > f(x)$ , and p be an RWfactorizable program of type $R \to W$ computing f. Then, $(\lambda,p^\ell,p^b)$ properly computes f.
Example Given the program $\mathit{id}$ defined by
$\mathit{id}^b$ is defined by
where $S \equiv \mathtt{cat}(\mathtt{tl}\ \mathtt{x},\mathtt{w})$ . We know that $S^\ell$ correctly computes the length of $\mathtt{tl}(\mathtt{x})$ , which is (abusing notation) $\mathtt{x}^ \unicode{x2020}  1$ . Moreover,
Recall that $\mathtt{cat}^\diamond$ computes the alwaysfalse function. Combining this all into semantically equivalent and legible pseudocode, we get
We can see that $\mathtt{cat}^b(\mathtt{x}^ \unicode{x2020},\mathtt{c})$ computes the bit indexed by $\mathtt{c}$ : operationally, it decrements the index $\mathtt{x}^ \unicode{x2020}$ until it is equal to the counting module $\mathtt{c}$ , then spits out the bit indexed by $\mathtt{x}^ \unicode{x2020}$ . Hence, $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{\mathit{id}^b}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x,c)$ computes the bit $x_c$ for sufficiently large $\lambda$ and appropriate values of c.
Observe that for sufficiently large $\lambda$ , $(\lambda,\mathit{id}^\ell,\mathit{id}^b)$ correctly bitlength computes the identity function, as $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{\mathit{id}^\ell}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x) = x$ and $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{\mathit{id}^b}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x,c) = x_c$ .
7 Compiling BL to RWfactorizable programs
In this section, we show how to compile a pair of bitlength programs into a single RWfactorizable program, thus establishing extensional equivalence for these two notions of computability, at least for total functions. The core of this section consists of two transformations:

The more significant of these is a transformation $\unicode{x2021}$ , which acts as a sort of inverse to $ \unicode{x2020}$ : it eliminates indices in favor of string suffixes, i.e., Rdata, and counting modules in favor of tuples of Rdata. (More precisely, this is a family of transformations parameterized by how many R values we need to encode a single counting module.) This process transforms every bitlength program into a consfree program with a “global input variable.”

The simpler transformation takes a consfree program with a global input variable into one without. We do this in most naive way possible, simply by passing the global input as an additional parameter to every recursive call.
The former transformation uses a wellknown trick of consfree programming, namely that we can simulate a counting module of size polynomial in the input length by a tuple of suffixes of the input. If we just think of a suffix of the input as encoding its length (i.e., forgetting about its bits), then we can identify it with some single digit $\{0,1,\dots,n\}$ , where n is the length of the input. Therefore, we can identify a ktuple of suffixes with some kdigit number in base $n+1$ , which we can identify in turn with some number less than $(n+1)^k$ . To implement the full data type of a counting module, it simply suffices to implement the fixedwidth arithmetic and comparison operations using consfree programs. In this way, we can replace polynomially bounded counting modules with fixedwidth tuples of R values.
A complication is the fact that our language does not accommodate nested tuples. For example, suppose that we had to replace every counting module of type C by three R values of type $R \times R \times R$ . Then if we had a tuple of type $I \times C \times 2$ , it should be replaced by a tuple of type $(R,R^3,2)$ , but since we don’t have nested tuples, we are required to “flatten it out” into a tuple of type (R,R,R,R,2). This makes indexing harder: to get the element of $R^3$ encoding the counting module, we have to extract the middle three coordinates.
7.1 Programs with global input
Bitlength programs have a global input value, which is the x in the judgment $x , n, \rho \vdash_p T \to v$ . RWfactorizable programs, and consfree programs in particular, do not. It will be convenient to first transform bitlength programs into consfree programs with some global input variable $\mathtt{in}$ , and then eliminate it, instead of trying to cram both in one transformation.
Definition 35. A RW term term with global input is obtained by extending the formation rules of Figure 1 by the additional axiom $\mathtt{in} : R$ . A RWfactorizable program with global input is defined like an ordinary RWfactorizable program, except that the terms $T_i$ are RWterms with global input.
The semantics relation $\vdash$ has the form $x , \rho \vdash T \to v$ (note the additional x argument on the lefthand side) and is defined by extending the rules of Figure 2 by the axiom $x,\rho \vdash \mathtt{in} \to x$ . If $\mathtt{f}_0(\mathtt{x}_0)$ is the head of a program p, then we define
An RWfactorizable program with global input is consfree if it contains no term of type W.
We can easily transform a RW program with global input into one without. The basic idea is to pass the global input explicitly into each recursive function symbol as an extra argument which never gets modified. The remainder of this subsection consists of making this intuition formal. Moreover, we will restrict our attention to consfree programs, because that is the only case we need.
Definition 36. For any RW product term $\alpha$ , let $\alpha_R$ be $\alpha \times R$ . For any RW function term $\rho = \beta \to \alpha$ , let $\rho_R$ be $\beta_R \to \alpha$ . Define an injection $\mathtt{x} \mapsto \mathtt{x}_R$ , $\mathtt{f} \mapsto \mathtt{f}_R$ from variables and recursive function symbols of type $\alpha$ and $\rho$ to type $\alpha_R$ and $\rho_R,$ respectively.
The idea of the next transformation is we replace the variable $\mathtt{x}$ with the variable $\mathtt{x}_R$ . The last coordinate of $\mathtt{x}_R$ stores the “global input” which gets passed around to all the recursive functions in the program, and the rest of the variable stores the “original variable” $\mathtt{x}$ .
Suppose T is a term in which only the variable $\mathtt{x}$ may occur. (Call this an $\mathtt{x}$ term for brevity.) Let n be the length of the type of $\mathtt{x}$ . Define the map $T \mapsto T^\mathtt{x}_R$ from consfree terms with global input to consfree terms as follows (for brevity, we omit the superscript $\mathtt{x}$ ):

If $T \equiv \mathtt{x}$ , then $T_R \equiv \mathtt{x}_R [0,n1]$ .

If $T \equiv \mathtt{in}$ , then $T_R \equiv \mathtt{x}_R [n]$ .

If $T \equiv \mathtt{if}\ T_0\ \mathtt{then}\ T_1\ \mathtt{else}\ T_2$ then $T_R \equiv \mathtt{if}\ (T_0)_R\ \mathtt{then}\ (T_1)_R\ \mathtt{else}\ (T_2)_R$ .

If $T \equiv \mathtt{hd}(S)$ , $\mathtt{tl}(S)$ , or $\mathtt{null}(S)$ , then $T_R \equiv \mathtt{hd}(S_R)$ , $\mathtt{tl}(S_R)$ , or $\mathtt{null}(S_R)$ respectively.

If $T \equiv T_0 \oplus \dots \oplus T_{n1}$ , then $T_R \equiv (T_0)_R \oplus \dots \oplus (T_{n1})_R$ .

If $T \equiv S[i,j]$ , then $T_R \equiv S_R[i,j]$ .

If $T \equiv \mathtt{f}(S)$ , then $T_R \equiv \mathtt{f}_R(S_R \oplus \mathtt{x}_R[n])$ .
Notice that for any RWterm with global input T containing only $\mathtt{x}$ , then $T_R^\mathtt{x}$ is a wellformed RWterm of the same type of T. Moreover, $\mathtt{x}_R$ is the only variable which may occur in $T^\mathtt{x}_R$ . This transformation is easily seen to preserve tail recursion.
Definition 38. Suppose the consfree program with global input p consists of the lines $\mathtt{f}_i(\mathtt{x}_i) = T_i$ for $0 \le i \le k$ . Then define the program $p_R$ to consist of lines $(\mathtt{f}_i)_R((\mathtt{x}_i)_R) = (T_i)^{\mathtt{x}_i}_R$ for $0 \le i \le k$ .
Note that $p_R$ is a welldefined program. It contains the recursive function symbols $(\mathtt{f}_i)_R$ for each $\mathtt{f}_i$ from p. The type of $(\mathtt{x}_i)_R$ is the input type of $(\mathtt{f}_i)_R$ . The type of $(T_i)^{\mathtt{x}_i}_R$ is the type of $T_i$ , which is the output type of $\mathtt{f}_i$ , which is the output type of $(\mathtt{f}_i)_R$ . The only variable that may occur in $(T_i)_R$ is $(\mathtt{x}_i)_R$ , and the only recursive function symbols that may occur are among $((\mathtt{f}_0)_R,\dots,(\mathtt{f}_k)_R)$ .
In the next lemma, recall that if $(u_0,\dots,u_{n1})$ is a decomposition of the value u into atomic values, then by $u \circ x$ we mean $(u_0,\dots,u_{n1},x)$ . Its proof is postponed to Appendix A.
Lemma 6. For any consfree program with global input p, values x u, and v, variable $\mathtt{x}$ , and $\mathtt{x}$ term T,
Hence,
Theorem 7. For any consfree program with global input p with nullary input, string x and value v, if $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = v$, then $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p_R}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = v$ .
Proof Let $\mathtt{f}_0(\mathtt{x})$ be the head of p. Since p has nullary input, $\mathtt{x}$ is a variable of type the empty product, and $\mathtt{x}_R$ is a variable of type R. If $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = v$, then $x \vdash \mathtt{f}_0 \to v$ . By Lemma 6, $[\mathtt{x}_R = x] \vdash (\mathtt{f}_0)_R((\mathtt{x}_0)_R) \to v$ . But since $(\mathtt{f}_0)_R((\mathtt{x}_0)_R)$ is the head of $p_R$ , $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p_R}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = v$ .
7.2 Eliminating indices and counting modules
In this subsection, we show how to compile any bitlength program into a consfree program with global input. We fix a natural number $k \ge 1$ which is the number of copies of R we want to replace every copy of C by. The transformation $\unicode{x2021}$ defined in this section should be understood as parameterized by this number k. First we will define a map on types, variables, and terms, then values, then programs, and we conclude with a proof of correctness.
The main idea: Bitlength programs contain two types of data that RWfactorizable programs do not: indices and counting modules. We replace indices by single R values and counting modules by ktuples of R values.
The former correspondence is straightforward: if the input string x has length n, then its bits are $x_n \dots x_2 x_1$ . R values range over suffixes of x. We encode the index i by the R value $x_i \dots x_2 x_1$ . The “dummy index” 0 is encoded by the empty string. With respect to this encoding, the index primitives $\mathtt{bit}$ , $\mathtt{P}$ , $\mathtt{null}$ , and $\mathtt{max}$ correspond to $\mathtt{hd}$ , $\mathtt{tl}$ , $\mathtt{null}$ , and $\mathtt{in}$ (the global input variable) respectively. The only index primitive that needs to be programmed is $\mathtt{min}$ , which can be replaced by $\mathtt{f}(\mathtt{in})$ , where
Let $\mathtt{zero}_I$ be the term $\mathtt{f}(\mathtt{in})$ .
If we ignore the characters in an Rstring, it simply encodes a length ranging from 0 to $n+1$ ; i.e., a single digit base $n+1$ . Hence, a ktuple of Rdata encodes a kdigit number base $n+1$ , or alternatively, as a natural number less than $(n+1)^k$ . Therefore, ktuples of R data can be used to simulate counting modules which are polynomially bounded in the length of the input.^{ Footnote 13 } The counting modules primitives $+$ , $$ , and $\le$ can be replaced by consfree programs $\mathtt{add}$ , $\mathtt{minus}$ , and $\mathtt{less}$ , which simulate the corresponding primitives on ktuples of R values by mimicking any common algorithm for fixedwidth arithmetic.^{ Footnote 14 } The consfree constants 0 and 1 can similarly be replaced with programs $\mathtt{zero}$ and $\mathtt{one}$ , which compute the constant $(0,\dots,0,0)$ and constant $(0,\dots,0,1)$ functions, respectively.^{ Footnote 15 }
We assume the existence of these five programs without constructing them and note that they can always be made tailrecursive. In fact, all the recursion we need can be collected into a few important subroutines. Thinking of R values as single digits, we can name the largest digit (by the global input variable $\mathtt{in}$ ) and we can decrement digits (by $\mathtt{tl}$ ). Using these primitives, we can define simple tailrecursive subroutines incrementing a digit, comparing two digits, and naming the digit 0. Then, the programs $\mathtt{add}$ , $\mathtt{minus}$ , $\mathtt{less}$ , $\mathtt{zero}$ , and $\mathtt{one}$ are explicit in these subroutines; i.e., can be defined in terms of them using no additional recursion.
Definition 39. Let $2^\unicode{x2021} = 2$ , $I^\unicode{x2021} = R$ , and $C^\unicode{x2021} = R^k$ . For every bitlength product type $\alpha$ , define the RW product type $\alpha^\unicode{x2021}$ by replacing every copy of I by R, replacing every copy of C by $R^k$ , and flattening. For example:
Extend this to a map on function types by $(\beta \to \alpha)^\unicode{x2021} = \beta^\unicode{x2021} \to \alpha^\unicode{x2021}$ .
Finally, for each product type $\alpha$ , define the map $s_\alpha : \alpha^\unicode{x2021} \to \alpha$ by mapping each coordinate of $\alpha^\unicode{x2021}$ to the coordinate “which it comes from” in $\alpha$ . For example, $s_C : k \to 1$ is defined by $s_C(i) = 0$ for all $i \in k$ ; $s_{2 \times I \times C}:k+2 \to 3$ and $s_{2 \times I \times C}(i)$ is 0 if $i=0$ , 1 if $i = 1$ , and 2 otherwise; and
is defined by
Notice that each such map $s_\alpha$ is a monotone (nondecreasing) surjection.
Definition 40. Fix an injection $\mathtt{x} \mapsto \mathtt{x}^\unicode{x2021}$ from bitlength variables to RW variables such that if $\mathtt{x}$ has type $\alpha$ , $\mathtt{x}^\unicode{x2021}$ has type $\alpha^\unicode{x2021}$ . Fix an injection $\mathtt{f} \mapsto \mathtt{f}^\unicode{x2021}$ from bitlength recursive function symbols of type $\rho$ to RW function symbols of type $\rho^\unicode{x2021}$ , for every bitlength function type $\rho$ .
In the next definition, $\mathtt{in}$ is a fixed variable of type R naming the global input, $\mathtt{zero}$ and $\mathtt{one}$ are fixed function symbols of type $ C^ \unicode{x2020}$ , $\mathtt{add}$ and $\mathtt{minus}$ are fixed function symbols of type $(C \times C \to C)^\unicode{x2021}$ , and $\mathtt{less}$ is a fixed function symbol of type $(C \times C \to 2)^\unicode{x2021}$ .
Definition 41. Define a map $T \mapsto T^ \unicode{x2020}$ from bitlength terms to consfree terms with global input by:

If $T \equiv \mathtt{true} $ or $T \equiv \mathtt{false,}$ then $T^\unicode{x2021} \equiv T$ .

If $T \equiv \mathtt{x}$ , a variable of type $\alpha$ , then $T^\unicode{x2021} \equiv \mathtt{x}^\unicode{x2021}$ .

If $T \equiv \mathtt{0}$ then $T^\unicode{x2021} \equiv \mathtt{zero}$ .

If $T \equiv \mathtt{1}$ then $T^\unicode{x2021} \equiv \mathtt{one}$ .

If $T \equiv T_0 + T_1$ then $T^\unicode{x2021} \equiv \mathtt{add}(T_0^\unicode{x2021},T_1^\unicode{x2021})$ .

If $T \equiv T_0  T_1$ then $T^\unicode{x2021} \equiv \mathtt{minus}(T_0^\unicode{x2021},T_1^\unicode{x2021})$ .

If $T \equiv T_0 \le T_1$ , then $T^\unicode{x2021} \equiv \mathtt{less}(T_0^\unicode{x2021},T_1^\unicode{x2021})$ .

If $T \equiv \mathtt{min}$ then $T^\unicode{x2021} \equiv \mathtt{zero}_I$ .

If $T \equiv \mathtt{max}$ then $T^\unicode{x2021} \equiv \mathtt{in}$ .

If $T \equiv \mathtt{P}(S)$ then $T^\unicode{x2021} \equiv \mathtt{tl}(S^\unicode{x2021})$ .

If $T \equiv \mathtt{null}(S)$ then $T^\unicode{x2021} \equiv \mathtt{null}(S^\unicode{x2021})$ .

If $T \equiv \mathtt{bit}(S)$ then $T^\unicode{x2021} \equiv \mathtt{hd}(S^\unicode{x2021})$ .

If $T \equiv T_0 \oplus \dots \oplus T_{n1}$ then $T^\unicode{x2021} \equiv T_0^\unicode{x2021} \oplus \dots \oplus T_{n1}^\unicode{x2021}$ .

If $T \equiv S[i,j]$ , let m be the length of S and n the length of $S^\unicode{x2021}$ . Then, $T^\unicode{x2021} \equiv S^\unicode{x2021}[\imath,\jmath]$ , where the interval $[\imath,\jmath] \subseteq m$ is the $s_\alpha$ preimage of $[i,j] \subseteq n$ .

If $T \equiv \mathtt{if}\ T_0\ \mathtt{then}\ T_1\ \mathtt{else}\ T_2$ then $T^\unicode{x2021} \equiv \mathtt{if}\ T_0^\unicode{x2021}\ \mathtt{then}\ T_1^\unicode{x2021}\ \mathtt{else}\ T_2^\unicode{x2021}$ .

If $T \equiv \mathtt{f}(S)$ , then $T \equiv \mathtt{f}^\unicode{x2021}( S^\unicode{x2021} )$ .
Now we define a map on values. For this definition, recall the bijection
defined by $(d_0,\dots,d_{k1}) \mapsto \sum_{i < k} d_i n^i.$ Intuitively, this identifies kdigit numerals base n with the numbers they denote.
Remark 12. As long as $\mathtt{zero}$ , $\mathtt{one}$ , $\mathtt{add}$ , $\mathtt{minus}$ , and $\mathtt{less}$ are implemented by tailrecursive programs, this transformation is easily seen to preserve tail recursion.
Definition 42. For any string $x \in 2^\star$ , define the map $v \mapsto v^\unicode{x2021}$ as follows. If $v \in 2$ , then $v_x^\unicode{x2021} = v$ . If $v \in I(x)$ , then $v_x^\unicode{x2021}$ is the suffix of x of length $v$ . If $v \in C((x+1)^k)$ , then $v_x^\unicode{x2021}$ is the unique ktuple of suffixes $(s_0,\dots,s_{k1})$ of x such that
If $(v_0,\dots,v_{n1})$ is a decomposition of v into atomic types, then $v^\unicode{x2021} = v_0^\unicode{x2021} \circ \dots \circ v_{n1}^\unicode{x2021}$ . Notice that for any values u and v, $(u \circ v)^\unicode{x2021} = u^\unicode{x2021} \circ v^\unicode{x2021}$ .
Definition 43. Given a bitlength program $p = (\mathtt{f}_i(\mathtt{x}_i) = T_i)$ , the consfree program with global input $p^\unicode{x2021}$ is defined to be $(\mathtt{f}_i^\unicode{x2021}(\mathtt{x}^\unicode{x2021}_i) = T_i^\unicode{x2021}) $ .
This program is welldefined: if $T_i$ is an $\mathtt{x}_i$ term, then $T_i^\unicode{x2021}$ is an $\mathtt{x}_i^\unicode{x2021}$ term. The only recursive function symbols that may occur in $T_i^\unicode{x2021}$ , besides the previously defined $\mathtt{zero}_I$ , $\mathtt{zero}$ , $\mathtt{one}$ , $\mathtt{add}$ , $\mathtt{minus}$ and $\mathtt{less}$ , are the $\mathtt{f}_j^\unicode{x2021}$ . Moreover, it is tailrecursive if p is.
The proof of the next result is postponed to Appendix A.
Lemma 7. For every bitlength program p, bitlength term T from p, string x, xenvironment $\rho$ , and value v,
Lemma 7 and Theorem 7 have the following corollary. Let $p^\unicode{x2021}_R$ be $(p^\unicode{x2021})_R$ .
Theorem 8. For any bitlength program p and polynomially bounded $\lambda : \omega \to \omega$ , string x and value v, if $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x) = v$ without collisions, then $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p^\unicode{x2021}_R}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = v^\unicode{x2021}$ .
Proof Choose k such that $\lambda(n) < (n+1)^k$ for all n and define $\mu:\omega \to \omega$ by $\mu(n) = (n+1)^k$ . Suppose that $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\lambda(x) = v$ without collisions. Then, $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}_\mu(x) = v$ by monotonicity of collisionfree computation. By Lemma 7 and the definition of $p^\unicode{x2021}$ , $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p^\unicode{x2021}}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = v^\unicode{x2021}$ . By Theorem 7, $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p^\unicode{x2021}_R}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x) = v^\unicode{x2021}$ .
Example. The following program of type $C \times C \to C$ multiplies its two inputs. (Or rather, the two coordinates of its single input—recall these are $\mathtt{c}[0]$ and $\mathtt{c}[1]$ .)
Suppose that $k=2$ , so we replace each occurrence of C by two copies of R. Then, the type of $\mathtt{c}^\unicode{x2021}$ is $R^4$ , where the former and latter two copies of R correspond to $\mathtt{c}[0]$ and $\mathtt{c}[1],$ respectively. Hence,
7.3 Building typeW output
So far we have shown that we can convert any bitlength program p into an equivalent consfree RWfactorizable program $p^\unicode{x2021}_R$ . Given a polynomially bounded function $\lambda$ and bitlength programs p and q such that $(\lambda,p,q)$ properly computes a function f, how do we use the consfree programs $q^\unicode{x2021}_R$ and $p^\unicode{x2021}_R$ to form an RWfactorizable program computing f? (As above, $\unicode{x2021}$ is dependent on a parameter k, which we choose large enough so that $(n+1)^k$ dominates $\lambda$ .)
As usual, the basic idea is straightforward. We compute the length of the output string using $q^\unicode{x2021}_R$ . We iterate through indices of the output string less than $q^\unicode{x2021}_R$ and compute the corresponding bit of the output string using $p^\unicode{x2021}_R$ . For each of these computed bits, we $\mathtt{cons}$ them on to a variable $\mathtt{w}$ , which “accumulates” the eventual output.
If we were to write this in a legible but informal imperative pseudocode, it would look like this:
It is easy to see that this program computes f(x) on input x, as it outputs a string of length $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{q^\unicode{x2021}_R}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x)$ (x) whose ith bit is $\mbox{$\lbrack\hspace{0.3ex}\lbrack$}{p^\unicode{x2021}_R}\mbox{$\rbrack\hspace{0.3ex}\rbrack$}(x,i)$ . Written slightly more carefully, we get this:
where $\mathtt{h}_p$ and $\mathtt{h}_q$