# samuelgruetter/dot-calculus

Switch branches/tags
Nothing to show
Fetching contributors…
Cannot retrieve contributors at this time
1166 lines (847 sloc) 42.3 KB

# The DOT Calculus

A minimally complete version of dependent object types. The calculus comprises functions, labeled types and terms combined through intersections, recursive bindings, and nothing else.

The meta theory establishes type safety, a result that has also been fully mechanized. Here is the corresponding Coq script.

## Abstract Syntax

``````Term member     a, b, c
Type member     A, B, C
Variable        x, y, z

Type     S, T, U = {a: T}                       field declaration
{A: S..T}                    type declaration
S & T                        intersection
x.A                          projection
rec(x: T)                    recursive dependent type
all(x: S)T                   dependent function
Top                          top type
Bot                          bottom type

Value          v = new(x: T)d                   object
lambda(x: T)t                lambda

Term     s, t, u = x                            variable
v                            value
x.a                          selection
x y                          application
let x = t in u               let

Definition     d = {a = t}                      field definition
{A = T}                      type definition
d & d'                       aggregate definition

Store          s = ... x = v ...
Environment    G = ... x: T ...
``````

### Evaluation: `s | t -> s' | t'`

``````(Project)
s | x.a  -->  s | t          if s(x) = new(x: T)(d, a = t)
(Apply)
s | x y  -->  s | [z:=y]t    if s(x) = lambda(z: T)t
(Let-Var)
s | let x = y in t  -->  s | [x:=y]t
(Let-Value)
s | let x = v in t  -->  s, x = v | t
(Ctx)
s | t  -->  s' | t'
---------------------------------------------
s | let x = t in u  -->  s' | let x = t' in u
``````

## Typing Rules

### Type Assignment `G |- t: T`

``````(Var)
G, x: T, G' |- x: T
(All-I)
G, x: T |- t: U    (x not in fv(T))
-----------------------------------
G |- lambda(x: T)t: all(x: T)U
(All-E)
G |- x: all(z: S)T    G |- y: S
-------------------------------
G |- x y: [z:=y]T
({}-I)
G, x: T |- d: T
--------------------------
G |- new(x: T)d: rec(x: T)
({}-E)
G |- x: {a: T}
--------------
G |- x.a: T
(Let)
G |- t: T   G, x: T |- u: U   (x not in fv(U))
----------------------------------------------
G |- let x = t in u: U
(Rec-I)
G |- x: T
-----------------
G |- x: rec(x: T)
(Rec-E)
G |- x: rec(x: T)
-----------------
G |- x: T
(&-I)
G |- x: T   G |- x: U
---------------------
G |- x: T & U
(Sub)
G |- t: T   G |- T <: U
-----------------------
G |- t: U
``````

### Definition Type Assignment `G |- d: T`

``````(Fld-I)
G |- t: T
--------------------
G |- {a = t}: {a: T}
(Typ-I)
G |- {A = T}: {A: T..T}
(AndDef-I)
G |- d1: T1   G |- d2: T2   (dom(d1), dom(d2) disjoint)
-------------------------------------------------------
G |- d1 & d2: T1 & T2
``````

### Subtyping: `G |- T <: U`

``````(<:-Top)
G |- T <: Top
(Bot-<:)
G |- Bot <: T
(Refl-<:)
G |- T <: T
(Trans-<:)
G |- S <: T   G |- T <: U
-------------------------
G |- S <: U
(And-<:)
G |- T & U <: T

G |- T & U <: U
(<:-And)
G |- S <: T   G |- S <: U
-------------------------
S <: T & U
(Fld-<:-Fld)
G |- T <: U
---------------------
G |- {a: T} <: {a: U}
(Typ-<:-Typ)
G |- S2 <: S1   G |- T1 <: T2
-------------------------------
G |- {A: S1..T1} <: {A: S2..T2}
(<:-Sel)
G |- x: {A: S..T}
-----------------
G |- S <: x.A
(Sel-<:)
G |- x: {A: S..T}
-----------------
G |- x.A <: T
(All-<:-All)
G |- S2 <: S1   G, x: S2 |- T1 <: T2
------------------------------------
G |- all(x: S1)T1 <: all(x: S2)T2
``````

Note: `G, x: T` is well-defined only if `x` is neither in the domain of `G` nor in its free variables.

## Abbreviations

Group multiple intersected definitions or declarations in one pair of braces, replacing `&` with `;`. E.g.

``````         { A = T; a = t }  ===  { A = T } & { a = t }
{ A: S..T; a: T }  ===  { A: S..T } & { a: T }
``````

Allow terms in applications and selections, using the expansions

``````                      t u  ===  let x = t in x u
x u  ===  let y = u in x y
t.a  ===  let x = t in x.a
``````

Expand type ascriptions to applications:

``````                     t: T  ===  (lambda(x: T)x)t
``````

Shorthand syntax for object types and values:

``````     { z => D1; ...; Dn }  ===  rec(z: D1 & ... & Dn)
new { z => d1; ...; dn }  ===  new(x: D1 & ... & Dn)d1 & ... & dn
where Di derived from di. (di needs to have full type info)
``````

One can leave out the `z =>` if `z` does not appear in the rest of the term.

Shorthand syntax for self bounds: In type of `x`, expand

``````                  A <: T   ===  A: Bot .. T
A >: S   ===  A: S .. Top
A = T   ===  A: T .. T
A   ===  A: Bot .. Top
``````

## Meta Theory

### Definition (Precise typing)

