Computational Universes


Discussion

If we want to regard computation as being algebraic in nature, then it is natural to think of Shonfinkel's combinators as providing a basis. Thus, we would think of having an algebra U, called a computational universe in which the laws hold.

We would like such a universe to be countably infinite, but will clearly have to accept that many problems, such as the equality of its members, will be undecidable.

We do not want to be prescriptive about a particular universe. For a start we are not taking a reductionist approach, in which a universe is constructed from an ultra-simple base. For, while a reductionist approach is intellectually satisfying, it fails to address the engineering realities of the construction of any programming language, namely that any programming language is implemented on an existing computer which will offer a range of quite complex capabilities. Moreover, since it is desirable for a language to be implementable on a range of computers, it is better that it be specified in terms of a relatively high-level universe, which can then be mapped to a specific computer.

Given that we expect to incorporate some quite high-level operations in our universes, it is useful to avoid prescribing exactly what they are, beyond the minimum required to achieve a computational capability. For different programming languages can be considered as defined on different basis of primitive operations.

[Note for the html form of the document - we shall write <= for set inclusion, \/ for set-union and /\ for set intersection. We shall also use == to denote an equivalence operation]

Definition of Universe

A computational universe is an algebra U with a single non-associative operator (called "application") subject to the axioms below. We write application as juxtaposition, so that u1 u2 denotes the application of the element u1 of U to the element u2 of U.

If the set E is empty, we say that U is a universe without exceptions.

Remark: the above axioms are characteristic of an eager language. For under lazy evaluation, the argument of (K k) x would not be evaluated, so there would be no way of discovering if it were an exception.

Free Universes.

Let B be a set of base elements. We define a term in B as follows Then the free computational universe Free(B) is the set of equivalence classes of terms of B under the laws:

That is, the equivalence relation is the symmetric and transitive closure of t1->t2 iff t1 can be converted into t2 by substituting an instance of the left-hand-side of F1 or F2 by the corresponding instance of its RHS.

Let us denote by t' the equivalence class to which a given term t belongs.


Theorem

For any finite set B, Free(B) is a non-strict computational universe which is exception free.

Proof

Firstly, we need the following lemmas, the first of which shows that application is well-defined, Let us denote the equivalence class of a term t by t'. then it is clear that for all equivalence classes k' x', and for all equivalence classes f' g' x' We can take the exception-set E of the universe to be the empty-set {}. Given that E is empty, all operations are non-strict.

So, it seems that we have a countably infinite model of a computational universe. It should be noted that this is not a constructive algebra in the sense that we can decide whether any two members are equal - the word problem is insoluble. However it does mean that we can go ahead with a clear conscience and prove a few things about computational universes without the agonising suspicion that we are talking about nothing.


Lemma

If U is a computational universe with Shonfinkel combinators S and K and exception set E, then for all u in U, u not in E, SKKu = u.

Proof

SKKu = (Ku)(Ku) = u.

[??? this is flawed - we have to allow that S may crash on non-exception arguments, cos we can render the Y-combinator in SK terms. So we need some concept of ]


Definition

We shall call SKK the I-combinator.

Types of Object

In general we are interested in being able to prove properties of expressions in a given computational universe. In particular, we will be anxious to know in what circumstances an exception can arise. While proving that an exception can never occur is a hard problem, we can quite easily predict circumstances in which an exception will occur.

Following the standard approach of computer science, we introduce the notion of types of object.

Definition

Let U be a computational universe. Then a type T<=U is a subset of U.

Discussion

The above definition of type is non-constructive. It will serve nevertheless to establish some basic attributes of types. Naturally we will have to find a way of constructively specifying a range of types sufficiently diversified as to support worthwhile discovery of erroneous code. However our investigation of non-constructive types will identify operations that we need to perform constructively.

To see the difficulty of proving that an exception can never occur, consider the exception raised by division by zero. We might think that we could elaborate our type-system to avoid the possibility of well-typed expressions raising an exception, but this can rapidly be seen to be impossible - consider the rational function:

                 P[x]
    R[x]   =   --------
                 Q[x]

to know whether R[x] will raise an exception, we have to know the zeros of the polynomial Q[x], which is a non-trivial (and indeed in a certain sense, insoluble) problem. Even if we relaxed our requirement to "f(a) evaluates without exception almost everywhere in A", we still have problems, since to know that this statement is true of R[x] requires knowledge, if not of the Fundamental Theorem of Algebra, at least of the fact that a polynomial can have at most n roots, which, if not exactly a profound theorem, is certainly beyond the scope of knowledge that it is reasonable to expect a type-system to possess.

Definition

Let U be a computational universe, with exception set E. We say that p in U is a procedure if for some u in U, the application (p u) is not in E.

We denote the type of procedures of U by Proc(U), and of exceptions by Exc(U).

Definition

If U is a universe and D and R are types of U, then D->R is the type

Thus if p is a procedure, we say that p has the type D->R if p in D->R. It should be noted that in general, no unique function-type can be ascribed to a procedure. For a given procedure object p it is possible that p in D1 -> R1 and also p in D2 -> R2 where there is way of subsuming these two relationships in the form of p in D3 -> R3 without losing useful discriminatory power. For example, the absolute value function in most first-generation Lisp derivative languages belongs to the following function-types:

