Cons-free Programming with Immutable Functions

11/09/2017 ∙ by Cynthia Kop, et al. ∙ Københavns Uni 0

We investigate the power of non-determinism in purely functional programming languages with higher-order types. Specifically, we set out to characterise the hierarchy NP ⊆ NEXP ⊆ NEXP^(2) ⊆...⊆ NEXP^(k) ⊆... solely in terms of higher-typed, purely functional programs. Although the work is incomplete, we present an initial approach using cons-free programs with immutable functions.



There are no comments yet.


page 1

page 2

page 3

page 4

This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1 Introduction

In [3], Jones introduces cons-free programming: working with a small functional programming language, cons-free programs are defined to be read-only: recursive data cannot be created or altered (beyond taking sub-expressions), only read from the input. By imposing further restrictions on data order and recursion style, classes of cons-free programs turn out to characterise various classes in the time and space hierarchies of computational complexity. However, this concerns only deterministic classes.

It is tantalising to consider the non-deterministic classes such as : is there a way to characterise these using cons-free programs? Unfortunately, merely adding non-determinism to Jones’ language does not suffice: cons-free programs with data order characterise whether or not a non-deterministic choice operator is included in the language [1], and for higher data orders adding such an operator increases the expressivity from to  [4]. Thus, additional language features or limitations are needed.

In this work, we explore cons-free programs with immutable functions, where data of higher type may be created but not manipulated afterwards. We present some initial ideas to obtain both a characterisation of by terminating cons-free programs with immutable functions, and a generalisation towards all classes in the hierarchy

This is a work in progress; the core results have not yet been fully proven correct, and definitions may be tweaked. The goal is not only to find a characterisation of the hierarchy above, but also to identify the difficulties on the way. It is not unlikely that this could help to find other interesting characterisations, and highlight properties of non-determinism.

2 Preliminaries

A more elaborate presentation of the subjects discussed in this section is available in [4].

2.1 Turing Machines and complexity

We assume familiarity with standard notions of Turing Machines and complexity classes (see, e.g.,

[5, 2]); here, we fix notation.

Turing Machines (TMs) are triples of finite sets of tape symbols, states and transitions, where and contains tuples with (the original state), (the read symbol), (the written symbol), (the direction), and (the result state). Every TM in this paper has a single, right-infinite tape. A TM accepts a decision problem if for any : iff there is an evaluation starting on the tape which ends in the state. For a function, a TM runs in time if for : if accepts , then this can be done in at most steps.

Let be a function. Then, is the set of all such that there exist and a TM running in time that accepts .

For , let and . For , define . Let .

2.2 Non-deterministic programs

We consider functional programs with simple types and call-by-value evaluation. Data constructors (denoted ) are at least , and (denoted infix), although others are allowed.

::= ::= ()

There is no pre-defined integer datatype. Notions of data and values are given by the grammar to the right, where indicates a function symbol defined by one or more clauses. The language supports statements, but has no construct. For a program with main function —where and each have type order —and input data , has result value if there is an evaluation .

There is also a non-deterministic choice construct: may evaluate to a value if some does. Thus, a program can have multiple result values on the same input.

A program with main function accepts a decision problem if for all : iff has result value on input , where and . It is not necessary for to be the only result value.

2.3 Cons-free programs

A clause is cons-free if for all sub-expressions of : if with a data constructor, then or also occurs as a sub-expression of some . A program is cons-free if all its clauses are.

Intuitively, in a cons-free program no new recursive data can be created: all data encountered during evaluation occur inside the input, or as part of some clause.

Example 1

The clauses for below are cons-free; the clauses for are not.

2.4 Counting