`G |-! t: T` if `G |- t: T` and the following two conditions hold:

1. If `t` is a value, the typing derivation of `t` ends in (All-I) or ({}-I).
2. If `t` is a variable, the typing derivation of `t` consists only of (Var), (Rec-E) and (Sub) steps and every (Sub) step makes use of only the subtyping rules (And-<:) and (Trans).

### Definition (Environment/store correspondence)

An environment `G` corresponds to a store `s`, written `G ~ s`, if `G ~ s` can be derived using the rules below.

``````                          (empty) ~ (empty)

G ~ s   G |-! v: T
------------------
G, x: T ~ s, x = v
``````

### Definition (Underlying value)

Given a store `s` and a variable `x` bound in `s`, the underlying value `s(x)` is the value `v` such that `x = v in s`.

### Lemma (Weakening)

Let `G = G', x: S`. Then

• If `G' |- t: T` then `G |- t: T`
• If `G' |-! v: T` then `G |-! v: T`.
• If `G' |- T <: U` then `G |- T <: U`.
• If `G' ~ s` then `G ~ s`.

Proof: All derivations remain valid in an environment with extra information.

### Definition (Environment subsumption)

Environment `G` subsumes `G'`, written `G <: G'`, if for all `x: T` in `G'` we have `G |- x: T`.

### Lemma (Narrowing)

If `G <: G'` then:

• If `G' |- t: T` then also `G |- t: T`
• If `G' |- d: T` then also `G |- d: T`
• If `G' |- S <: T` then also `G' |- S <: T`

Proof: A straightforward induction on typing, subtyping and well-formedness derivations.

### Definition (Environment Renaming)

``````[x:=y]G = [[x:=y]z: [x:=y]T | z: T in G]
``````

### Lemma (Renaming)

Let [s] be a renaming `[x0:=y0]` for arbitrary variables `x0`, `y0`. Then

• ` [s]rec(x: T) = rec([s]x: [s]T)`
• ` [s]all(x: T)U = all([s]x: [s]T): [s]U`
• ` [s]new(x: T)d = new([s]x: [s]T): [s]d`
• ` [s]lambda(x: T)t = lambda([s]x: [s]T): [s]t`
• `[s]let x = t in u = let [s]x = [s]t in [s]u`

Proof. We prove the first equation; the others are analogous. We distinguish whether or not `x0 = x`.

If `x0 = x` then

``````  [s]rec(x0: T)
= (by definition of substitution)
rec(x0: T)
= (by alpha renaming x0 to y0)
rec(y0: [y0:=x0]T)
= (by rewriting)
rec([s]x0: [s]T)
``````

If `x0 != x` then

``````  [s]rec(x: T)
= (by definition of substitution)
rec(x: [s]T)
= (since x0 != x)
rec([s]x0: [s]T)
``````

### Lemma (Subst)

1. If `G, x: S |- t: T` and `G |- y: [x:=y]S` then `G |- [x:=y]t: [x:=y]T`.
2. If `G, x: S |- d: T` and `G |- y: [x:=y]S` then `G |- [x:=y]d: [x:=y]T`.

We prove the more general proposition:

If `G, x: S, G' |- t: T` and `G, [x:=y]G' |- y: [x:=y]S`, then `G, [x:=y]G' |- [x:=y]t: [x:=y]T`. (and the same for `d` instead of `t`).

Proof by mutual induction on derivations. Let `[s] = [x0:=y0]`. Assume `G, x0: S0, G' |- t0: T0` and `G, [s]G' |- y0: [s]S0`. To show: `G, [s]G' |- [s]t0: [s]T0`.

We distinguish according to the last rule in the derivation of `G, x0: S0, G' |- t0: T0`

Case (Var): We have in this case: `t = x0`, `T0 = S0`, `G, x0: S0, G' |- x: S0`, and `G, [s]G' |- y0: [s]S0`. Together, `G, x0: S0, G' |- [s]x0: [s]S0`.

Case (All-I) Then `t0 = lambda(x: T)t` and the last rule is

``````                 G, x0: S0, G', x: T |- t: U
------------------------------------------
G, x0: S0, G' |- lambda(x: T)t: all(x: T)U
``````

By the I.H., `G, [s]G', [s]x: [s]T |- [s]t: [s]U`. By (All-I), `G, [s]G' |- lambda([s]x: [s]T)[s]t): all([s]x: [s]T)[s]U`. By applying Lemma (Renaming) twice to the RHS, `G, [s]G' |- [s]lambda(x: T)t): [s]all(x: T)U`.

Case (All-E) Then `t0 = x y` and the last rule is

``````   G, x0: S0, G' |- x: all(y: S)T    G, x0: S0, G' |- y: S
-------------------------------------------------------
G, x0: S0, G' |- x y: [z:=y]T
``````

By the. I.H., `G, [s]G' |- [s]x: all(z: [s]S)[s]T` and `G, [s]G' |- [s]y: [s]S`. By (All-E), `G, [s]G' |- [s]x [s]y: [z:=[s]y][s]T`. W.l.o.g choose `z` so that `z != x0`, `z != y`. Hence, `[z:=[s]z][s]` = [s][z:=y]. Together, `G,[s]G' |- [s](x y): [s][z:=y]T`.

Case ({}-I): Then `t0 = new(x: T)d` and the last rule is

``````                 G, x0: S0, G', x: T |- d: T
--------------------------------------
G, x0: S0, G' |- new(x: T)d: rec(x: T)
``````

