0% found this document useful (0 votes)
30 views

Polymorphic Subtypes For Effect Analysisthe Static Semantics (1997)

This paper presents a type system that integrates polymorphism, subtyping, and effects for the purpose of analyzing programs with communication, such as Concurrent ML. Prior work had succeeded in combining some aspects but not all three. The key idea of this work is to carefully consider effects when determining what variables to generalize over in the let rule, maintaining soundness and substitution properties. This represents an important step in generalizing previous work on subeffecting and incorporating effects into subtyping approaches. The type system is demonstrated on a fragment of Concurrent ML that includes primitives for synchronous communication between processes.

Uploaded by

Lei Ma
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views

Polymorphic Subtypes For Effect Analysisthe Static Semantics (1997)

This paper presents a type system that integrates polymorphism, subtyping, and effects for the purpose of analyzing programs with communication, such as Concurrent ML. Prior work had succeeded in combining some aspects but not all three. The key idea of this work is to carefully consider effects when determining what variables to generalize over in the let rule, maintaining soundness and substitution properties. This represents an important step in generalizing previous work on subeffecting and incorporating effects into subtyping approaches. The type system is demonstrated on a fragment of Concurrent ML that includes primitives for synchronous communication between processes.

Uploaded by

Lei Ma
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

Polymorphic Subtyping for Effect Analysis:

the Static Semantics

Hanne Riis Nielson & Flemming Nielson & Torben Amtoft

Computer Science Department, Aarhus University, Denmark


e-mail:{hrnielson,fnielson,tamtoft}@daimi.aau.dk

Abstract. The integration of polymorphism (in the style of the ML


let-construct), subtyping, and effects (modelling assignment or commu-
nication) into one common type system has proved remarkably difficult.
One line of research has succeeded in integrating polymorphism and sub-
typing; adding effects in a straightforward way results in a semantically
unsound system. Another line of research has succeeded in integrating
polymorphism, effects, and subeffecting; adding subtyping in a straight-
forward way invalidates the construction of the inference algorithm. This
paper integrates all of polymorphism, effects, and subtyping into an an-
notated type and effect system for Concurrent ML and shows that the
resulting system is a conservative extension of the ML type system.

1 Introduction
Motivation. The last decade has seen a number of papers addressing the diffi-
cult task of developing type systems for languages that admit polymorphism in
the style of the ML let-construct, that admit subtyping, and that admit effects
as may arise from assignment or communication.
This is a problem of practical importance. The programming language Stan-
dard ML has been joined by a number of other high-level languages demonstrat-
ing the power of polymorphism for large scale software development. Already
Standard ML contains imperative effects in the form of ref-types that can be
used for assignment; closely related languages like Concurrent ML or Facile fur-
ther admit primitives for synchronous communication. Finally, the trend towards
integrating aspects of object orientation into these languages necessitates a study
of subtyping.
Apart from the need to type such languages we see a need for type systems
integrating polymorphism, subtyping, and effects in order to be able to continue
the present development of annotated type and effect systems for a number of
static program analyses; example analyses include control flow analysis, binding
time analysis and communication analysis. This will facilitate modular proofs of
correctness while at the same time allowing the inference algorithms to generate
syntax-free constraints that can be solved efficiently.

State of the art. One of the pioneering papers in the area is [10] that developed
the first polymorphic type inference and algorithm for the applicative fragment
of ML; a shorter presentation for the typed λ-calculus with let is given in [3].
Since then many papers have studied how to integrate subtyping. A number
of early papers did so by mainly focusing on the typed λ-calculus and only
briefly dealing with let [11, 5]. Later papers have treated polymorphism in full
generality [18, 8]. A key ingredient in these approaches is the simplification of
the enormous set of constraints into something manageable [4, 18].
Already ML necessitates an incorporation of imperative effects due to the
presence of ref-types. A pioneering paper in the area is [21] that develops a
distinction between imperative and applicative type variables: for creation of a
reference cell we demand that its type contain imperative variables only; and
one is not allowed to generalise over imperative variables unless the expression
in question is non-expansive (i.e. does not expand the store) which will be the
case if it is an identifier or a function abstraction.
The problem of typing ML with references (but without subtyping) has lead
to a number of attempts to improve upon [21]; this includes the following:

– [23] is similar in spirit to [21] in that one is not allowed to generalise over a
type variable if a reference cell has been created with a type containing this
variable; to trace such variables the type system is augmented with effects.
Effects may be approximated by larger effects, that is the system employs
subeffecting.
– [19] can be considered a refinement of [23] in that effects also record the region
in which a reference cell is created (or a read/write operation performed);
this information enables one to “mask” effects which have taken place in
“inaccessible” regions.
– [9] presents a somewhat alternative view: here focus is not on detecting
creation of reference cells but rather to detect their use; this means that if
an identifier occurs free in a function closure then all variables in its type
have to be “examined”. This method is quite powerful but unfortunately
it fails to be a conservative extension of ML (cf. Sect. 2.6): some purely
applicative programs which are typeable in ML may be untypeable in this
system.

The surveys in [19, section 11] and in [23, section 5] show that many of these
systems are incomparable, in the sense that for any two approaches it will often
be the case that there are programs which are accepted by one of them but
not by the other, and vice versa. Our approach (which will be illustrated by
a fragment of Concurrent ML but is equally applicable to Standard ML with
references) involves subtyping which is strictly more powerful than subeffecting
(as shown in Example 4); apart from this we do not attempt to measure its
strength relative to other approaches.
In the area of static program analysis, annotated type and effect systems have
been used as the basis for control flow analysis [20] and binding time analysis
[14, 7]. These papers typically make use of a polymorphic type system with
subtyping and no effects, or a non-polymorphic type system with effects and
subtyping. A more ambitious analysis is the approach of [15] to let annotated
type and effect systems extract terms of a process algebra from programs with
communication; this involves polymorphism and subeffecting but the algorithmic
issues are non-trivial [12] (presumably because the inference system is expressed
without using constraints); [1] presents an algorithm that is sound as well as
complete, but which generates constraints that are not guaranteed to have best
solutions. Finally we should mention [22] where effects are incorporated into ML
types in order to deal with region inference.

A step forward. In this paper we take an important step towards integrating


polymorphism, subtyping, and effects into one common type system. As far as
the annotated type and effect system is concerned this involves the following key
idea:
– Carefully taking effects into account when deciding the set of variables over
which to generalise in the rule for let; this involves taking upwards closure
with respect to a constraint set and is essential for maintaining semantic
soundness and a number of substitution properties.
This presents a major step forward in generalising the subeffecting approach
of [19] and in admitting effects into the subtyping approaches of [18, 8]. The
development is not only applicable to Concurrent ML (with communication)
but also Standard ML (with references) and similar settings.

The essence of Concurrent ML. In this paper we study a fragment of Con-


current ML (CML) that as ML includes the λ-calculus and let-polymorphism,
but which also includes five primitives for synchronous communication:
The constant channel allocates a new communication channel when applied
to ().
The function fork spawns a new process e when applied to the expression
fn dummy ⇒ e; this process will then execute concurrently with the other pro-
cesses, one of which is the program itself.
The constant sync activates and synchronises a delayed communication cre-
ated by either send or receive. Thus one process can send the value of e to
another process by the expression sync (send (ch,e)) where communication
takes place along the channel ch; similarly a process can receive a value from
another process by the expression sync (receive (ch)).
The following program illustrates some of the essential features: it is a version
of the well-known map function except that a process is forked for each tail while
the forking process itself works on the head.
rec map2 f =>
fn xs =>
if isnil(xs) then []
else let ch = channel ()
in fork (fn d =>
(sync (send (ch, map2 f (tl xs)))));
cons (f (hd xs))
(sync (receive ch))
That is, when applied to some function f and say the list [x1,x2,x3] the initial
process p0 will wait for a new process p1 to send the value of [f x2,f x3] over a
new channel ch1 and in the meantime p0 computes f x1 such that it can finally
return the value of [f x1,f x2,f x3]; p1 will do its job by waiting for a new
process p2 to communicate the value of [f x3] over a new channel ch2 and in
the meantime p1 computes f x2; etc.

Overview. We develop an annotated type and effect system in which a simple


notion of behaviours is used to keep track of the types of channels created; unlike
previous approaches by some of the authors no attempt is made to model any
causality among the individual behaviours. Finally, we show that the system is
a “conservative extension” of the usual type system for Standard ML.
The formal demonstration of semantic soundness, as well as the construction
of the inference algorithm, are dealt with in companion papers [2, 13].

2 Inference System
The fragment of Concurrent ML [17, 16] we have chosen for illustrating our
approach has expressions (e ∈ Exp) and constants (c ∈ Con) given by the
following syntax:
e ::= c | x | fn x ⇒ e | e1 e2 | let x = e1 in e2
| rec f x ⇒ e | if e then e1 else e2
c ::= () | true | false | n | + | * | = | · · ·
| pair | fst | snd | nil | cons | hd | tl | isnil
| send | receive | sync | channel | fork
For expressions this includes constants, identifiers, function abstraction, applica-
tion, polymorphic let-expressions, recursive functions, and conditionals; a pro-
gram is an expression without any free identifiers.
Constants can be divided into four classes, according to whether they are
sequential or non-sequential and according to whether they are constructors or
base functions.
The sequential constructors include the unique element () of the unit type,
the two booleans, numbers (n ∈ Num), pair for constructing pairs, and nil and
cons for constructing lists.
The sequential base functions include a selection of arithmetic operations,
fst and snd for decomposing a pair, and hd, tl and isnil for decomposing and
inspecting a list.
We shall allow to write (e1 ,e2 ) for pair e1 e2 , to write [] for nil and
[e1 · · · en ] for cons (e1 ,cons(· · ·,nil) · · ·). Additionally we shall write e1 ;e2
for snd (e1 ,e2 ); to motivate this notice that since the language is call-by-value,
evaluation of the latter expression will give rise to evaluation of e1 followed by
evaluation of e2 , the value of which will be the final result.
The unique flavour of Concurrent ML is due to the non-sequential constants
which are the primitives for communication; we include five of these but more
(in particular choose and wrap) can be added. The non-sequential constructors
are send and receive: rather than actually enabling a communication they
create delayed communications which are first-class entities that can be passed
around freely. This leads to a very powerful programming discipline (in particular
in the presence of choose and wrap) as is discussed in [17]. The non-sequential
base functions are channel for allocating new communication channels, fork for
spawning new processes, and sync for synchronising delayed communications;
examples of their use are given in the Introduction.

Remark. We stated in the Introduction that our development is widely appli-