Cons-free programs neither have an integer data type, nor a way to construct unbounded recursive data (e.g., we cannot build etc.). It is, however, possible to design cons-free programs operating on certain bounded classes of numbers: by representing numbers as values using the input data. For example, given a list of length as input:

  1. numbers can be represented as lists of length (sub-expressions of );

  2. numbers can be represented as tuples : writing , the number is represented by a tuple such that each has length ;

  3. numbers can be represented by values : writing for the bitvector corresponding to , it is represented by any value such that iff , where is the representation of as a tuple from point (2).

Building on (3), numbers in can be represented by values of type order . It is not hard to construct cons-free rules to calculate successor and predecessor functions, and to test whether a number representation corresponds to .

Jones [3] uses these number representations and counting functions to write a cons-free program with data order which simulates a given TM running in at most steps. However, this program relies heavily on the machine being deterministic.

3 Characterising

To characterise non-deterministic classes we start by countering this problem: we present a cons-free program which determines the final state of a non-deterministic TM running in steps, given number representations for and counting functions.

For a machine (A,S,T), let be a fixed number such that for every and there are at most different triples such that . Let be a set of tuples such that (a) occurs in and (b) each combination occurs at most once in . Now, our simulation uses the data constructors: and noted in Section 2.2; for (writing for the blank symbol), and for ; ; , …, ; and . The rules to simulate the machine are given in Figure 1.

for all
for all
for all s.t.  and
there are no with
Figure 1: Simulating a Non-deterministic Turing Machine

If is a polynomial, this program has data order following (2) of Section 2.4. Thus, non-deterministic cons-free programs with data order can accept any decision problem in . However, since even deterministic such programs can accept all problems in , this is not surprising. What is noteworthy is how we use the higher-order value: there is just one functional variable, which, once it has been created, is passed around but never altered. This is unlike the values representing numbers, where we modify a functional value by taking its “successor” or “predecessor”. This observation leads to the following definition:

Definition 2

A program has immutable functions if for all clauses : (a) the clause uses at most one variable with a type of order , and (b) if there is such a variable, then contains no other sub-expressions with type order .

Every program where all variables have type order automatically has immutable functions. The program of Figure 1 also has immutable functions, provided the number representations all have type order . We thus conclude:

Lemma 3

Every decision problem in is accepted by a terminating cons-free program with immutable functions.

If , then there are and a TM such that for all and : iff there is an evaluation of which accepts in at most steps. Using to build the program of Figure 1, iff accepts , iff .

For terminating cons-free programs with immutable functions to characterise , it remains to be seen that every decision problem accepted by such a program is in . That is, for a fixed program we must design a (non-deterministic) algorithm operating in polynomial time which returns for input data iff has as a result value on input .

Towards this purpose, we first alter the program slightly:

Lemma 4

If , then , where is obtained from by replacing all sub-expressions in the right-hand side of a clause where is not an application by . Here,

  • for .

In addition, there is a transformation which preserves and reflects such that all argument types of defined symbols and all clauses have type order and there are no clauses with a variable of functional type.

[Idea] The / change trivially works, the type order change uses the restriction on data order as detailed in [4, Lemma 1] and functional variables can be avoided because, by immutability, all clauses for must have a variable as their right-hand side.

We implicitly assume that the transformations of Lemma 4 have been done.

To reason on values in the algorithm, we define a semantical way to describe them.

Definition 5

For a fixed cons-free program and input data expressions , let be the set of data expressions which occur either as a sub-expression of some , or as sub-expression of the right-hand side of some clause. For a sort (basic type), let . Also let , and if is not an arrow type,

By relating values of type to elements of , we can prove that Algorithm 6 below returns if and only if is a result value of for input .

Algorithm 6

Let be a fixed, terminating cons-free program with immutable functions.

Input: data expressions .

For every function symbol with type and arity (the number of arguments to in clauses), every and all , note down a “statement” . For all clauses , also note down statements for every sub-expression of , and mapping all to some element of .

Treating as a substitution, mark statements confirmed if .