By the I.H., `G, [s]G', [s]x: [s]T |- [s]d: [s]T`. By ({}-I), `G, [s]G' |- new([s]x: [s]T)[s]d: rec([s]x: [s]T)` By applying Lemma (Renaming) twice to the RHS, `G, [s]G' |- [s]new(x: T)d: [s]rec(x: T)`.

Case ({}-E) Then `t0 = x.a` and the last rule is:

``````                 G, x0: S0, G' |- x: {a: T}
---------------------------
G, x0: S0, G' |- x.a: T
``````

By the I.H., `G, [s]G' |- [s]x: {a: [s]T}`. By ({}-E), `G, [s]G' |- [s]x.a: [s]T`.

Case (Let): Then `t0 = let x = t in u` and the last rule is:

``````G, x0: S0, G' |- t: T   G, x0: S0, G', x: T |- u: U   (x not in fv(U))
----------------------------------------------------------------------
G, x0: S0, G' |- let x = t in u: U
``````

By the I.H., `G, [s]G' |- [s]t: [s]T` and `G, [s]G', [s]x: [s]T |- [s]u: [s]U`. With (Let) it follows that `G, [s]G' |- let [s]x = [s]t in [s]u: [s]U`. By (Renaming), `G, [s]G' |- [s]let x = t in u: [s]U`.

Case (Rec-I): Then `t0 = x` and the last rule is:

``````                          G |- x: T
-----------------
G |- x: rec(x: T)
``````

By the I.H., `G, [s]G' |- [s]x: [s]T`. By (Rec-I), `G, [s]G' |- [s]x: rec([s]x: [s]T)`. By applying Lemma (Renaming) to the `rec` term, `G, [s]G' |- [s]x: [s]rec(x: T)`.

Case (Rec-E): Then `t0 = x` and the last rule is:

``````                G, x0: S0, G' |- x: rec(x: T)
-----------------------------
G, x0: S0, G' |- x: T
``````

By the I.H., `G, [s]G' |- [s]x: [s]rec(x: T)`. By applying Lemma (Renaming) to the `rec` term, `G, [s]G' |- [s]x: rec([s]x: [s]T)`. By (Rec-E), `G, [s]G' |- [s]x: [s]T`.

Case (&=I). Then `t0 = x` amd the last rule is:

``````                    G |- x: T   G |- x: U
---------------------
G |- x: T & U
``````

By the I.H., `G, [s]G' |- [s]x: [s]T` and `G, [s]G' |- [s]x: [s]U`. By (&=I), `G, [s]G' |- [s]x: [s]T & [s]U`.

Case (Sub) Then `t0 = t` and the last rule is:

``````       G, x0: S0, G' |- t: T   G, x0: S0, G' |- T <: U
-----------------------------------------------
G, x0: S0, G' |- t: U
``````

By the I.H., `G, [s]G' |- [s]t: [s]T`. By (Subst-<:), `G, [s]G' |- [s]T <: [s]U`. By (Sub), `G, [s]G' |- [s]T: [s]U`.

Case (Fld). Then `t0 = {a = t}` and the last rule is:

``````                    G, x0: S0, G' |- t: S
--------------------------------
G, x0: S0, G' |- {a = t}: {a: T}
``````

By the I.H, `G, [s]G' |- [s]t: [s]S`. By (Fld), `G, [s]G' |- {a = [s]t}: {a: [s]T}`. Rewriting this gives `G, [s]G' |- [s]{a = t}: [s]{a: T}`.

Cases (Typ), (And) are analogous to (Fld).

### Lemma (Subst-<:)

If `G, x: S, G' |- T <: U` and `G, [x:=y]G' |- y: [x:=y]S`, then `G, [x:=y]G' |- [x:=y]T <: [x:=y]U`.

Proof by mutual induction on derivations. Let [s] = [x0:=y0]. Assume `G, x0: S0, G' |- T0 <: U0` and `G, [s]G' |- y0: [s]S0`. To show: `G [s]G' |- [s]T0 <: [s]U0`.

We only show two cases; the others are similar.

Case(<:-Sel): Then `T0 = S` and the last rule of `D` is:

``````                G, x0: S0, G' |- x: {A: S..T}
-----------------------------
G, x0: S0, G' |- S <: x.A
``````

By the I.H., `G, [s]G' |- [s]x: {A: [s]S..[s]T}`. By (<:-Sel), `G, [s]G' |- [s]S <: [s]x.A`.

Case (All-<:-All) Then `T0 = all(x: S1)T1` and the last rule is:

`````` G, x0: S0, G' |- S2 <: S1   G, x0: S0, G', x: S2 |- T1 <: T2
------------------------------------------------------------
G, x0: S0, G' |- all(x: S1)T1 <: all(x: S2)T2
``````

By the I.H., `G, [s]G' |- [s]S2 <: [s]S1` and `G, [s]G', [s]x: [s]S2 |- [s]T1 <: [s]T2`. By (All-<:-All), `G, [s]G' |- all([s]x: [s]S1)[s]T1 <: all([s]x: [s]S1)[s]T1`. By (Renaming), `G, [s]G' |- [s]all(x: S1)T1 <: [s]all(x: S2)T2`.

### Lemma (Corresponding Definition Types)

If `G ~ s` and `s(x) = new(x: S)d` for some definitions `d = d1 & ... & dn` then

1. `x: rec(x: S) in G`.

2. `S = S1 & ... & Sn` where for each `i` either