cable. To this end it is worth pointing out the similarities between the ref-types
of Standard ML and the delayed communications of Concurrent ML. In particu-
lar ref e corresponds to channel (), e1 :=e2 corresponds to sync (send (e1 ,e2 )),
and !e corresponds to sync (receive e). Looking slightly ahead the Standard ML
type t ref will correspond to the Concurrent ML type t chan. 2

Example 1. Consider the program

fn f => let id = fn y =>


(if true
then f
else fn x =>
(sync (send (channel (), y));
x));
y
in id id

that takes a function f as argument, defines an identity function id, and then
applies id to itself. The identity function contains a conditional whose sole pur-
pose is to force f and a locally defined function to have the same type. The
locally defined function is yet another identity function except that it attempts
to send the argument to id over a newly created channel. (To be able to execute
one would need to fork a process that could read over the same channel.)
This program is of interest because it will be rejected by a system using
subeffecting only, whereas it will be accepted in the systems of [19] and [21]. We
shall see that we will be able to type this program in our system as well! 2

2.1 Annotated Types

To prepare for the type inference system we must clarify the syntax of types,
effects, type schemes, and constraints. The syntax of types (t ∈ Typ) is given by:

t ::= α | unit | int | bool | t1 × t2 | t list


| t1 →b t2 | t chan | t com b
Here we have base types for the unit type, booleans and integers; type variables
are denoted α; composite types include the product type, the function type and
the list type; finally we have the type t chan for a typed channel allowing values
of type t to be transmitted, and the type t com b for a delayed communication
that will eventually result in a value of type t.
Except for the presence of a b-component in t1 →b t2 and t com b this is
much the same type structure that is actually used in Concurrent ML [17]. The
role of the b-component is to express the dynamic effect that takes place when
the function is applied or the delayed communication synchronised. Motivated
by [19] and (a simplified version of) [15] the syntax of effects, or behaviours,
(b ∈ Beh) is given by:

b ::= {t chan} | β | ∅ | b1 ∪ b2

Apart from the presence of behaviour variables (denoted β) a behaviour can thus
be viewed as a set of “atomic” behaviours each of form {t chan}, recording the
allocation of a channel of type t chan. The definition of types and behaviours is
of course mutually recursive.
A constraint set C is a finite set of type (t1 ⊆ t2 ) and behaviour inclusions
(b1 ⊆ b2 ). A type scheme (ts ∈ TSch) is given by

ts ::= ∀(~
αβ~ : C). t

where α~ β~ is the list of quantified type and behaviour variables, C is a constraint


set, and t is the type. We regard type schemes as equivalent up to alpha-renaming
of bound variables. There is a natural injection from types into type schemes
which takes the type t into the type scheme ∀(() : ∅). t.
We list in Figure 1 the type schemes of a few selected constants. For those
constants also to be found in Standard ML the constraint set is empty and the
type is as in Standard ML except that the empty behaviour has been placed on
all function types. The type of sync interacts closely with the types of send and
receive: if ch is a channel of type t chan, the expression receive ch is going to
have type t com ∅, and the expression sync (receive ch) is going to have type
t; similarly for send. The type of channel (indirectly) records the type of the
created channel in the behaviour labelling the function type. Finally1 the type
of fork indicates that the argument may have any behaviour whatsoever, in
particular this means that e in fork (fn dummy ⇒ e) may create new channels
without this being recorded in the overall effect2 .
Following the approach of [18, 8] we will incorporate the effects of [19, 15] by
defining a type inference system with judgements of the form

C, A ⊢ e : σ & b

where C is a constraint set, A is an environment i.e. a list [x1 : σ1 , · · · , xn : σn ] of


typing assumptions for identifiers, σ is a type t or a type scheme ts, and b is an
1
As discussed previously one might add wrap to the language: this constant trans-
forms delayed communications of type t com b into delayed communications of type
t′ com b′ ; here b′ (and thus also b) may be non-trivial.
2
To repair this one could add behaviours of form fork b.
c TypeOf(c)

+ int × int →∅ int

pair ∀(α1 α2 : ∅). α1 →∅ α2 →∅ α1 × α2


fst ∀(α1 α2 : ∅). α1 × α2 →∅ α1
snd ∀(α1 α2 : ∅). α1 × α2 →∅ α2
send ∀(α : ∅). (α chan) × α →∅ (α com ∅)

receive ∀(α : ∅). (α chan) →∅ (α com ∅)


sync ∀(αβ : ∅). (α com β) →β α
channel ∀(αβ : {{α chan} ⊆ β}). unit →β (α chan)

fork ∀(αβ : ∅). (unit →β α) →∅ unit

Fig. 1. Type schemes for selected constants.

effect. This means that e has type or type scheme σ, and that its execution will
result in a behaviour described by b, assuming that free identifiers have types as
specified by A and that all type and behaviour variables are related as described
by C.
The overall structure of the type inference system of Figure 2 is very close to
those of [18, 8] with a few components from [19, 15] thrown in; the novel ideas of
our approach only show up as carefully constructed side conditions for some of
the rules. Concentrating on the “overall picture” we thus have rather straight-
forward axioms for constants and identifiers; here A(x) denotes the rightmost
entry for x in A. The rules for abstraction and application are as usual in effect
systems: the latent behaviour of the body of a function abstraction is placed
on the arrow of the function type, and once the function is applied the latent
behaviour is added to the effect of evaluating the function and its argument (re-
flecting that the language is call-by-value). The rule for let is straightforward
given that both the let-bound expression and the body needs to be evaluated.
The rule for recursion makes use of function abstraction to concisely represent
the “fixed point requirement” of typing recursive functions; note that we do not
admit polymorphic recursion3 . The rule for conditional is unable to keep track
of which branch is chosen, therefore an upper approximation of the branches is
taken. We then have separate rules for subtyping, instantiation and generalisa-
tion and we shall explain their side conditions shortly.

3
Even though this is undecidable in general [6] one might allow polymorphic recursion
in the annotations as in [7] or [22].
(con) C, A ⊢ c : TypeOf(c) & ∅

(id) C, A ⊢ x : A(x) & ∅

C, A[x : t1 ] ⊢ e : t2 & b
(abs)
C, A ⊢ fn x ⇒ e : (t1 →b t2 ) & ∅

C1 , A ⊢ e1 : (t2 →b t1 ) & b1 C2 , A ⊢ e2 : t2 & b2


(app)
(C1 ∪ C2 ), A ⊢ e1 e2 : t1 & (b1 ∪ b2 ∪ b)

C1 , A ⊢ e1 : ts1 & b1 C2 , A[x : ts1 ] ⊢ e2 : t2 & b2


(let)
(C1 ∪ C2 ), A ⊢ let x = e1 in e2 : t2 & (b1 ∪ b2 )

C, A[f : t] ⊢ fn x ⇒ e : t & b
(rec)
C, A ⊢ rec f x ⇒ e : t & b

C0 , A ⊢ e0 : bool & b0 C1 , A ⊢ e1 : t & b1 C2 , A ⊢ e2 : t & b2


(if)
(C0 ∪ C1 ∪ C2 ), A ⊢ if e0 then e1 else e2 : t & (b0 ∪ b1 ∪ b2 )

C, A ⊢ e : t & b
(sub) if C ⊢ t ⊆ t′ and C ⊢ b ⊆ b′
C, A ⊢ e : t′ & b′