Now repeat the following steps, until no further changes are made:

  1. Mark statements confirmed if is the first clause that matches and is marked confirmed, where is the “substitution” such that .

  2. Mark statements with a variable confirmed if there is s.t. for all . (By immutability, has base type.)

  3. Mark statements confirmed if both are confirmed.

  4. Mark statements confirmed if (a) and are both confirmed, or (b) and are both confirmed.

  5. Mark statements confirmed if some is confirmed.

  6. Mark statements confirmed if there are with confirmed for and either (a) and is confirmed, or (b) and is confirmed for all .

Output: return the set of all such that is confirmed.

This algorithm has exponential complexity since, for of order , the cardinality of is exponential in the input size (the number of constructors in ). However, since a program with immutable functions cannot effectively use values with type order —so can be transformed to give all values and clauses type order or —and the size of each is polynomial, the following non-deterministic algorithm runs in polynomial time:

Algorithm 7

Let is a type of order which is used as argument type of some . Let , and let number of function symbols. For every clause of base type, and every sub-expression of which has a higher type and is not a variable, generate elements of . Let the functional “values” thus generated .

Now run Algorithm 6, but only consider statements with all and in .

Proposition 8

has result value iff there is an evaluation of Algorithm 7 which returns a set containing .

[Proof Idea] We can safely assume that if , it is derived in the same way each time it is used. Therefore, in any derivation, at most distinct values are created to be passed around; the formation of each value may require number of function symbols additional helper values.

By Lemma 3 and Proposition 8, we have: terminating cons-free programs with immutable functions characterise . This also holds for the limitation to any data order .

4 Beyond

Unlike Jones, we do not obtain a hierarchy of characterisations for increasing data orders. However, we can obtain a hierarchical result by extending the definition of immutable:

Definition 9

A program has order immutable functions if for all clauses : (a) the clause uses at most one variable with a type of order , and (b) if there is such a variable, then contains no other sub-expressions with type order .

Proposition 10

Terminating cons-free programs with order immutable functions characterise .

[Proof Idea] An easy adaptation from the proofs of Lema 3 and Proposition 8.

5 Conclusion and discussion

If Propositions 8 and 10 hold, we have obtained a characterisation of the hierarchy in primarily syntactic terms.

Arguably, this is a rather inelegant characterisation, both because of the termination requirement and because the definition of immutability itself is somewhat arcane; it is not a direct translation of the intuition that functional values, once created, may not be altered.

The difficulty is that non-determinism is very powerful, and easily raises expressivity too far when not contained. This is evidenced in [4] where adding non-determinism to cons-free programs of data order raises the characterised class from to . (In [4], we did not use immutability; alternatively restricting the clauses to disallow partial application of functional variable resulted in the original hierarchy .) In our setting, we must be careful that the allowances made to build the initial function cannot be exploited to manipulate exponentially many distinct values. For example, if we drop the termination requirement, we could identify the lowest number such that holds for any polytime-decidable property , as follows:

Here, the clauses for result in if when representing the successor of as a bitvector , and in otherwise. It is unlikely that the corresponding decision problem is in . Similar problems may arise if we allow multiple higher-order variables, although we do not yet have an example illustrating this problem.

In the future, we intend to complete the proofs, and study these restrictions further. Even if this does not lead to an elegant characterisation of the hierarchy, it is likely to give further insights in the power of non-determinism in higher-order cons-free programs.


  • [1] G. Bonfante. Some programming languages for logspace and ptime. In AMAST, pages 66–80, 2006.
  • [2] N. Jones. Computability and Complexity from a Programming Perspective. MIT Press, 1997.
  • [3] N. Jones. The expressive power of higher-order types or, life without CONS. Journal of Functional Programming, 11(1):55–94, 2001.
  • [4] C. Kop and J. Simonsen. The power of non-determinism in higher-order implicit complexity. In ESOP, pages 668–695, 2017.
  • [5] C. Papadimitriou. Computational Complexity. Addison-Wesley, 1994.