• `di` is of the form `{a = t}` and `Si = {a: T}` for some `T` such that `G |- t: T`, or
• `di` is of the form `{A = T}` and `Si = {A: T..T}`.

Proof By the definition of `~`, `G` contains a binding for `x`, say `G = G1,x:T,G2` such that `G1 |- s(x): T`. Also by the definition of `~` and with ({}-I), `G1 |-! new(x: S)d: rec(x: S)`, which establishes (1). Furthermore, by the formulation of the ({}-I) Rule and definition typing it follows that `S` has the form given in (2).

### Lemma (Corresponding types)

If `G ~ s` and `x: T in G` then exactly one of the following alternatives applies:

1. `s(x) = lambda(y:S)t` for a term `t` such that `G, x: S |- t: U` and `T = all(x: S)U`.
2. `s(x) = new(s:S)d` and `T = rec(x:S)`.

Proof: Assume `x: T in G`, say `G = G1,x:T,G2`. By the definition of `~`, `G1 |-! v: T` for some value `v`. We distinguish acccording to whether `v` is a `lambda` or `new`.

In the first case, let `v = lambda(y: S)t`. By by definition of `|-!`, `T` is derived using rule (all-I). Hence, `T = all(x: S)U` for some type `U` such that `G1, x: S |- t: U`. By (Weakening), `G, x: S |- t: U`.

In the second case, let `v = new(x: S)d` (arranging w.l.o.g by alpha renaming that the bound variable in the new is `x`). By by definition of `|-!`, `T` is derived using rule ({}-I). Hence, `T = rec(x: S)`.

### Lemma (Unique tight bounds)

If `G ~ s` and `G |-! x: {A: T1..T1}` and `G |-! x: {A: T2..T2}` then `T1 = T2`.

Proof Since `G |-! x: {A: Ti..Ti}` (i = 1,2), `G` contains a binding for `x`, say `x: T in G`. By (Corresponding Types) one of the following alternatives applies.

1. `s(x) = lambda(y:S)t` for a term `t` such that `G, x: S |- t: U` and `T = all(x: S)U`. But `x: {A: Ti..Ti)` cannot be derived from `x: all(x: S)U` using only (Rec-E) and (And-<:), (Trans) subsumption steps, so this alternative is impossible.

2. `s(x) = new(x:S)d` and `T = rec(x:S)`. By (Corresponding Definition Types), `T` is of the form `rec(x: S1 & ... & Sn)` where exactly one `Si` defines a label `A`. Let `Si = {A: U..U}`. It follows that `T1 = U = T2`.

### Definition (Tight bound typing)

A typing or subtyping derivation is tight in environment `G` if it only contains the following tight variants of (Sel-<:), (<:-Sel) when `G' = G`:

``````(<:-Sel-tight)
G' |-! x: {A: T..T}
-------------------
G' |- T <: x.A
(Sel-<:-tight)
G' |-! x: {A: T..T}
-------------------
G' |- x.A <: T
``````

For environments that extend G, full (Sel-<:) and (<:-Sel) are permitted.

We write `G |-# t: T` if `G |- t: T` with a derivation that is tight in `G`.

We write `G |-# S <: U` if `G |- S <: U` with a derivation that is tight in `G`.

### Definition (Has member)

A variable `x` with type `T` has a member `A: S..U` in environment `G`, written `G |-# x: T has A: S..U`, if `G |-# x: T` and the judgement is derivable by the following rules.

``````(Refl-has)
G |-# x: {A: S..U} has A: S..U
(&-has)
G |-# x: T1 has A: S..U
----------------------------
G |-# x: T1 & T2 has A: S..U

G |-# x: T2 has A: S..U
----------------------------
G |-# x: T1 & T2 has A: S..U
(rec-has)
G |-# x: T has A: S..U
------------------------------
G |-# x: rec(x: T) has A: S..U
(sel-has)
G |-! y: {B: T'..T'}   G |-# x: T' has A: S..U
----------------------------------------------
G |-# x: y.B has A: S..U
(Bot-has)
G |-# x: Bot has A: S..U
``````

### Lemma (Has member inversion)

If `G |- x: T has A: S..U` then one of the following cases applies:

1. `T = {A: S..U}`.
2. `T = T1 & T2` and `G |-# x: T1 has A: S..U` or `G |-# x: T2 has A: S..U`.
3. `T = rec(x: T')` and `G |-# x: T' has A: S..U`.
4. `T = y.B` and there exists a type `T'` such that `G |-! y: {B: T'..T'}` and `G |-# x: T' has A: S..U`.
5. `T = Bot`.

Proof: Direct from the (Has member) rules.

### Lemma (Has member tightness)

If `G ~ s` and `s(x) = new(x: T)d` and `G |-# x: rec(x: T) has A: S..U` then there is a type `T'` such that `S = T'` and `U = T'`.

Proof: By inspection of definition typing.

### Lemma (Has member covariance)

If `G ~ s`, `G |-# T1 <: T2` and `G |-# x: T1` and `G |-# x: T2 has A: S2..U2` then there exist types `S1`, `U1` such that `G |-# x: T1 has A: S1..U1` and `G |-# S2 <: S1` and `G |-# U1 <: U2`.

Proof: by induction on subtyping derivations.

Case (<:-Top). Does not apply since `Top` cannot appear in a `has` judgement.

Case (Bot-<:). By definition of (Has-member), case (Bot-has).

Case (Refl-<:). Immediate

Case (Trans-<:). Then the last rule is:

``````                G |-# T1 <: T3   G |-# T3 <: T2
-------------------------------
G |-# T1 <: T2
``````