αβ~ : C0 ). t0 & b
C, A ⊢ e : ∀(~
(ins) αβ~ : C0 ). t0 is solvable from C by S0
if ∀(~
C, A ⊢ e : S0 t0 & b

C ∪ C0 , A ⊢ e : t0 & b
(gen) if ∀(~αβ~ : C0 ). t0 is both well-formed,
αβ~ : C0 ). t0 & b
C, A ⊢ e : ∀(~ ~ ∩
solvable from C, and satisfies {~ αβ}
FV(C, A, b) = ∅

Fig. 2. The type inference system.

2.2 Subtyping
Rule (sub) generalises the subeffecting rule of [19] by incorporating subtyping
and extends the subtyping rule of [18] to deal with effects. To do this we associate
two kinds of judgements with a constraint set: the relations C ⊢ b1 ⊆ b2 and
C ⊢ t1 ⊆ t2 are defined by the rules and axioms of Figure 3. In all cases we write
≡ for the equivalence induced by the orderings. We shall also write C ⊢ C ′ to
mean that C ⊢ b1 ⊆ b2 for all (b1 ⊆ b2 ) in C ′ and that C ⊢ t1 ⊆ t2 for all (t1 ⊆ t2 )
in C ′ .
The relation C ⊢ t1 ⊆ t2 expresses the usual notion of subtyping, in partic-
ular it is contravariant in the argument position of a function type but there
Ordering on behaviours

(axiom) C ⊢ b1 ⊆ b2 if (b1 ⊆ b2 ) ∈ C

(refl) C ⊢b⊆b

C ⊢ b1 ⊆ b2 C ⊢ b2 ⊆ b3
(trans)
C ⊢ b1 ⊆ b3

C ⊢ t ≡ t′
(chan)
C ⊢ {t chan} ⊆ {t′ chan}

(∅) C ⊢∅⊆b

(∪) C ⊢ bi ⊆ (b1 ∪ b2 ) for i = 1, 2

C ⊢ b1 ⊆ b C ⊢ b2 ⊆ b
(lub)
C ⊢ (b1 ∪ b2 ) ⊆ b

Ordering on types

(axiom) C ⊢ t1 ⊆ t2 if (t1 ⊆ t2 ) ∈ C

(refl) C ⊢t⊆t

C ⊢ t1 ⊆ t2 C ⊢ t2 ⊆ t3
(trans)
C ⊢ t1 ⊆ t3

C ⊢ t′1 ⊆ t1 C ⊢ t2 ⊆ t′2 C ⊢ b ⊆ b′
(→) ′
C ⊢ (t1 →b t2 ) ⊆ (t′1 →b t′2 )
C ⊢ t1 ⊆ t′1 C ⊢ t2 ⊆ t′2
(×)
C ⊢ (t1 × t2 ) ⊆ (t′1 × t′2 )

C ⊢ t ⊆ t′
(list)
C ⊢ (t list) ⊆ (t′ list)

C ⊢ t ≡ t′
(chan)
C ⊢ (t chan) ⊆ (t′ chan)

C ⊢ t ⊆ t′ C ⊢ b ⊆ b′
(com)
C ⊢ (t com b) ⊆ (t′ com b′ )

Fig. 3. Subtyping and subeffecting.


is no inclusion between base types. In the case of chan note that the type t
of t chan essentially occurs covariantly (when used in receive) as well as con-
travariantly (when used in send); hence we must require that C ⊢ t ≡ t′ in order
for C ⊢ t chan ⊆ t′ chan to hold.
The definition of C ⊢ b1 ⊆ b2 is a fairly straightforward axiomatisation of set
inclusion upon behaviours; note that the premise for C ⊢ {t1 chan} ⊆ {t2 chan}
is that C ⊢ t1 ≡ t2 .

2.3 Generalisation

We now explain some of the side conditions for the rules (ins) and (gen). This
involves the notion of substitution: a mapping from type variables to types and
from behaviour variables to behaviours4 such that the domain is finite. Here the
domain
S of a substitution S is Dom(S) = {γ | S γ 6= γ} and the range is Ran(S) =
{FV(S γ) | γ ∈ Dom(S)} where the concept of free variables, denoted FV(· · ·),
is standard. The identity substitution is denoted Id and we sometimes write
Inv(S) = Dom(S) ∪ Ran(S) for the set of variables that are involved in the
substitution S.
Rule (ins) is much as in [18] and merely says that to take an instance of a
type scheme we must ensure that the constraints are satisfied; this is expressed
using the notion of solvability:

Definition 1. The type scheme ∀(~ αβ~ : C0 ). t0 is solvable from C by the substi-
tution S0 if Dom(S0 ) ⊆ {~ ~
αβ} and if C ⊢ S0 C0 .
A type t is trivially solvable from C, and an environment A is solvable from
C if for all x in Dom(A) it holds that A(x) is solvable from C.
Except for the well-formedness requirement (explained later), rule (gen) seems
close to the corresponding rule in [18]: clearly we cannot generalise over vari-
ables free in the global type assumptions or global constraint set, and as in effect
systems (e.g. [19]) we cannot generalise over variables visible in the effect. Fur-
thermore, as in [18] solvability is imposed to ensure that we do not create type
schemes that have no instances; this condition ensures that the expressions let
x = e1 in e2 and let x = e1 in (x;e2 ) are going to be equivalent in the type
system.

Example 2. Without an additional notion of well-formedness this does not give


a semantically sound rule (gen); as an example consider the expression e given
by

let ch = channel ()
in · · ·
(sync(send(ch,7)))
(sync(send(ch,true)))
4
We use γ to range over α’s and β’s as appropriate and use g range over t’s and b’s
as appropriate.
and note that it is semantically unsound (at least if “· · ·” forked some process
receiving twice over ch and adding the results). Writing C = {{α chan} ⊆ β,
{{int chan}} ⊆ β, {{bool chan}} ⊆ β} and C ′ = {{α′ chan} ⊆ β} then gives
C ∪ C ′ , [ ] ⊢ channel () : α′ chan & β
and, without taking well-formedness into account, rule (gen) would give
C, [ ] ⊢ channel () : (∀(α′ : C ′ ). α′ chan) & β
because α′ ∈/ FV(C, β) and ∀(α′ : C ′ ). α′ chan is solvable from C by either of
the substitutions [α′ 7→ α], [α′ 7→ int] and [α′ 7→ bool]. This then would give
C, [ch : ∀(α′ : C ′ ). α′ chan] ⊢ ch : int chan & ∅
C, [ch : ∀(α′ : C ′ ). α′ chan] ⊢ ch : bool chan & ∅
so that
C, [ ] ⊢ e : t & b
for suitable t and b. As it is easy to find S such that ∅ ⊢ S C, we shall see (by
Lemma 10 and Lemma 11) that we even have
∅, [ ] ⊢ e : t′ & b′
for suitable t′ and b′ . This shows that some notion of well-formedness is essential
for semantic soundness; actually the example suggests that if there is a constraint
({α′ chan} ⊆ β) then one should not generalise over α′ if it is impossible to
generalise over β. 2

The arrow relation


In order to formalise the notion of well-formedness we next associate a third
kind of judgement and three kinds of closure with a constraint set. Motivated
by the concluding remark of Example 2 we establish a relation between the left
hand side variables and the right hand side variables of a constraint:
Definition 2. The judgement C ⊢ γ1 ← γ2 holds if there exists (g1 ⊆ g2 ) in C
such that γi ∈ FV(gi ) for i = 1, 2.
From this relation we define a number of other relations: → is the inverse of ←,
i.e. C ⊢ γ1 → γ2 holds iff C ⊢ γ2 ← γ1 holds, and ↔ is the union of ← and →,
i.e. C ⊢ γ1 ↔ γ2 holds iff either C ⊢ γ1 ← γ2 or C ⊢ γ1 → γ2 holds. As usual ←∗
(respectively →∗ , ↔∗) denotes the reflexive and transitive closure of the relation.
For a set X of variables we then define the downwards closure X C↓ , the
upwards closure X C↑ and the bidirectional closure X Cl by:
X C↓ = {γ1 | ∃γ2 ∈ X : C ⊢ γ1 ←∗ γ2 }
X C↑ = {γ1 | ∃γ2 ∈ X : C ⊢ γ1 →∗ γ2 }
X Cl = {γ1 | ∃γ2 ∈ X : C ⊢ γ1 ↔∗ γ2 }
It is instructive to think of C ⊢ γ1 ← γ2 as defining a directed graph structure
upon FV(C); then X C↓ is the reachability closure of X, X C↑ is the reachability
closure in the graph where all edges are reversed, and X Cl is the reachability
closure in the corresponding undirected graph.

Well-formedness

We can now define the notion of well-formedness for constraints and for type
schemes; for the latter we make use of the arrow relations defined above.

Definition 3. Well-formed constraint sets


A constraint set C is well-formed if all right hand sides of (g1 ⊆ g2 ) in C have g2
to be a variable; in other words all inclusions of C have the form t ⊆ α or b ⊆ β.

The well-formedness assumption on constraint sets is motivated by the desire


to be able to use the subtyping rules “backwards” (as spelled out in Lemma 4
below) and in ensuring that subtyping interacts well with the arrow relation (see
Lemma 5 below).

Lemma 4. Suppose C is well-formed and that C ⊢ t ⊆ t′ .



– If t′ = t′1 →b t′2 there exist t1 , t2 and b such that t = t1 →b t2 and such
that C ⊢ t′1 ⊆ t1 , C ⊢ t2 ⊆ t′2 and C ⊢ b ⊆ b′ .
– If t′ = t′1 com b′ there exist t1 and b such that t = t1 com b and such that
C ⊢ t1 ⊆ t′1 and C ⊢ b ⊆ b′ .
– If t′ = t′1 × t′2 there exist t1 and t2 such that t = t1 × t2 and such that
C ⊢ t1 ⊆ t′1 and C ⊢ t2 ⊆ t′2 .
– If t′ = t′1 chan there exists t1 such that t = t1 chan and such that C ⊢ t1 ≡ t′1 .
– If t′ = t′1 list there exists t1 such that t = t1 list and such that C ⊢ t1 ⊆ t′1 .
– If t′ = int (respectively bool, unit) then t = int (respectively bool, unit).

Proof. See Appendix A.

Lemma 5. Suppose C is well-formed:


C↓ C↓
if C ⊢ b ⊆ b′ then FV(b) ⊆ FV(b′ ) .

Proof. See Appendix A.

We now turn to well-formedness of type schemes where we ensure that the


embedded constraints are themselves well-formed. Additionally we shall wish
to ensure that the set of variables over which we generalise, is sensibly related
to the constraints (unlike the situation in Example 2). The key idea is that if
C ⊢ γ1 ← γ2 then we do not generalise over γ1 unless we also generalise over γ2 .
These considerations lead to:
Definition 6. Well-formed type schemes
A type scheme ∀(~ αβ~ : C0 ). t0 is well-formed if C0 is well-formed, if all (g ⊆ γ) in
C0 contain at least one variable among {~ ~ and if {~
αβ}, ~ = {~
αβ} ~ C0 ↑ .
αβ}
A type t is trivially well-formed.

αβ~ : C). t is well-formed. It is essential for our