But the second does not subsume the first, because the first statement tells us the relevant fact that if we give abs an integer as argument it returns an integer as result.


Lemma (contravariance of domain, covariance of range)

If D1, D2, R1, R2, are types for which D2<=D1 and R1<=R2, then D1->R1 <= D2->R2

Proof

Let p in D1->R1. Then (p d1) in R1 for all d1 in D1.

But D2<=D1. Hence for all d2 in D2, (p d2) in R1. Since however R1 <= R2, we see that (p d2 in R2 .

Thus we have shown that any p in D1->R1. maps D2 to R2, thus establishing our lemma.


A consequence of the contravariance rule is that, for example, despite the fact that Integer<=Number, the type Integer->Integer is not contained in the type Number->Number. Thus the inteersection

is non-redundant.

A simple converse of these two lemmas is clearly not true of all domains. for consider a domain without procedure objects. Then D->R is always the empty-set, so that D1->R1<=D2->R2 is true for any domains and ranges whatever. So, discussion of the converse of these lemmas will have to wait until we have established how richly populated our Procedure type needs to be.



Finding the Type of an Expression

In this section we prove some results required to be able to infer the type of an expression in a computational universe.

The Type of Shonfinkel Combinators.

Since the combinators are denizens of every universe, let's start with their type. As might be expected for such general operators, anything one can say about their type is universally quantified over one or more type-variables.


Lemma

If T is a type, then I:T->T

Proof

Let t in T. Then I t = t. Thus I in T->T.


Lemma

If T1 and T2 are types, then K in T1->T2->T1

Proof

Let t1 in T1, consider (K t1). For all t2 in T2, (K t1) t2 = t1. Thus (K t1) in T2->T1. Hence K in T1->(T2->T1)

Lemma

If T1, T2, T'2 and T3 are types of a universe U without exceptions, where T'2 <= T2, then S in (T1->T2 -> T3) -> (T1->T'2) -> T1 -> T3

Proof

It is sufficient to show that if f in T1->T2->T3 then (S f) in (T1->T'2)->T1->T3

Hence it suffices to show that if, in addition, g in T1->T'2 then (S f g) in T1 -> T3.

Hence it suffices to show that if, in addition, x in T1 then S f g x in T3.

But S f g x = (f x) (g x). Since x in T1, and f in T1->T2->T3, it follows that (f x) in T2->T3. Likewise (g x) in T'2. But T'2<=T2, so that ((f x) (g x)) in T3. Hence (S f g x) in T3, hence (S f g) in T1->T3, hence (S f) in (T1->T'2)->T1->T3, hence

.

One interpretation of the above results is that a particular type for one of the combinators is as an intersection. For example, for any two types T1 and T2:


Finding the type of an application

The following lemma suggests how we can ascribe a type to a function-application, where the function belongs to a type-intersection.

Lemma

Let p in D1->R1 /\ D2->R2 ...Dn->Rn. Let d in D1 /\ D2..Dn. Then (p d) in R1/\R2...Rn.

Proof

For all i of 1..n, d of Di. Now p of Di->Ri. Hence (p d) of Ri for all i of 1..n.


To apply this lemma, suppose we have an expression (p x) where p in D1->R1 /\ D2->R2 ...Dn->Rn, and x in X, for some type X. Then we choose a subsequence Dj1...Djk of the Di for which X<=Dj1...<=Djk. Then we can infer that (p x) in Rj1...Rjk

From the covariance-contravariance lemma, we can readily infer the following.

Lemma

(D1\/D2) -> (R1/\R2) <= (D1->R1)/\(D2->R2).

Particular Universes

A universe U is said to have the integers embedded if there is a type Integer<=U for which

Let us now consider the problem of embedding the rationals in a universe which already has embedded integers. We could go about this in two ways. The rationals could be made disjoint from the integers (which would be the way it would be done in SML), or they can be made to include the integers (as in Common Lisp, Scheme, POP-11, Mathematica). A universe U is said to have the rationals embedded if there is a type Rational<=U for which


We can regard a universe with the rationals embedded as also being a universe with the integers embedded, if we restrict ourselves to the sub-universe generated by 0,1,+,*,negate.

The Hindley-Milner Type Universe

Definition

Let T be a finite set of entities called concrete types. Let V be a countably infinite set of type variables. Let e be an exception. Then a type-term is defined as

Definition

We say that two type-terms t1 and t2 are type-equivalent if the most-general-unifier is a permutation of type-variables.

Clearly the concept of type-equivalence defined above is an equivalence relation.

Definition

If T is a set of base-types, and V is a countably infinite set of type variables, then the Hindley-Milner Universe is the set of equivalence classes of type-terms under type equivalence. As before, we will denote the equivalence class corresponding to a term t by t'.

Clearly, if we have two members u1,u2 of a Hindley-Milner Universe U, we can choose two terms t1,t2 with distinct type variables such that u1 = t1' and u2 = t2'.

Definition

If u1 and u2 are members of HM(T,V) then the application (u1 u2) is defined as follows

Lemma

With the above definition of application, the Hindley-Milner Universe U=HM(T,V,e) is a computational universe with exception {e}

Proof