By subsumption, since `G |-# x: T1` we have also `G |-# x: T3`. By the I.H. there exist types `S3`, `U3` such that `G |-# x: T3 has A: S3..U3` and `G |- S2 <: S3` and `G |- U3 <: U2`. By the I.H. again, `G |- x: T1 has A: S1..U1` with `G |- S3 <: S1` and `G |- U1 <: U3`. By (Trans-<:), `G |- S2 <: S1` and `G |- U1 <: U2`.

Case (And-<:). Then the last rule is one of the axioms `G |-# T2 & U <: T2` or `G |-# U & T2 <: T2`. Assume the first, the second is analogous. By rule (has-&), `G |-# x: T2 & U has A: S2..U2`.

Case (<:-And). Then `T2 = T21 & T22` and the last rule is:

``````              G |-# T1 <: T21   G |-# T1 <: T22
---------------------------------
G |-# T1 <: T21 & T22
``````

By (Has member inversion), there exists `i in {1,2}` such that `G |-# x: T2i has A: S2..U2`. By the I.H., `G |-# x: T1 has S2..U2`.

Case (Fld-<:-Fld). Does not apply since `{a: U}` cannot appear in a `has` judgement.

Case (Typ-<:-Typ). Then `T1 = {A1: S1..U1}` and `T2 = {A2: S2'..U2'}` and the last rule is:

``````              G |-# S2' <: S1   G |-# U1 <: U2'
----------------------------------
G |-# {A: S1..U1} <: {A: S2'..U2'}
``````

By (Has member inversion) on `T2`, `S2' = S2` and `U2' = U2`. By definition of (Has member) on `T1`, `G |-# x: T1 has A: S1..U1`. By inversion of the subtyping rule, the result follows.

Case (<:-Sel-tight). Then `T2 = y.B` and the last rule is:

``````                     G |-! y: {B: T1..T1}
-------------------
G |-# T1 <: y.B
``````

By (has member inversion), there exists a type `T` such that `G |-! y: {B: T..T}` and `G |-# x: T has A: S2..U2`. By (Unique tight bounds), `T = T1`, which proves the case.

Case (Sel-<:-tight). Then `T1 = y.B` and the last rule is:

``````                     G |-! y: {B: T2..T2}
-------------------
G |-# y.B <: T2
``````

By definition of (Has member), case (sel-has), the result follows.

Case (All-<:-All). Does not apply since `all(x:S)T` cannot appear in a `has` judgement.

### Lemma (Has member monotonicity)

If `G ~ s` and `s(x) = new(x: T0)d` and `G |-# x: T has A: S..U` then there exists a type `T1` such that `G |-# x: rec(x: T0) has {A: T1..T1}` and `G |-# S <: T1` and `G |-# T1 <: U`.

Proof: By induction of `G |-# x: T`.

Case (Var). Then the last rule is

``````                     G, x: T, G' |- x: T
``````

Since `G ~ s`, `T = rec(x: T0)`. By (Has member tightness), there is a type `T1` such that `S = T1` and `U = T1`.

Case (Sub). Then the last rule is:

``````                 G |-# x: T2   G |-# T2 <: T
---------------------------
G |-# x: T
``````

By (Has member covariance) there are types `S1`, `U1` such that `G |- x: T2 has A: S1..T1` and `G |- S <: S1` and `G |- U1 <: U`. By the I.H. there exists a type `T1` such that `G |- x: rec(x: T0) has {A: T1..T1}` and `G |- S <: T1` and `G |- T1 <: U1`. By (Trans) `G |- S <: T1` and `G |- T1 <: U`.

Case (Rec-I). Then `T = rec(x: T')` and the last rule is:

``````                         G |-# x: T'
------------------
G |-# x: rec(x: T')
``````

By (Has member inversion), `G |-# x: T' has A: S..U`. By the I.H., there exists a type `T1` such that `G |-# x: rec(x: T0) has {A: T1..T1}` and `G |-# S <: T1` and `G |-# T1 <: U`.

Case (Rec-E). Then the last rule is:

``````                      G |-# x: rec(x: T)
-----------------
G |-# x: T
``````

By (has-rec), `G |-# x: rec(x: T) has A: S..U`. By the I.H. there exists a type `T1` such that `G |-# x: rec(x: T0) has {A: T1..T1}` and `G |-# S <: T1` and `G |-# T1 <: U`.

Case (&-I). Then `T = T1 & T2` and the last rule is:

``````                  G |-# x: T1   G |-# x: T2
-------------------------
G |- x: T1 & T2
``````

By (Has member inversion), there exists `i in {1,2}` such that `G |-# x: Ti has A: S..U`. By the I.H. there exists a type `T1` such that `G |- x: rec(x: T') has {A: T1..T1}` and `G |- S <: T1` and `G |- T1 <: U`.

### Lemma (Tight bound completeness)

If `G ~ s` and `s(x) = new(x: T)d` and `G |-# x: {A: S..U}` then `G |-# x.A <: U` and `G |-# S <: x.A`.