Notice that if C = ∅ then ∀(~
development that the following property holds:

Fact 7. Well-formedness and Substitutions


αβ~ : C). t is well-formed then also S (∀(~
If ∀(~ αβ~ : C). t) is well-formed (for all
substitutions S).

Proof. We can, without loss of generality, assume that (Dom(S) ∪ Ran(S)) ∩


{~ ~ = ∅. Then S (∀(~
αβ} αβ~ : C). t) = ∀(~αβ~ : S C). S t. Consider (g1′ ⊆ g2′ ) in S C;
it is easy to see that it suffices to show that g2′ is a variable in {~ ~
αβ}.
Let g1′ = S g1 and g2′ = S g2 where (g1 ⊆ g2 ) ∈ C. Since C is well-formed it
holds that g2 is a variable, and since FV(g1 , g2 ) ∩ {~ ~ =
αβ} 6 ∅ and since {~ ~ =
αβ}
C↑
{~ ~
αβ} it holds that g2 ∈ {~ ~ Therefore g′ = S g2 = g2 so g′ is a variable in
αβ}. 2 2
{~ ~
αβ}.
C′↑
Example 3. Continuing Example 2 note that {α′ } = {α′ , β} showing that our
current notion of well-formedness prevents the erroneous typing. 2

Example 4. Continuing Example 1 we shall now briefly explain why it is accepted


by our system. For this let us assume that y will have type αy and that x will
have type αx. Then the locally defined function
fn x => (sync (send (channel (), y)); x)
will have type αx →b αx for b = {αy chan}. Due to our rule for subtyping we
may let f have the type αx →∅ αx and still be able to type the conditional.
Clearly the expression defining id may be given the type αy →∅ αy and the
effect ∅. Since αy is not free in the type of f we may use generalisation to
give id the type scheme ∀(αy : ∅). αy →∅ αy . This then suffices for typing the
application of id to itself.
Now consider a system with subeffecting only (as in [23]): then for the type
of f to match that of the locally defined function we have to give f the type
αx →b αx where b = {αy chan}. This then means that while the defining ex-
pression for id still has the type αy →∅ αy we are unable to generalise it to
∀(αy : ∅). αy →∅ αy because αy is now free in the type of f. Consequently the
application of id to itself cannot be typed. (It is interesting to point out that if
one changed the applied occurrence of f in the program to the expression fn z
=> f z then subeffecting would suffice for generalising over αy and hence would
allow to type the self-application of id.)
The system of [19] does not have subtyping but nevertheless the application
of id to itself is typeable [19, section 11, the case (id4 id4)]. This is due to the
presence of regions and masking (cf. the discussion in the Introduction): with
ρ the region in which the new channel is allocated, the expression sync (send
(channel (), y)) does not contain ρ in its type αy and neither is ρ present in
the environment, so it is possible to discard the effect {αy chan}ρ (recording
that a channel carrying values of type αy has been allocated in region ρ). Thus
the two branches of the conditional can both be given type αx →∅ αx.
Also in the approach of [21] one can generalise over αy and hence type the
self-application of id. To see this, first note that αy is classified as an imperative
type variable (rather than an applicative type variable which would directly have
allowed the generalisation) because αy is used in the channel construct and thus
has a side effect. Despite of this, next note that the defining expression for the id
function is classified as non-expansive (rather as expansive which would directly
have prohibited the generalisation of imperative type variables) because all side
effects occurring in the definition of id are “protected” by a function abstraction
and hence not “dangerous”. We refer to [21] for the details. 2

2.4 Properties of the Inference System

We now list a few basic properties of the inference system that we shall use later.

Fact 8. For all constants c of Figure 1, the type scheme TypeOf(c) is closed,
well-formed and solvable from ∅.

Fact 9. If C, A ⊢ e : σ & b and A is well-formed and solvable from C then σ is


well-formed and solvable from C.

Proof. A straightforward case analysis on the last rule applied; for constants we
make use of Fact 8.

Lemma 10. Substitution Lemma


For all substitutions S:

(a) If C ⊢ C ′ then S C ⊢ S C ′ .
(b) If C, A ⊢ e : σ & b then S C, S A ⊢ e : S σ & S b (and has the same shape).

Proof. See Appendix A.

Lemma 11. Entailment Lemma


For all sets C ′ of constraints satisfying C ′ ⊢ C:

(a) If C ⊢ C0 then C ′ ⊢ C0 ;
(b) If C, A ⊢ e : σ & b then C ′ , A ⊢ e : σ & b (and has the same shape).

Proof. See Appendix A.


2.5 Proof Normalisation
It turns out that the proof of semantic soundness [2] is complicated by the pres-
ence of the non-syntax directed rules (sub), (gen) and (ins) of Figure 2. This
motivates trying to normalise general inference trees into a more manageable
shape5 ; to this end we define the notions of “normalised” and “strongly nor-
malised” inference trees. But first we define an auxiliary concept:

Definition 12. An inference for C, A ⊢ e : σ & b is constraint-saturated, written


C, A ⊢c e : σ & b, if and only if all occurrences of the rules (app), (let), and (if)
have the same constraints in their premises; in the notation of Figure 2 this
means that C1 = C2 for (app) and (let) and that C0 = C1 = C2 for (if).

Fact 13. Given an inference tree for C, A ⊢ e : σ & b there exists a constraint-
saturated inference tree C, A ⊢c e : σ & b (that has the same shape).

Proof. A straightforward induction in the shape of the inference tree using


Lemma 11 in the cases (app), (let) and (if).

We now define the central concepts of T- and TS-normalised inference trees.

Definition 14. Normalisation


An inference tree for C, A ⊢ e : t & b is T-normalised if it is created by:
– (con) or (id); or
– (ins) applied to (con) or (id); or
– (abs), (app), (rec), (if) or (sub) applied to T-normalised inference trees; or
– (let) applied to a TS-normalised inference tree and a T-normalised inference
tree.
An inference tree for C, A ⊢ e : ts & b is TS-normalised if it is created by:
– (gen) applied to a T-normalised inference tree.
We shall write C, A ⊢n e : σ & b if the inference tree is T-normalised (if σ is a
type) or TS-normalised (if σ is a type scheme).

Notice that if jdg = C, A ⊢ e : σ & b occurs in a normalised inference tree then we


in fact have jdg = C, A ⊢n e : σ & b, unless jdg is created by (con) or (id) and
σ is a type scheme. Next consider the result of applying (ins) to a normalised
inference tree; even though the resulting inference tree is not normalised the
resulting judgement in fact has a normalised inference:

Lemma 15. Suppose that


jdg = C, A ⊢ e : S t0 & b
follows by an application of (ins) to the normalised judgement
5
This will also facilitate proving the completeness of an inference algorithm.
jdg′ = C, A ⊢n e : ∀(~
αβ~ : C0 ). t0 & b

where Dom(S) ⊆ {~ ~ and C ⊢ S C0 . Then also jdg has a normalised inference:


αβ}

C, A ⊢n e : S t0 & b.

Proof. The normalised judgement jdg′ follows by an application of (gen) to the


normalised judgement
C ∪ C0 , A ⊢n e : t0 & b

where {~ ~ ∩ FV(C, A, b) = ∅. From Lemma 10 we therefore get


αβ}
C ∪ S C0 , A ⊢n e : S t0 & b

and using Lemma 11 we get C, A ⊢n e : S t0 & b as desired.

It is not a severe restriction to work with normalised inferences only:


Lemma 16. Normalisation Lemma
If A is well-formed and solvable from C then an inference tree C, A ⊢ e : σ & b
can be transformed into one C, A ⊢n e : σ & b that is normalised.

Proof. See Appendix A.

A somewhat stronger property is the following:

Definition 17. An inference tree for C, A ⊢ e : σ & b is strongly normalised if it


is normalised as well as constraint-saturated. We write C, A ⊢s e : σ & b when
this is the case.
By Fact 13 we have:

Fact 18. A normalised inference tree C, A ⊢n e : σ & b can be transformed into


one that is strongly normalised.

2.6 Conservative Extension


We finally show that our inference system is a conservative extension of the
system for ML type inference. For this purpose we restrict ourselves to con-
sider sequential expressions only, that is expressions without the non-sequential
constants channel, fork, sync, send, and receive.
An ML type u (as opposed to a CML type t, in the following just denoted
type) is either a type variable α, a base type like int, a function type u1 → u2 ,
a product type u1 × u2 , or a list type u1 list. An ML type scheme is of the
form ∀~α .u.
From a type t we can in a natural way construct an ML type ǫ(t): ǫ(α) = α,
ǫ(int) = int, ǫ(t1 →b t2 ) = ǫ(t1 ) → ǫ(t2 ), ǫ(t1 × t2 ) = ǫ(t1 ) × ǫ(t2 ),
ǫ(t1 list) = ǫ(t1 ) list, and ǫ(t com b) = ǫ(t chan) = ǫ(t).
From an ML type u we can construct a type ι(u) by annotating all arrows
with ∅ : ι(α) = α, ι(int) = int, ι(u1 → u2 ) = ι(u1 ) →∅ ι(u2 ), ι(u1 × u2 ) =
ι(u1 ) × ι(u2 ), ι(u1 list) = ι(u1 ) list.
We say that a type scheme ts = ∀(~ αβ~ : C). t is sequential if C is empty.
From a sequential type scheme ts = ∀(~ ~ : ∅). t we construct an ML type
αβ
scheme ǫ(ts) as follows: ǫ(ts) = ∀~ α .ǫ(t). (We shall dispense with defining ǫ(ts)
on non-sequential type schemes for reasons to be discussed in Appendix A.)
From an ML type scheme us = ∀~ α .u we construct a (sequential) type scheme
ι(us) as follows: ι(us) = ∀(~α : ∅). ι(u).
Fact 19. Let u be an ML type, then ǫ(ι(u)) = u. Similarly for ML type schemes.
The core of the ML type inference system is depicted in Figure 4. It em-
ploys a function MLTypeOf which to each sequential constant assigns either
an ML type or an ML type scheme; as an example we have MLTypeOf(pair)
= ∀α1 α2 .α1 → α2 → α1 × α2 .
Assumption 20. For all sequential constants c: ι(MLTypeOf(c)) = TypeOf(c)
(so by Fact 19: MLTypeOf(c) = ǫ(TypeOf(c))).

(con) A ⊢ML c : MLTypeOf(c)

(id) A ⊢ML x : A(x)

A[x : u1 ] ⊢ML e : u2
(abs)
A ⊢ML fn x ⇒ e : u1 → u2

(app) A ⊢ML e1 : u2 → u1 , A ⊢ML e2 : u2


A ⊢ML e1 e2 : u1

A ⊢ML e1 : us1 , A[x : us1 ] ⊢ML e2 : u2


(let)
A ⊢ML let x = e1 in e2 : u2

(ins) A ⊢ML e : ∀~
α .u if Dom(R) ⊆ {~
α}
A ⊢ML e : R u

(gen) A ⊢ML e : u if FV(A) ∩ {~


α} = ∅
A ⊢ML e : ∀~
α .u

Fig. 4. The core of the ML type inference system.

We are now ready to state that our system conservatively extends ML.
Theorem 21. Let e be a sequential expression:
– if [ ] ⊢ML e : u then ∅, [ ] ⊢ e : ι(u) & ∅;
– if C, [ ] ⊢ e : t & b where C contains no type constraints then [ ] ⊢ML e : ǫ(t).
Proof: See Appendix A.
3 Conclusion

We have extended previous work on integrating polymorphism, subtyping and


effects into a combined annotated type and effect system. The development was
illustrated for a fragment of Concurrent ML but is equally applicable to Stan-
dard ML with references. A main ingredient of the approach was the notion of
constraint closure, in particular the notion of upwards closure. We hope that this
system will provide a useful basis for developing a variety of program analyses;
in particular closure, binding-time and communication analyses for languages
with imperative or concurrent effects.
The system developed here includes no causality concerning the temporal
order of effects; in the future we hope to incorporate aspects of the causality
information for the communication structure of Concurrent ML [15]. Another
(and harder) goal is to incorporate decidable fragments of polymorphic recursion.
Finally, it should prove interesting to apply these ideas also to strongly typed
languages with object-oriented features.

Acknowledgement. This work has been supported in part by the DART


project (Danish Natural Science Research Council) and the LOMAPS project
(ESPRIT BRA project 8130); it represents joint work among the authors.

References

1. T. Amtoft, F. Nielson, H.R. Nielson: Type and behaviour reconstruction for


higher-order concurrent programs. To appear in Journal of Functional Program-
ming, 1997.
2. T. Amtoft, F. Nielson, H.R. Nielson, J. Ammann: Polymorphic subtypes for effect
analysis: the dynamic semantics. This volume of SLNCS, 1997.
3. L. Damas and R. Milner: Principal type-schemes for functional programs. In Proc.
of POPL ’82. ACM Press, 1982.
4. Y.-C. Fuh and P. Mishra: Polymorphic subtype inference: closing the theory-
practice gap. In Proc. TAPSOFT ’89. SLNCS 352, 1989.
5. Y.-C. Fuh and P. Mishra: Type inference with subtypes. Theoretical Computer
Science, 73, 1990.
6. F. Henglein: Type inference with polymorphic recursion. ACM Transactions on
Programming Languages and Systems, 15(2):253-289, 1993.
7. F. Henglein and C. Mossin: Polymorphic binding-time analysis. In Proc. ESOP
’94, pages 287–301. SLNCS 788, 1994.
8. M.P. Jones: A theory of qualified types. In Proc. ESOP ’92, pages 287–306.
SLNCS 582, 1992.
9. X. Leroy and P. Weis: Polymorphic type inference and assignment. In Proc. POPL
’91, pages 291–302. ACM Press, 1991.
10. R. Milner: A theory of type polymorphism in programming. Journal of Computer
Systems, 17:348–375, 1978.
11. J.C. Mitchell: Type inference with simple subtypes. Journal of Functional Pro-
gramming, 1(3), 1991.
12. F. Nielson and H.R. Nielson: Constraints for polymorphic behaviours for Concur-
rent ML. In Proc. CCL’94. SLNCS 845, 1994.
13. F. Nielson, H.R. Nielson, T. Amtoft: Polymorphic subtypes for effect analysis: the
algorithm. This volume of SLNCS, 1997.
14. H.R. Nielson and F. Nielson: Automatic binding analysis for a typed λ-calculus.
Science of Computer Programming, 10:139–176, 1988.
15. H.R. Nielson and F. Nielson: Higher-order concurrent programs with finite com-
munication topology. In Proc. POPL’94, pages 84–97. ACM Press, 1994.
16. P. Panangaden and J.H. Reppy: The essence of Concurrent ML. In ML with Con-
currency: Design, Analysis, Implementation and Application (editor: Flemming
Nielson), Springer-Verlag, 1996.
17. J.H. Reppy: Concurrent ML: Design, application and semantics. In Proc. Func-
tional Programming, Concurrency, Simulation and Automated Reasoning, pages
165–198. SLNCS 693, 1993.
18. G.S. Smith: Polymorphic inference with overloading and subtyping. In SLNCS
668, Proc. TAPSOFT ’93, 1993. Also see: Principal Type Schemes for Functional
Programs with Overloading and Subtyping: Science of Computer Programming 23,
pp. 197-226, 1994.
19. J.P. Talpin and P. Jouvelot: The type and effect discipline. Information and Com-
putation, 111, 1994.
20. Y.-M. Tang: Control flow analysis by effect systems and abstract interpretation.
PhD thesis, Ecoles des Mines de Paris, 1994.
21. M. Tofte. Type inference for polymorphic references. Information and Computa-
tion, 89:1–34, 1990.
22. M. Tofte and L. Birkedal: Region-annotated types and type schemes, 1996. Sub-
mitted for publication.
23. A.K. Wright: Typing references by effect inference. In Proc. ESOP ’92, pages
473–491. SLNCS 582, 1992.

A Proofs of Main Results


Well-formedness
Lemma 4 Suppose C is well-formed and that C ⊢ t ⊆ t′ .

– If t′ = t′1 →b t′2 there exist t1 , t2 and b such that t = t1 →b t2 and such
that C ⊢ t′1 ⊆ t1 , C ⊢ t2 ⊆ t′2 and C ⊢ b ⊆ b′ .
– If t′ = t′1 com b′ there exist t1 and b such that t = t1 com b and such that
C ⊢ t1 ⊆ t′1 and C ⊢ b ⊆ b′ .
– If t′ = t′1 × t′2 there exist t1 and t2 such that t = t1 × t2 and such that
C ⊢ t1 ⊆ t′1 and C ⊢ t2 ⊆ t′2 .
– If t′ = t′1 chan there exists t1 such that t = t1 chan and such that C ⊢ t1 ≡ t′1 .
– If t′ = t′1 list there exists t1 such that t = t1 list and such that C ⊢ t1 ⊆ t′1 .
– If t′ = int (respectively bool, unit) then t = int (respectively bool, unit).
In addition we are going to prove that the size of each of the latter inference
trees is strictly less than the size of the inference tree for C ⊢ t ⊆ t′ . Here the
size of an inference tree is defined as the number of (not necessarily different)
symbols occurring in the tree, except that occurrences in C do not count.

Proof. We only consider the case t′ = t′1 →b t′2 , as the others are similar. The
proof is carried out by induction in the inference tree, and since C is well-formed
the last rule applied must be either (refl), (trans) or (→).
(refl): the claim is trivial6.
(trans): assume that C ⊢ t ⊆ t′ by means of a tree of size n because C ⊢ t ⊆ t′′
by means of a tree of size n′′ and because C ⊢ t′′ ⊆ t′ by means of a tree of size
n′ . Here n = n′ + n′′ + |t| + |t′ | + 2. By applying the induction hypothesis on
′′
the latter inference we find t′′1 , t′′2 and b′′ such that t′′ = t′′1 →b t′′2 and such
that C ⊢ t′1 ⊆ t′′1 and C ⊢ t′′2 ⊆ t′2 and C ⊢ b′′ ⊆ b′ , each judgement by means of an
inference tree of size < n′ . By applying the induction hypothesis on the former
inference (C ⊢ t ⊆ t′′ ) we find t1 , t2 and b such that t = t1 →b t2 and such
that C ⊢ t′′1 ⊆ t1 and C ⊢ t2 ⊆ t′′2 and C ⊢ b ⊆ b′′ , each judgement by means of an
inference tree of size < n′′ . We thus have C ⊢ t′1 ⊆ t1 , by means of an inference
tree of size < n′ + n′′ + |t′1 | + |t1 | + 2 < n′ + n′′ + |t′ | + |t| + 2 = n. By similar
reasoning we infer that C ⊢ t2 ⊆ t′2 and C ⊢ b ⊆ b′ , each judgement by means of
an inference tree of size < n.
(→): the claim is trivial. 2

For variables we need a different kind of lemma:


C↓
Lemma 22. Suppose C ⊢ α ⊆ α′ with C well-formed. Then α ∈ {α′ } .

Proof. Induction in the proof tree, performing case analysis on the last rule
applied:
(axiom): then (α ⊆ α′ ) ∈ C so the claim is trivial.
(refl): the claim is trivial.
(trans): assume that C ⊢ α ⊆ α′ because C ⊢ α ⊆ t′′ and C ⊢ t′′ ⊆ α′ . By using
Lemma 4 on the inference C ⊢ α ⊆ t′′ we infer that t′′ is a variable α′′ . By applying
C↓ C↓
the induction hypothesis we infer that α ∈ {α′′} and that α′′ ∈ {α′ } , from
C↓
which we conclude that α ∈ {α′ } . 2

Lemma 5 Suppose C is well-formed:


C↓ C↓
if C ⊢ b ⊆ b′ then FV(b) ⊆ FV(b′ ) , and
C↓
if C ⊢ t ≡ t′ then FV(t)C↓ = FV(t′ ) .

Proof. Induction in the size of the inference tree, where we define the size of
the inference tree for C ⊢ t ≡ t′ as the sum of the size of the inference tree for
C ⊢ t ⊆ t′ and the size of the inference tree for C ⊢ t′ ⊆ t.
First we consider the part concerning behaviours, performing case analysis
on the last inference rule applied:
(axiom): then (b ⊆ b′ ) ∈ C so since C is well-formed b′ is a variable; hence
the claim.
(refl): the claim is trivial.
6
This case is the reason for not defining the size of a tree as the number of inferences.
(trans): assume that C ⊢ b ⊆ b′ because C ⊢ b ⊆ b′′ and C ⊢ b′′ ⊆ b′ . The in-
C↓ C↓ C↓
duction hypothesis tells us that FV(b) ⊆ FV(b′′ ) and that FV(b′′ ) ⊆
′ C↓
FV(b ) ; hence the claim.
(chan): assume that C ⊢ {t chan} ⊆ {t′ chan} because C ⊢ t ≡ t′ . The in-
C↓ C↓
duction hypothesis tells us that FV(t) = FV(t′ ) ; hence the claim.
(∅): the claim is trivial.
(∪): the claim is trivial.
(lub): assume that C ⊢ b1 ∪ b2 ⊆ b′ because C ⊢ b1 ⊆ b′ and C ⊢ b2 ⊆ b′ . The
C↓ C↓ C↓
induction hypothesis tells us that FV(b1 ) ⊆ FV(b′ ) and that FV(b2 ) ⊆
C↓ C↓ C↓ C↓
FV(b′ ) , from which we infer that FV(b1 ∪ b2 ) = FV(b1 ) ∪ FV(b2 ) ⊆
′ C↓
FV(b ) .
Next we consider the part concerning types, where we perform case analysis
on the form of t′ :

t′ = t′1 →b t′2 : Let n1 be the size of the inference tree for C ⊢ t ⊆ t′ and let
n2 be the size of the inference tree for C ⊢ t′ ⊆ t. Lemma 4 (applied to the former
inference) tells us that there exist t1 , b and t2 such that t = t1 →b t2 and such
that C ⊢ t′1 ⊆ t1 , C ⊢ b ⊆ b′ and C ⊢ t2 ⊆ t′2 , where each inference tree is of size
< n1 (due to the remark prior to the proof). Lemma 4 (applied to the latter
inference, i.e. C ⊢ t′ ⊆ t) tells us that C ⊢ t1 ⊆ t′1 , C ⊢ b′ ⊆ b and C ⊢ t′2 ⊆ t2 , where
each inference tree is of size < n2 .
Thus C ⊢ t1 ≡ t′1 and C ⊢ t2 ≡ t′2 , where each inference tree has size < n1 +n2 .
C↓ C↓
We can thus apply the induction hypothesis to infer that FV(t1 ) = FV(t′1 )
C↓ C↓ C↓
and that FV(t2 ) = FV(t′2 ) ; and similarly we can infer that FV(b) ⊆
′ C↓ ′ C↓ C↓
FV(b ) and that FV(b ) ⊆ FV(b) . This enables us to concluce that
C↓ C↓
FV(t) = FV(t′ ) .
t′ has a topmost type constructor other than →: we can proceed as above.
t′ is a variable: Since C ⊢ t′ ⊆ t we can use Lemma 4 to infer that t is a vari-
C↓
able; then we use Lemma 22 to infer that FV(t′ ) ⊆ FV(t) . Similarly we can
C↓ C↓ C↓
infer FV(t) ⊆ FV(t′ ) . This implies the desired relation FV(t) = FV(t′ ) .
2

Properties of the inference system


Lemma 10 For all substitutions S:
(a) If C ⊢ C ′ then S C ⊢ S C ′ .
(b) If C, A ⊢ e : σ & b then S C, S A ⊢ e : S σ & S b (and has the same shape).
Proof. The claim (a) is straight-forward by induction on the inference C ⊢ g1 ⊆ g2
for each (g1 ⊆ g2 ) ∈ C ′ . For the claim (b) we proceed by induction on the infer-
ence.
For the case (con) we use that the type schemes of Fig. 1 are closed (Fact 8).
For the case (id) the claim is immediate, and for the cases (abs), (app), (let),
(rec), (if) it follows directly using the induction hypothesis. For the case (sub)
we use (a) together with the induction hypothesis.
αβ~ : C0 ). t0 & b
The case (ins). Then C, A ⊢ e : S0 t0 & b because C, A ⊢ e : ∀(~
where C ⊢ S0 C0 and Dom(S0 ) ⊆ {~ ~
αβ}, and wlog. we can assume that {~ αβ}~ is
disjoint from Inv(S). The induction hypothesis gives

S C, S A ⊢ e : ∀(~
αβ~ : S C0 ). S t0 & S b. (1)

From (a) we get S C ⊢ S S0 C0 . Let S0′ = [~ αβ~ 7→ S S0 (~ ~ then on FV(t0 , C0 )


αβ)],
′ ′
it holds that S0 S = S S0 . Therefore S C ⊢ S0 S C0 , so we can apply (ins) on (1)
with S0′ as the “instance substitution” to get S C, S A ⊢ e : S0′ S t0 & S b. Since
S0′ S t0 = S S0 t0 this is the required result.
The case (gen). Then C, A ⊢ e : ∀(~ αβ~ : C0 ). t0 & b because
C ∪ C0 , A ⊢ e : t0 & b, and

αβ~ : C0 ). t0 is well-formed
∀(~ (2)
there exists S0 with Dom(S0 ) ⊆ {~ ~ such that C ⊢ S0 C0
αβ} (3)
{~ ~ ∩ FV(C, A, b) = ∅
αβ} (4)

Define R = [~ ~′ β~′ ] with {α~′ β~′ } fresh. We then apply the induction hypoth-
αβ~ 7→ α
esis (with S R) and due to (4) this gives us S C ∪ S R C0 , S A ⊢ e : S R t0 & S b.
Below we prove

∀(α~′ β~′ : S R C0 ). S R t0 (= S (∀(~


αβ~ : C0 ). t0 )) is well-formed, (5)
there exists S ′ with Dom(S ′ ) ⊆ {α~′ β~′ } such that S C ⊢ S ′ S R C0 , and (6)
{α~′ β~′ } ∩ FV(S C, S A, S b) = ∅ (7)

It then follows that S C, S A ⊢ e : S (∀(~ ~ : C0 ). t0 ) & S b as required. Clearly


αβ
the inference has the same shape.
First we observe that (5) follows from (2) and Fact 7. For (6) define S ′ =
~ ~
[α β ′ 7→ S S0 (~
′ ~ From C ⊢ S0 C0 and (a) we get S C ⊢ S S0 C0 . Since S ′ S R =
αβ)].
S S0 on FV(C0 ) the result follows. Finally (7) holds trivially by choice of α~′ β~′ .
2

Lemma 11 For all sets C ′ of constraints satisfying C ′ ⊢ C:

(a) If C ⊢ C0 then C ′ ⊢ C0 .
(b) If C, A ⊢ e : σ & b then C ′ , A ⊢ e : σ & b (and has the same shape).

Proof. The claim (a) is straight-forward by induction on the inference C ⊢ g1 ⊆ g2


for each (g1 ⊆ g2 ) ∈ C0 . For the claim (b) we proceed by induction on the infer-
ence.
For the cases (con), (id) the claim is immediate, and for the cases (abs),
(app), (let), (rec), (if) it follows directly using the induction hypothesis. For the
cases (sub) and (ins) we use (a) together with the induction hypothesis.
The case (gen). Then C, A ⊢ e : ∀(~ αβ~ : C0 ). t0 & b because
C ∪ C0 , A ⊢ e : t0 & b and
αβ~ : C0 ). t0 is well-formed
∀(~ (8)
there exists S with Dom(S) ⊆ {~ ~ such that C ⊢ S C0
αβ} (9)
{~ ~ ∩ FV(C, A, b) = ∅
αβ} (10)
We now use a small trick: let R be a renaming of the variables of {~ ~ ∩ FV(C ′)
αβ}
′ ′
to fresh variables. From C ⊢ C and Lemma 10(a) we get R C ⊢ R C and using
(10) we get R C = C so R C ′ ⊢ C. Clearly R C ′ ∪ C0 ⊢ C ∪ C0 so the induction
hypothesis gives R C ′ ∪ C0 , A ⊢ e : t0 & b. Below we verify that
there exists S ′ with Dom(S ′ ) ⊆ {~ ~ such that R C ′ ⊢ S ′ C0
αβ} (11)
{~ ~ ∩ FV(R C , A, b) = ∅
αβ} ′
(12)
and we then have R C ′ , A ⊢ e : ∀(~αβ~ : C0 ). t0 & b. Now define the substitution
R′ such that Dom(R′) = Ran(R) and R′ γ ′ = γ if R γ = γ ′ and γ ′ ∈ Dom(R′ ).
Using Lemma 10(b) with the substitution R′ we get C ′ , A ⊢ e : ∀(~ αβ~ : C0 ). t0 & b
as required. Clearly the inference has the same shape.
To prove (11) define S ′ = S. Above we showed that R C ′ ⊢ C so using (9) and
(a) we get R C ′ ⊢ S ′ C0 as required. Finally (12) follows trivially from {~ ~ ∩
αβ}

FV(R C ) = ∅. 2

Proof normalisation
Lemma 16 If A is well-formed and solvable from C then an inference tree
C, A ⊢ e : σ & b can be transformed into one C, A ⊢n e : σ & b that is normalised.
Proof. Using Fact 13, we can, without loss of generality, assume that we have a
constraint-saturated inference tree for C, A ⊢ e : σ & b. We proceed by induction
on the inference.
The case (con). We assume C, A ⊢c c : TypeOf (c) & ∅. If TypeOf(c) is a
type then we already have a T-normalised inference. So assume TypeOf(c) is
a type scheme ∀(~ αβ~ : C0 ). t0 and let R be a renaming of α~ β~ to fresh variables
α ′ ~
~ β . We can then construct the following TS-normalised inference tree:

(con)
αβ~ : C0 ). t0 & ∅
C ∪ R C0 , A ⊢ c : ∀(~
(ins)
C ∪ R C0 , A ⊢ c : R t0 & ∅
(gen)
C, A ⊢ c : ∀(α~′ β~′ : R C0 ). R t0 & ∅
The rule (ins) is applicable since Dom(R) ⊆ {~ ~ and C ∪ R C0 ⊢ R C0 . The rule
αβ}
(gen) is applicable because ∀(~ αβ : C0 ). t0 = ∀(α~′ β~′ : R C0 ). R t0 (up to alpha-
~
renaming) is well-formed and solvable from C (Fact 8), and furthermore {α~′ β~′ }∩
FV(C, A, ∅) = ∅ holds by choice of α~′ β~′ .
The case (id). We assume C, A ⊢c x : A(x) & ∅. If A(x) is a type then we
already have a T-normalised inference. So assume A(x) = ∀(~ αβ~ : C0 ). t0 and
~ β~ to fresh variables α~′ β~′ . We can then construct the
let R be a renaming of α
following TS-normalised inference tree:

(id)
αβ~ : C0 ). t0 & ∅
C ∪ R C0 , A ⊢ x : ∀(~
(ins)
C ∪ R C0 , A ⊢ x : R t0 & ∅
(gen)
C, A ⊢ x : ∀(α~′ β~′ : R C0 ). R t0 & ∅

The rule (ins) is applicable since Dom(R) ⊆ {~ ~ and C ∪ R C0 ⊢ R C0 . The rule


αβ}
(gen) is applicable because ∀(~ ~ : C0 ). t0 = ∀(α~′ β~′ : R C0 ). R t0 (up to alpha-
αβ
renaming) by assumption is well-formed and solvable from C, and furthermore
{α~′ β~′ } ∩ FV(C, A, ∅) = ∅ holds by choice of α~′ β~′ .
The case (abs). Then we have C, A ⊢c fn x ⇒ e : t1 →b t2 & ∅ because
C, A[x : t1 ] ⊢c e : t2 & b. Since t1 is well-formed and solvable from C we can
apply the induction hypothesis and get C, A[x : t1 ] ⊢n e : t2 & b from which we
infer C, A ⊢n fn x ⇒ e : t1 →b t2 & ∅.
The case (app). Then we have C, A ⊢c e1 e2 : t1 & (b1 ∪ b2 ∪ b) because
C, A ⊢c e1 : t2 →b t1 & b1 and C, A ⊢c e2 : t2 & b2 . Then the induction hy-
pothesis gives C, A ⊢n e1 : t2 →b t1 & b1 and C, A ⊢n e2 : t2 & b2 . We thus can
infer the desired C, A ⊢n e1 e2 : t1 & (b1 ∪ b2 ∪ b).
The case (let). Then we have C, A ⊢c let x = e1 in e2 : t2 & (b1 ∪ b2 ) be-
cause C, A ⊢c e1 : ts1 & b1 and C, A[x : ts1 ] ⊢c e2 : t2 & b2 . Then the induction
hypothesis gives C, A ⊢n e1 : ts1 & b1 . From Fact 9 we get that ts1 is well-
formed and solvable from C, so we can apply the induction hypothesis to get
C, A[x : ts1 ] ⊢n e2 : t2 & b2 . This enables us to infer the desired
C, A ⊢n let x = e1 in e2 : t2 & (b1 ∪ b2 ).
The cases (rec), (if ), (sub): Analogous to the above cases.
The case (ins). Then we have C, A ⊢c e : S t0 & b because
C, A ⊢c e : ∀(~ αβ~ : C0 ). t0 & b where Dom(S) ⊆ {~ αβ}~ and C ⊢ S C0 . By apply-
ing the induction hypothesis we get C, A ⊢n e : ∀(~ αβ~ : C0 ). t0 & b so by Lemma
15 we get C, A ⊢n e : S t0 & b as desired.
The case (gen). Then we have C, A ⊢c e : ∀(~ αβ~ : C0 ). t0 & b because
C ∪ C0 , A ⊢c e : t0 & b where ∀(~ ~
αβ : C0 ). t0 is well-formed, solvable from C and
satisfies {~ ~ ∩ FV(C, A, b) = ∅. Now A is well-formed and solvable from C ∪ C0
αβ}
so the induction hypothesis gives C ∪ C0 , A ⊢n e : t0 & b. Therefore we have the
TS-normalised inference tree C, A ⊢n e : ∀(~ αβ~ : C0 ). t0 & b. 2

Conservative extension

Theorem 21 Let e be a sequential expression:

– if [ ] ⊢ML e : u then ∅, [ ] ⊢ e : ι(u) & ∅;


– if C, [ ] ⊢ e : t & b where C contains no type constraints then [ ] ⊢ML e : ǫ(t).
Before embarking on the proof we need to extend ǫ() and ι() to work on
substitutions: from a substitution S we construct an ML substitution R = ǫ(S)
by stipulating R α = ǫ(S α); and from an ML substitution R we construct a
substitution S = ι(R) by stipulating S α = ι(R α).

Fact 23. For all S and R and all t and u, we have ǫ(S t) = ǫ(S) ǫ(t) and ι(R u) =
ι(R) ι(u).

Proof. The claims are proved by induction in t respectively in u. If t = α the first


equation follows from the definition of ǫ(S), and if u = α the second equation
follows from the definition of ι(R). If t (respectively u) is a base type like int,
the equations are trivial. If t is a composite type like t1 →b t2 , the first equation
reads

ǫ(S t1 ) → ǫ(S t2 ) = ǫ(S) ǫ(t1 ) → ǫ(S) ǫ(t2 )

and follows from the induction hypothesis. If u is a composite type like u1 → u2 ,


the second equation reads

ι(R u1 ) →∅ ι(R u2 ) = ι(R) ι(u1 ) →∅ ι(R) ι(u2 )

and follows from the induction hypothesis. 2

Proof of the first part of Theorem 21 The first part of the theorem follows
from the following proposition which admits a proof by induction:

Proposition 24. Let e be sequential. If A ⊢ML e : u then ∅, ι(A) ⊢ e : ι(u) & ∅.


Similarly with us instead of u.

Proof. Induction in the proof tree for A ⊢ML e : us, where we perform case
analysis on the definition in Fig. 4 (the clauses for conditionals and for recursion
are omitted, as they present no further complications).

The case (con): Follows from Assumption 20.

The case (id): Follows trivially.

The case (abs): By induction we get

∅, ι(A)[x : ι(u1 )] ⊢ e : ι(u2 ) & ∅

and by using (abs) we get

∅, ι(A) ⊢ fn x ⇒ e : ι(u1 ) →∅ ι(u2 ) & ∅

which is as desired since ι(u1 → u2 ) = ι(u1 ) →∅ ι(u2 ).


The case (app): We can apply the induction hypothesis twice to arrive at

∅, ι(A) ⊢ e1 : ι(u2 → u1 ) & ∅


∅, ι(A) ⊢ e2 : ι(u2 ) & ∅

so since ι(u2 → u1 ) = ι(u2 ) →∅ ι(u1 ) we can apply (app) to get

∅, ι(A) ⊢ e1 e2 : ι(u1 ) & ∅ ∪ ∅ ∪ ∅.

As ∅ ⊢ ∅ ∪ ∅ ∪ ∅ ⊆ ∅ by (sub) we have the desired judgement

∅, ι(A) ⊢ e1 e2 : ι(u1 ) & ∅.

The case (let): By applying the induction hypothesis twice we get

∅, ι(A) ⊢ e1 : ι(us1 ) & ∅


∅, ι(A)[x : ι(us1 )] ⊢ e2 : ι(u2 ) & ∅

so by applying (let) and (sub) we get the desired judgement

∅, ι(A) ⊢ let x = e1 in e2 : ι(u2 ) & ∅.

The case (ins): We can apply the induction hypothesis to get

∅, ι(A) ⊢ e : ∀(~
α : ∅). ι(u) & ∅

so applying (ins) with the substitution ι(R) we arrive at

∅, ι(A) ⊢ e : ι(R) ι(u) & ∅

which is as desired since by Fact 23 we have ι(R) ι(u) = ι(R u).

The case (gen): We can apply the induction hypothesis to get

∅, ι(A) ⊢ e : ι(u) & ∅

and the conclusion we want to arrive at is

∅, ι(A) ⊢ e : ∀(~
α : ∅). ι(u) & ∅

which follows by using (gen) provided that (i) ∀(~


α : ∅). ι(u) is well-formed and
solvable from ∅ and (ii) {~
α } ∩ FV(ι(A)) = ∅. Here (i) is trivial; and (ii) follows
from {~α } ∩ FV(A) = ∅ since clearly FV(ι(A)) = FV(A). 2

Auxiliary notions. Before embarking on the second part of Theorem 21 we


need to develop some extra machinery.
ML type equations. ML type equations are of the form u1 = u2 . With Ct a
set of ML type equations and with R an ML substitution, we say that R satisfies
(or unifies) Ct iff for all (u1 = u2 ) ∈ Ct we have R u1 = R u2 .
The following fact is well-known from unification theory:

Fact 25. Let Ct be a set of ML type equations. If there exists an ML substitution


which satisfies Ct , then Ct has a “most general unifier”: that is, an idempotent
substitution R which satisfies Ct such that if R′ also satisfies Ct then there exists
R′′ such that R′ = R′′ R.

Lemma 26. Suppose R0 with Dom(R0) ⊆ G satisfies a set of ML type equations


Ct . Then Ct has a most general unifier R with Dom(R) ⊆ G.

Proof. From Fact 25 we know that Ct has a most general unifier R1 , and hence
there exists R2 such that R0 = R2 R1 . Let G1 = Dom(R1 )\Dom(R0); for α ∈ G1
we have R2 R1 α = R0 α = α and hence R1 maps the variables in G1 into distinct
variables G2 (which by R2 are mapped back again). Since R1 is idempotent we
have G2 ∩ Dom(R1 ) = ∅, so R0 equals R2 on G2 showing that G2 ⊆ Dom(R0).
Moreover, G1 ∩ G2 = ∅.
Let φ map α ∈ G1 into R1 α and map α ∈ G2 into R2 α and behave as
the identity otherwise. Then φ is its own inverse so that φ φ = Id. Now define
R = φ R1 ; clearly R unifies Ct and if R′ also unifies Ct then (since R1 is most
general unifier) there exists R′′ such that R′ = R′′ R1 = R′′ φ φ R1 = (R′′ φ) R.
We are left with showing (i) that R is idempotent and (ii) that Dom(R) ⊆
G. For (i), first observe that R1 φ equals Id except on Dom(R1). Since R1 is
idempotent we have FV(R1 α) ∩ Dom(R1) = ∅ (for all α) and hence

R R = φ R1 φ R1 = φ Id R1 = R

For (ii), observe that R equals Id on G1 so it will be sufficient to show that


R α = α if α ∈ / (G ∪ G1 ). But then α ∈
/ Dom(R0) and hence α ∈ / G2 and
α∈/ Dom(R1) so R α = φ α = α. 2

From a constraint set C we construct a set of ML type equations ǫ(C) as


follows:
ǫ(C) = {(ǫ(t1 ) = ǫ(t2 )) | (t1 ⊆ t2 ) ∈ C}.

Fact 27. Suppose C ⊢ t1 ⊆ t2 . If R satisfies ǫ(C) then R ǫ(t1 ) = R ǫ(t2 ).


So if C ⊢ C ′ and R satisfies ǫ(C) then R satisfies ǫ(C ′ ).

Proof. Induction in the proof tree. If (t1 ⊆ t2 ) ∈ C, the claim follows from the
assumptions. The cases for reflexivity and transitivity are straight-forward. For

the structural rules, assume e.g. that C ⊢ t1 →b t2 ⊆ t′1 →b t′2 because (among
′ ′
other things) C ⊢ t1 ⊆ t1 and C ⊢ t2 ⊆ t2 . By using the induction hypothesis we
get the desired equality

R ǫ(t1 →b t2 ) = R ǫ(t1 ) → R ǫ(t2 ) = R ǫ(t′1 ) → R ǫ(t′2 ) = R ǫ(t′1 →b t′2 ).
Relating type schemes. For a type scheme ts = ∀(~ αβ~ : C). t we shall not
in general (when C 6= ∅) define any entity ǫ(ts); this is because one natural
attempt, namely ∀(~ α : ǫ(C)). ǫ(t), is not an ML type scheme and another natural
attempt, ∀~α .ǫ(t), causes loss of the information in ǫ(C). Rather we shall define
some relations between ML types, types, ML type schemes and type schemes:
Definition 28. We write u ≺R α β~ : C0 ). t0 and where R is an
ǫ ts, where ts = ∀(~
ML substitution, iff there exists R0 which equals R on all variables except α ~
such that R0 satisfies ǫ(C0 ) and such that u = R0 ǫ(t0 ).
Notice that instead of demanding R0 to equal R on all variables but α ~ , it is
sufficient to demand that R0 equals R on FV(ts). (We have the expected property
′ R ′
that if u ≺Rǫ ts and ts is alpha-equivalent to ts then also u ≺ǫ ts .)

Definition 29. We write u≺us, where us = ∀~


α .u0 , iff there exists R0 with
Dom(R0 ) ⊆ α
~ such that u = R0 u0 .

Definition 30. We write us ∼


=R R
ǫ ts to mean that (for all u) u≺us iff u ≺ǫ ts.

α β~ : ∅). t is sequential. Then