Proof: Since `G |-# x: {A: S..U}`, we have also `G |-# x: {A: S..U} has A: S..U`. By (Has member monotonicity), there exists a type `T1` such that `G |-# x: rec(x: T) has {A: T1..T1}` and `G |-# S <: T1` and `G |-# T1 <: U`. By (Has member inversion, case 3), `G |-# x: T has A: T1..T1`. By (Corresponding Definition Types) `T` is of the form `S1 & ... & Sn` where each `Si` is of the form `{A: Ti..Ti}` or `{a: Ti}`. By (Has member inversion, case 2), there must exist a `Si` such that `G |- x: Si has A: T1..T1`. By (Has member inversion), `Si = {A: T1..T1}`. By Definition of (|-!), `G |-! x: {A: T1..T1}`. By definition of (Sel-<:-tight) and (<:-Sel-tight), `G |-# x.A <: T1` and `G |-# T1 <: x.A`. By (Trans) `G |-# x.A <: U` and `G |-# S <: x.A`.

### Lemma (All-I Inversion)

If `G |-! lambda(x: S)t: U` then `U = all(x: S)T` for some type `T` such that `G, x: S |- t: T`.

### Lemma ({}-I Inversion)

If `G |-! new(x: T)(d1 & ... & dn): U` then `U = rec(x: T)` and `T` is of the form `S1 & ... & Sn`, where each `Si` corresponds to exactly one definition `di` in the following way:

• if `di = {a = t}` then `Si = {a: T'}` for some `T'` such that `G |- t: T'`.
• if `di = {A = T}` then `Si = {A: T..T}`.

### Definition (Possible types)

For a variable `x`, value `v`, environment `G`, the set `Ts(G, x, v)` of possible types of `x` defined as `v` in `G` is the smallest set `SS` such that:

1. If `v = new(x: T)d` then `T` in `SS`.
2. If `v = new(x: T)d` and `{a = t}` in `d` and `G |- t: T'` then `{a: T'} in SS`.
3. If `v = new(x: T)d` and `{A = T'}` in `d` and `G |- S <: T'`, `G |- T' <: U` then `{A: S..U} in SS`.
4. If `v = lambda(x: S)t` and `G, x: S |- t: T` and `G |- S' <: S` and `G, x: S' |- T <: T'` then `all(x: S')T' in SS`.
5. If `S1 in SS` and `S2 in SS` then `S1 & S2 in SS`.
6. If `S in SS` and `G |-! y: {A: S..S}` then `y.A in SS`.
7. If `T in SS` and then `rec(x: T) in SS`.
8. `Top` in `SS`.

### Lemma (Tight possible types closure)

If `G ~ s` and `s(x) = v` then `Ts(G, x, v)` is closed wrt `G |-# _ <: _`.

Proof: Let `SS = Ts(G, x, v)`. We show `SS` is closed wrt `G |-# _ <: _`.

Assume `T0 in SS` and `G |- T0 <: U0`. We show `U0 in SS` by an induction on subtyping derivations of `G |-# T0 <: U0`.

Case (<:-Top). Then `U0 = Top`. By (rule 8), `Top` in `SS`.

Case (Bot-<:). Does not apply, since assumption `T0 in SS` cannot hold when `T0 = Bot`.

Case (Refl-<:). Then `U0 = T0` hence `U0 in SS`.

Case (Trans-<:). Then last last rule is:

``````                      G |- T0 <: S   G |- S <: U0
---------------------------
G |- T0 <: U0
``````

Then by the I.H. (twice), `S in SS` and `U0 in SS`.

Case (And-<:). Then `T0 = U0 & S` or `T0 = S & U0` for some type `T`. Assume the first alternative, the second is analogous. The only ways a type `T & U` can be part of set `SS` is through rule (1) or (5). If `T0` is part of `SS` through rule (1), then `v = new(x: T0)d`, for some definitions `d`. By (Corresponding Definition Types) `T0` is of the form `S1 & ... & Sn` where each `Si` corresponds to an atomic definition in `d`, and `U0` is the intersection of some subset of the `Si` types. By rule (2) and (3) each of the `Si` types is in `SS`. Hence by applying rule (5) as often as necessary, `U0 in SS`. If `T0` is part of `SS` because of rule (5), `U0` and `S` must both be in `SS`.

Case (<:-And). Then `U0 = T & U` and `G |- T0 <: T`, `G |- T0 <: U`. By the I.H. `T` and `U` are in `SS`. Hence, with rule (5), `U0 in SS`.

Case (Fld-<:-Fld). Then `T0 = {a: T1}` and `U0 = {a: U1}` for types `T1`, `U1` such that `G |- T1 <: U1`. The only way `T0` can be in `SS` is through rule (2), or rule (1) convertible to rule (2) by `G ~ s`. That is, `v = new(x: T)d` and `{a = t}` in `d` and `G |- t: T1`. Since `G |- T1 <: U1` we get with (Sub) that `G |- t: U1`. With rule (2), `U0 in SS`.

Case (Typ-<:-Typ) Then `T0 = {A: T1..T2}` and `U0 = {A: U1..U2}` for types `T1`, `T2`, `U1`, `U2` such that `G |- U1 <: T1` and `G |- T2 <: U2`. The only way `T0` can be in `SS` is through rule (3) or rule (1) convertible to rule (3) by `G ~ s`. That is, `v = new(x: T)d` and `{A = T'}` in `d` and `G |- T1 <: T'`, `G |- T' <: T2`. With (Trans), `G |- U1 <: T'` and `G |- T' <: U2`. With rule (3), `U0 in SS`.

Case (<:-Sel-tight). Then `U0 = y.A` for some `y` such that `G |-! y: {A: T0..T0}`. With rule (6), `U0 in SS`.

Case (Sel-<:-tight) Then `T0 = y.A` for some `y` such that `G |-! y: {A: U0..U0}`. The only way `y.A` can be in `SS` is through rule (6). That is, there is a type `S in SS` such that `G |-! y: {A: S..S}`. By (Unique tight bounds), `U0 = S`, hence `U0 in SS`.

Case (All-<:-All). Then `T0 = all(y: T1)T2` and `U0 = all(y: U1)U2` for some `T1`, `U1` such that `G |- U1 <: T1` and for some `T2`, `U2` such that `G, y: U1 |- T2 <: U2`. The only way `T0` can be in `SS` is through rule (4). That is, `v = lambda(x: T)d` and `G |- T1 <: T` and `G, x: T1 |- t: T2`. By (Narrowing), `G, x: U1 |- t: T2`. With (Sub), `G, x: U1 |- t: U2`. With (Trans), `G |- U1 <: T`. With rule (4), `all(x: U1)U2 in SS`.

This concludes the induction. Therefore, `SS` is closed wrt `G |-# _ <: _`.

### Lemma (Possible types completeness for values)

If `G ~ s` and `x = v in s` and `G |-! v: T` then `T in Ts(G, x, v)`.

Proof. Assume first that `v = new(x: S)d`. By the definition `|-!`, the proof of `G |-! v: T` must end in a `{}-I` rule. By ({}-I Inversion), `T = rec(x: S)`. By rule (1) of (Possible Types), `S in Ts(G, x, v)`. By rule (7) of (Possible Types), `rec(x: S) in Ts(G, x, v)`.

Assume now that `v = lambda(x: S)t`. By the definition `|-!`, the proof of `G |-! v: T` must end in a `All-I` rule. By (All-I Inversion), `U = all(x: S)T` for some type `T` such that `G, x: S |- t: T`. By rule (4) of (Possible Types), `all(x: S)T in Ts(G, x, v)`.

### Lemma (Tight possible types completeness)

If `G ~ s` and `x = v in s` and `G |-# x: T` then `T in Ts(G, x, v)`.

Proof: By induction on the derivation of `G |-# x: T`. The derivation of `G |-# x: T` must end in one of the following cases:

Case (Var). Since `G ~ s`, `G` contains a binding `x: T` such that `G |-! v: T`. By (Possible types completeness for values), `T in Ts(G, x, v)`.

Case (Rec-I). Then the last rule is:

``````                              G |-# x: T
-----------------
G |-# x: rec(x: T)
``````

By the I.H., `T in Ts(G, x, v)`. By rule (7) of (Possible Types), `rec(x: T) in Ts(G, x, v)`.

Case (Rec-E). Then the last rule is:

``````                          G |-# x: rec(x: T)
-----------------
G |-# x: T
``````

By the I.H., `rec(x: T) in Ts(G, x, v)`. The only way a `rec` type can be in `Ts(G, x, v)` is through rule (7). Hence, `T in Ts(G, x, v)`.

**Case (&-I). Then the last rule is:

``````                        G |-# x: T   G |-# x: U
---------------------
G |-# x: T & U
``````

By the I.H., `T in Ts(G, x, v)` and `U in Ts(G, x, v)`. By rule (5) of (Possible Types), `T & U in Ts(G, x, v)`.

Case (Sub). Then the last rule is:

``````                       G |-# x: T   G |-# T <: U
-----------------------
G |-# x: U
``````

By the I.H., `T in Ts(G, x, v)`. By (Tight possible types closure), `U in Ts(G, x, v)`.

### Lemma (Equivalence of `G |- ...` and `G |-# ...`)

`G |-# ...` to `G |- ...` is straightforward by mutual induction on typing and subtyping derivations.

For `G |-# ...` to `G |- ...`, all cases are straightforward by mutual induction except tightening subtyping of type selections. We can use (Tight bound completeness), provided we can show that `G |-# x : {A:S..U}` implies that `s(x) = new(x: T)d` for some `T` and `d`, given also `G ~ s`. Since `G ~ s`, we know that `s(x) = v` for some `v`. By (Tight possible types completeness), `{A:S..U} in Ts(G, x, v)`. By inversion, `v` must have of the form `new(x: T)d` for some `T` and `d`.

### Lemma (Possible types closure)

If `G ~ s` and `s(x) = v` then `Ts(G, x, v)` is closed wrt `G |- _ <: _`.

Proof: By (Tight possible types) and (Equivalence of `G |- _ <: _` and `G |-# _ <: _`).

### Lemma (Possible types completeness)

If `G ~ s` and `x = v in s` and `G |- x: T` then `T in Ts(G, x, v)`.

Proof: By (Tight possible types completeness) and (Equivalence of `G |- _ : _` and `G |-# _ : _`).

### Lemma (Possible types)

If `G ~ s` and `G |- x: T` then, for some value `v`, `s(x) = v` and `T in Ts(G, x, v)`.

Proof: If `G |- x: T`, `x` must be bound in `G`. Since `G ~ s` there must be a value `v` such that `s |= x = v`. By (Possible types completeness), `T in Ts(G, x, v)`.

### Lemma (Canonical forms 1)

If `G ~ s` and `G |- x: all(x: T)U` then `s(x) = lambda(x: T')t` where `G |- T <: T'` and `G, x: T |- t: U`.

Proof: Since `x` has a type in `G`, `x` must be bound in `G`, say `G = G1,x:S,G2`. Since `G ~ s` there exists a value `v` such that `x = v` in `s` and `G1 |- v:S`. By (Possible Types), `v` cannot be a new because `all(x: T)U` is not in `T(G, x, v)` if `v` is a `new`. So `v` must be of the form `lambda(x: T')t`. Again by (Possible Types) the only way an `x` defined as a `lambda(x: T')t` can have a type `all(x: T)U` is if, for some `U0`, `G |- T <: T'`, `G, x: T' |- t: U0` and `G, x: T |- U0 <: U`. By (Sub) and (Narrowing), `G, x: T |- t: U`.