Fact 31. Suppose us = ǫ(ts), where ts = ∀(~
∼ Id
us =ǫ ts.

Proof. We have us = ∀~α .ǫ(t), so for any u it holds that u≺us ⇔ ∃ R with
Dom(R) ⊆ α~ such that u = R ǫ(t) ⇔ u ≺Idǫ ts. 2

Notice that ∀().u ∼


=R
ǫ ∀(() : ∅). t holds iff u = R ǫ(t). We can thus consistently
∼ R
extend =ǫ to relate not only type schemes but also types:

Definition 32. We write u ∼


=R
ǫ t iff u = R ǫ(t).

Definition 33. We write A′ ∼


=R ′ ′ ∼R
ǫ A iff Dom(A ) = Dom(A) and A (x) =ǫ A(x)
for all x ∈ Dom(A).

Fact 34. Let R and S be such that ǫ(S) = R (this will for instance be the case if
S = ι(R), cf. Fact 19). Then the relation u ≺R Id
ǫ ts holds iff the relation u ≺ǫ S ts
holds.
Consequently, us ∼=R ∼Id
ǫ ts holds iff us =ǫ S ts holds.

Proof. Let ts = ∀(~ α β~ : C). t. Due to the remark after Definition 28 we can
~
assume that ~α β is disjoint from Dom(S) ∪ Ran(S), so S ts = ∀(~ α β~ : S C). S t.

First we prove “if”. For this suppose that R equals Id except on ~α and that
R′ satisfies ǫ(S C) and that u = R′ ǫ(S t), which by straight-forward extensions
of Fact 23 amounts to saying that R′ satisfies R ǫ(C) and that u = R′ R ǫ(t).
Since {~α } ∩ Ran(R) = ∅ we conclude that R′ R equals R except on α ~ , so we can

use R R to show that u ≺R ǫ ts.
Next we prove “only if”. For this suppose that R′ equals R except on α ~
and that R′ satisfies ǫ(C) and that u = R′ ǫ(t). Let R′′ behave as R′ on α ~ and
behave as the identity otherwise. Our task is to show that R′′ satisfies ǫ(S C) and
that u = R′′ ǫ(S t), which as we saw above amounts to showing that R′′ satisfies
R ǫ(C) and that u = R′′ R ǫ(t). This will follow if we can show that R′ = R′′ R.
~ we have R′′ R α = R′′ α = R′ α since Dom(R) ∩ {~
But if α ∈ α α } = ∅, and if
α∈/α~ we have R′′ R α = R α = R′ α where the first equality sign follows from
Ran(R) ∩ {~α } = ∅ and Dom(R′′) ⊆ α ~. 2

Fact 35. If us ∼
=Id
ǫ ts then FV(us) ⊆ FV(ts).

Proof. We assume us ∼ =Id


ǫ ts where us = ∀~α ′ .u and ts = ∀(~
αβ ~ : C). t. Let α1 be
given such that α1 ∈ / FV(ts), our task is to show that α1 ∈ / FV(us).
Clearly u≺us so u ≺Id ǫ ts, that is there exists R with Dom(R) ⊆ α ~ such
that R satisfies ǫ(C) and such that u = R ǫ(t). Now define a substitution R1
which maps α1 into a fresh variable and is the identity otherwise. Due to our
assumption about α1 it is easy to see that R1 R equals Id on FV(ts), and as
R1 R clearly satisfies ǫ(C) it holds that R1 u = R1 R ǫ(t) ≺Id ǫ ts and hence also
R1 u≺us. As α1 ∈ / FV(R1 u) we can infer the desired α1 ∈ / FV(us). 2

Proof of the second part of Theorem 21 The second part of the theorem
follows (by letting R = Id and A = A′ = [ ]) from the following proposition,
which admits a proof by induction.

Proposition 36. Let e be sequential, suppose C, A ⊢ e : ts & b, suppose R sat-


isfies ǫ(C), and suppose A′ ∼
=R ∼R
ǫ A; then there exists a us with us =ǫ ts such

that A ⊢ML e : us. Similarly with t and u instead of ts and us (in which case
u = R ǫ(t)).

We perform induction in the proof tree of C, A ⊢ e : ts & b, using terminology


from Fig. 2 (the clauses for conditionals and for recursion are omitted, as they
present no further complications):

The case (con): Here ts = TypeOf(c) and we choose us = MLTypeOf(c).


By Assumption 20 and by Fact 31 we know that us ∼ =Id
ǫ ts. Since TypeOf(c) is
closed (cf. Fact 8) we have us ∼Id
=ǫ ι(R) ts so Fact 34 gives us the desired relation
us ∼
=Rǫ ts.

The case (id): Here ts = A(x). Since A′ ∼


=R ′ ∼R
ǫ A it holds that A (x) =ǫ A(x) and
′ ′
A ⊢ML x : A (x), as desired.

The case (abs): Suppose R satisfies ǫ(C) and that A′ ∼ =Rǫ A. Then also
′ ∼ R
A [x : R ǫ(t1 )] =ǫ A[x : t1 ], so the induction hypothesis can be applied to find u2
such that u2 = R ǫ(t2 ) and such that A′ [x : R ǫ(t1 )] ⊢ML e : u2 . By using (abs)
we get the judgement

A′ ⊢ML fn x ⇒ e : R ǫ(t1 ) → u2

which is as desired since R ǫ(t1 ) → u2 = R ǫ(t1 →b t2 ).


The case (app): Suppose R satisfies ǫ(C1 ∪ C2 ) and that A′ ∼ =Rǫ A. Clearly R
satisfies ǫ(C1 ) as well as ǫ(C2 ), so the induction hypothesis can be applied to
infer that

A′ ⊢ML e1 : R ǫ(t2 →b t1 ) and A′ ⊢ML e2 : R ǫ(t2 )

and since R ǫ(t2 →b t1 ) = R ǫ(t2 ) → R ǫ(t1 ) we can apply (app) to arrive at


the desired judgement A′ ⊢ML e1 e2 : R ǫ(t1 ).

The case (let): Suppose R satisfies ǫ(C1 ∪ C2 ) and that A′ ∼ =R ǫ A. Since R satis-
fies ǫ(C1 ) we can apply the induction hypothesis to find us1 such that us1 ∼ =Rǫ ts1

and such that A ⊢ML e1 : us1 .
Since R satisfies ǫ(C2 ) and since A′ [x : us1 ] ∼
=Rǫ A[x : ts1 ] we can apply the

induction hypothesis to infer that A [x : us1 ] ⊢ML e2 : R ǫ(t2 ). Now use (let) to
arrive at the desired judgement A′ ⊢ML let x = e1 in e2 : R ǫ(t2 ).

The case (sub): Suppose R satisfies ǫ(C) and that A′ ∼


=Rǫ A. By applying the

induction hypothesis we infer that A ⊢ML e : R ǫ(t) and since by Fact 27 we
have R ǫ(t) = R ǫ(t′ ) this is as desired.

The case (ins): Suppose that R satisfies ǫ(C) and that A′ ∼ =R


ǫ A. The induction
hypothesis tells us that there exists us with us ∼ R
=ǫ ∀(~ α β~ : C0 ). t0 such that
A′ ⊢ML e : us.
Since C ⊢ S0 C0 and R satisfies ǫ(C), Fact 27 tells us that R satisfies ǫ(S0 C0 )
which by Fact 23 equals ǫ(S0 ) ǫ(C0 ), thus R ǫ(S0 ) satisfies ǫ(C0 ). As R ǫ(S0 )
equals R except on ~α , it holds that R ǫ(S0 ) ǫ(t0 ) ≺R α β~ : C0 ). t0 and since
ǫ ∀(~
∼ R
us =ǫ ∀(~ ~
α β : C0 ). t0 we have R ǫ(S0 ) ǫ(t0 )≺us. But this shows that we can use
(ins) to arrive at the judgement A′ ⊢ML e : R ǫ(S0 ) ǫ(t0 ) which is as desired
since ǫ(S0 ) ǫ(t0 ) = ǫ(S0 t0 ) by Fact 23.

The case (gen): Suppose that R satisfies ǫ(C) and that A′ ∼ =R


ǫ A. Our task is
to find us such that us ∼R
α β~ : C0 ). t0 and such that A ⊢ML e : us. Below
=ǫ ∀(~ ′

we will argue that we can assume that {~ α } ∩ (Dom(R) ∪ Ran(R)) = ∅.

Let T be a renaming substitution mapping α ~ into fresh variables α~ ′ . By


applying Lemma 10, by exploiting that FV(C, A, b) ∩ {~ α β~ } = ∅, and by
using (gen) we can construct a proof tree whose last nodes are
C ∪ T C0 , A ⊢ e : T t0 & b
α ′ β~ : T C0 ). T t0 & b
C, A ⊢ e : ∀(~
the conclusion of which is alpha-equivalent to the conclusion of the orig-
inal proof tree, and the shape of which (by Lemma 10) is equal to the
shape of the original proof tree.

There exists S0 with Dom(S0 ) ⊆ {~ α β~ } such that C ⊢ S0 C0 . Fact 27 then tells


us that R satisfies ǫ(S0 C0 ) which by Fact 23 equals ǫ(S0 ) ǫ(C0 ).
Now define R′0 to be a substitution with Dom(R′0 ) ⊆ {~ α } which maps α ~ into
~ is disjoint from Dom(R) ∪ Ran(R)) that
R ǫ(S0 ) ~α . It is easy to see (since α
R′0 R = R ǫ(S0 ), implying that R′0 satisfies R ǫ(C0 ).
By Lemma 26 there exists R0 with Dom(R0) ⊆ {~ α } which is a most gen-
eral unifier of R ǫ(C0 ). Hence with R′ = R0 R it holds not only that R′ satisfies
ǫ(C) but also that R′ satisfies ǫ(C0 ), so in order to apply the induction hypoth-
esis on R′ we just need to show that A′ ∼

=Rǫ A. This can be done by showing
that R equals R′ on FV(A), but this follows since our assumptions tell us that
Dom(R0) ∩ FV(R A) = ∅.
The induction hypothesis thus tells us that A′ ⊢ML e : R′ ǫ(t0 ). Let S = ι(R)
(which by Fact 19 implies that R = ǫ(S)); by Fact 34 and Fact 35 we infer that
FV(A′ ) ⊆ FV(S A), so since {~ α } ∩ FV(A) = ∅ and {~ α } ∩ Ran(S) = ∅ we
have {~α } ∩ FV(A′ ) = ∅. We can thus use (gen) to arrive at the judgement
A′ ⊢ML e : ∀~ α .R′ ǫ(t0 ).
We are left with showing that ∀~ α .R′ ǫ(t0 ) ∼
=Rǫ ∀(~
αβ~ : C0 ). t0 but this follows
from the following calculation (explained below):

u ≺R ~ : C0 ). t0
ǫ ∀(~αβ
⇔ u ≺Id ~ : S C0 ). S t0
ǫ ∀(~αβ
⇔ ∃R1 with Dom(R1 ) ⊆ {~ α}
such that R1 satisfies R ǫ(C0 ) and u = R1 R ǫ(t0 )
⇔ ∃R1 with Dom(R1 ) ⊆ {~ α}
such that ∃R2 : R1 = R2 R0 and u = R1 R ǫ(t0 )
⇔ ∃R2 with Dom(R2 ) ⊆ {~ α } such that u = R2 R0 R ǫ(t0 )
⇔ u≺∀~α .R′ ǫ(t0 ).

α β~ } is disjoint
The first ⇔ follows from Fact 34 where we have exploited that {~
from Dom(S)∪Ran(S); the second ⇔ follows from the definition of ≺Id ǫ together
with Fact 23; the third ⇔ is a consequence of R0 being the most general unifier
of R ǫ(C0 ); and the fourth ⇔ is a consequence of Dom(R0) ⊆ {~ α } since then
from R1 = R2 R0 we conclude that if α′ ∈ / {~α } then R1 α′ = R2 α′ and hence
Dom(R1) ⊆ {α} iff Dom(R2) ⊆ {α}.

You might also like