### Lemma (Canonical forms 2)

If `G ~ s` and `G |- x: {a: T}` then `s(x) = new(x: S)d` for some type `S`, definition `d` such that `G |- d: S` and `d` contains a definition `{a = t}` where `G |- t: T`.

Proof: Since `x` has a type in `G`, `x` must be bound in `G`, say `G = G1,x:S,G2`. Since `G ~ s` there exists a value `v` such that `x = v` in `s` and `G1 |- v:S`. By (Possible Types) `v` cannot be a lambda because `{a: T}` is not in `T(G, x, v)` if `v` is a `lambda`. So `v` must be of the form `new(x: S)d`. Again by (Possible Types) the only way an `x` defined as `new(x: S)d` can have a type `{a: T}` is if there is a definition `{a = t}` in `d` and `G |- t: T`.

### Theorem (Preservation)

If `G |- t: T` and `G ~ s` and `s | t -> s' | t'`, then there exists an environment `G''` such that, letting `G' = G, G''` one has `G' |- t': T` and `G' ~ s'`.

### Theorem (Progress)

If `G |- t: T` and `G ~ s` then either

• `t` is a normal form, or
• `s | t -> s' | t'`, for some store `s'`, term `t'`.

Proof: We prove both theorems together. To be shown:

Let `G |- t: T` and `G ~ s`. Then either

• `t` is a normal form, or
• there exists a store `s'`, term `t'` such that `s | t -> s' | t'`, and for any such `s'`, `t'` there exists an environment `G''` such that, letting `G' = G, G''` one has `G' |- t': T` and `G' ~ s'`.

The proof is by a induction on typing derivations of `G |- t: T`.

If the last rule is one of (Var), (All-I), ({}-I), (Rec-I), (Rec-E), (&-I), `t` is a normal form and the result follows immediately.

Case (All-E): Then the last rule is:

``````                   G |- x: all(z: S)T    G |- z: S
-------------------------------
G |- x y: [z:=y]T
``````

Since `G ~ s`, `G |- s(x): all(z: S)T`. By (Canonical forms 1), `s(x) = lambda(z: S')t` where `G |- S <: S'` and `G, z: S |- t: T`. By (Apply), `s | x y -> s | [z:=y]t`. By (Subst), G |- [z:=y]t: [z:=y]T.

Case ({}-E): Then the last rule is:

``````                            G |- x: {a: T}
--------------
G |- x.a: T
``````

Since `G ~ s`, `G |- s(x): {a: T}`. By (Canonical forms 2), `s(x) = new(y: S)d` for some binding `y = new(y: S)d`, such that `G |- d: S` and `d` contains a definition `{a = t}` where `G |- t: T`. By (Project) `s | x.a -> s | t`, which proves the case.

Case (Let): Then the last rule is:

``````            G |- t: T   G, x: T |- u: U   (x not in fv(U))
----------------------------------------------
G |- let x = t in u: U
``````

we distinguish according to whether `t` is a value, variable, or general term.

If `t = v` for some value `v`, then by (Let-Value), `s | let x = v in t --> s, x = v | t`. Inspection of the type assignment rules shows that any typing of a `lambda` must contain an (All-I) rule, which can only be followed by (Sub) steps. Similarly, the typing of a `new` must contain a ({}-I) rule, which can be only followed by subsumption steps. Let `T'` be the type obtained for `v` by the (All-I) or ({}-I) rule and let `D` be the (possibly empty) sequence of subsumption steps that follows it. Applying a (Var) step on `x` and following with `D` gives a derivation of `G, x: T' |- x: T`. This means `G, x: T' <: G, x: T`. By (Narrowing), `G, x: T' |- u: U`. Furthermore, by the construction of `T'`, `G |-! v: T'`, hence `G, x: T' ~ s, x = v`.

If `t = y` for some variable `y`, then by (Let-Var) `s | let x = y in t --> s | [x:=y]t`. The preconditions of the last rule are then: `G |- y: T` and `G, x: T |- u: U` and `x not in fv(U)`. Furthermore, since `fv(T) <= dom(G)` and `x not in dom(G)`, `x not in fv(T)`. It follows with (Subst) that `[x:=y]t: [x:=y]U`. Since `x not in fv(U)`, `[x:=y]U = U`, which proves the case.

If `t` is not a value nor a variable, then by the induction hypothesis there exist `s'`, `t'` such that `s | t -> s' | t'` and for any such `s'`, `t'` there exists an environment `G' = G, G''` such that `G' |- t': T` and `G' ~ s'`. By (Weakening) `G, G'', x: T |- u: U`. Hence, by (Let), `G' |- let x = t' in u: U`.

Case (Sub): Then the last rule is:

``````                       G |- t: T   G |- T <: U
-----------------------
G |- t: U
``````

If `t` is a value, the result follows immediately. Assume now that `t` is not a value. By the induction hypothesis there exist `s'`, `t'` such that `s | t -> s' | t'` and for any such `s'`, `t'` there exists an environment `G' = G, G''` such that `G' |- t': T` and `G' ~ s'`. By (Weakening, 2nd clause), `G' |- T <: U`. Then by (Sub) it follows that `G' |- t: U`.