• No results found

Chapter 6 Formal Language for Determinism by Default

6.2 Simplified Deterministic Language

6.2.1 Static Semantics

The typing is with respect to an environmentΓ, which is a possibly empty union of elements (v, T ) stating that variablev has type T :

Γ ::= ∅ | (v, T ) | Γ ∪ Γ

Chapter 4, except that in this simplified language there are no commutativity annotations. ⊢ P PROGRAM ∀C.(⊢ C) ∅ ⊢ e : T, E ⊢ C∗ e ⊢ C CLASS Γ = (this, C<ρ>) ∀F.(Γ ⊢ F ) ∀M.(Γ ⊢ M ) ⊢classC<ρ>{ F∗M∗} Γ ⊢ F FIELD Γ ⊢ T Γ ⊢ R Γ ⊢ T finR Γ ⊢ M METHOD Γ ⊢ Tr Γ ⊢ Tx Γ ⊢ E Γ ∪ (x, Tx) ⊢ e : Tr, E′ Γ ⊢ E′ ⊆ E Γ ⊢ Trm(Txx) E { e }

Regions and Types: The rules for valid regions and types are simplified from Chapter 4. There are no rules

for subtyping in the static semantics, because in this simplified language, we require identity of types at assignments. Γ ⊢ R REGION-NAME regionr ∈ P Γ ⊢ r REGION-PARAM (this, C<ρ>) ∈ Γ Γ ⊢ ρ Γ ⊢ T TYPE classC<ρ>{ F∗M} ∈ P Γ ⊢ R Γ ⊢ C<R>

Valid effects: The rules for valid effects, subeffects, and noninterfering effects are also a subset of the rules

from Chapter 4. Again, the subeffect relation is reflexive and transitive, and the noninterference relation is symmetric (obvious rules omitted).

Γ ⊢ E EFFECT-EMPTY Γ ⊢ ∅ EFFECT-READS Γ ⊢ R Γ ⊢readsR EFFECT-WRITES Γ ⊢ R Γ ⊢writesR EFFECT-UNION Γ ⊢ E Γ ⊢ E′ Γ ⊢ E ∪ E′ Γ ⊢ E ⊆ E′ SE-EMPTY Γ ⊢ ∅ ⊆ E

SE-READS-WRITES

Γ ⊢readsR ⊆writesR SE-UNION-1 Γ ⊢ E ⊆ E′ Γ ⊢ E ⊆ E′∪ E′′ SE-UNION-2 Γ ⊢ E′⊆ E Γ ⊢ E′′⊆ E Γ ⊢ E′∪ E′′⊆ E

Γ ⊢ E # E′ NI-EMPTY Γ ⊢ ∅ # E NI-READS Γ ⊢readsr #readsr′ NI-WRITES r 6= r′ Γ ⊢writesr #writesr′

NI-READS-WRITES

r 6= r′ Γ ⊢readsr #writesr′ NI-UNION Γ ⊢ E # E′′ Γ ⊢ E# E′′ Γ ⊢ E ∪ E′ # E′′

Expressions: As in Chapter 4, every expression has a type and an effect. The judgmentΓ ⊢ e : T, E means that expressione is well typed with type T and effect E in environment Γ.

Basic operations from Chapter 4: Field access and assignment, method invocation, variable access, and new objects all work the same way as described in Chapter 4. There are no arrays or letexpressions in this language. Γ ⊢ e : T, E FIELD-ACCESS (this, C<ρ>) ∈ Γ F (C, f ) = T finR Γ ⊢this.f : T,readsR FIELD-ASSIGN (this, C<ρ>) ∈ Γ Γ ⊢ e : T, E F (C, f ) = T finR Γ ⊢this.f=e : T, E ∪writesR INVOKE Γ ⊢ e : C<R>, E Γ ⊢ e′ : σ C<R>(Tx), E′ M (C, m) = Trm(Txx) Em{ e′′} Γ ⊢ e.m(e′ ): σC<R>(Tr), E ∪ E′∪ σC<R>(Em) VARIABLE (v, T ) ∈ Γ Γ ⊢ v : T, ∅ NEW Γ ⊢ T Γ ⊢newT : T, ∅

In rule INVOKE, the substitutionσC<R>substitutesR for the region parameter ρ of class C. Sequential composition: To type a sequential composition expressionseq(e,e′

), we type the component expressionse and e′

. The type of the expression is the typeT′

ofe′

. The effect is the union of the effectsE andE′ ofe and e′ . Γ ⊢ e : T, E SEQ Γ ⊢ e : T, E Γ ⊢ e′: T′, E′ Γ ⊢seq(e,e′ ): T′, E ∪ E

Deterministic parallel composition: Typing deterministic parallel composition cobegin(e,e′

) is the same as for sequential composition, except that we require the effects ofe and e′

to be noninterfering.

Γ ⊢ e : T, E COBEGIN Γ ⊢ e : T, E Γ ⊢ e′ : T′, E′ Γ ⊢ E # E′ Γ ⊢cobegin(e,e′

): T′, E ∪ E

6.2.2 Dynamic Semantics

Execution Environment: We extend the static expression syntax (Section 6.1), to represent computations.

In addition to an expression from the static syntax, an expression can also be an object reference o; or a local execution state (e, Σ, E), where Σ is a dynamic environment (defined below); or ei, wherei is a

unique identifier:

e ::= . . . | o | (e, Σ, E) | ei

The additional expressions have the following meanings:

• Object references o are the values produced by reducing expressions.

• A local execution state (e, Σ, E) records an expression e to evaluate, an environment Σ containing the bindings for the free variables ine, and the effect E of reducing e.

• The identifiers i are “tags” that allow us to refer unambiguously to subexpressions that are undergoing reduction.

Reducing local execution state “in place” allows us to retain the recursive structure of an execution history, as opposed to, e.g., flattening everything into threads. This in turn makes it easier to state and prove the desired properties of the execution.

As in Chapter 4, we define a dynamic environmentΣ that maps variables v to references o:

Σ ::= ∅ | (v, o) | Σ ∪ Σ

An objectO is a mapping from field names f to object references o:

A heapH is a partial function from object references o to pairs (O, T ), where O is an object, and T is the type ofO:

H ::=null| o 7→ (O, T ) | H ∪ H

nullis a special reference that is inDom(H) but does not map to an object. Attempting to invoke a method ofnullcauses the execution to fail.

Program Execution: We describe program execution as a small-step operational semantics. The execution

state is(e, H), consisting of an expression to evaluate and a heap. Program execution is defined by the transition relation

(e, H) → (e′, H′).

Informally, a single step transforms an expression into another expression and updates the heap. The rules defining this relation are stated below. Formally, ifP = C∗e

P, then an execution of programP is given by

((eP, ∅, ∅)i,null) →∗ (ei, H),

for somei, ei, andH, where i is an arbitrary index denoting the top-level expression in the reduction, eiis

the evolution of expression(eP, ∅, ∅)i, andH is the evolved heap (represented as a domain containingnull

plus all object referenceso added during the execution). A terminating execution has ei = (o, ∅, E)i, where

o is the “answer” computed by the program, and E is the union of all effects on H done in the execution.

Operational Semantics of Expressions: First, we need a standard rule for evaluating subexpressions:

DYN-SUBEXP (e, H) → (e′, H) (e′′ , H) → (e′′ [ei← e′i], H ′ )

Rule DYN-SUBEXP says that if we know how to evaluate expressione to e′

with respect to heap H, and e appears as a subexpression of e′′

with indexi, then we can reduce e′′

by rewriting the subexpressionei

in place and updating the heap. Because there are in general several subexpressionseithat are eligible for

rewriting in this way, we use the indicesi to identify which one is being reduced. The choice of which one to reduce next is, in general, nondeterministic.

Next we give the rules for evaluating local state expressions (e, Σ, E). For expressions with nontriv- ial subexpressions, we (1) convert the subexpressions e′

of e into the form (e′

, Σ′

, ∅)i, wherei is a fresh

identifier; (2) evaluate the subexpressions to(o, Σ′

, E)iusing rule DYN-SUBEXP; and (3) use the results to

finish evaluating the main expressione. Notice that in the subexpression evaluation, e′

evaluates too, Σ′

is unchanged, and the effect changes from∅ to some effect E. An expression reduction always starts out as (e, Σ, ∅), where e is an expression in the program text; goes through various transformations; and ends up as(o, Σ, E), where o is an object reference, and E collects the effects of the reduction.

Field access: For field access this.f, we read the value of field f out of the heap and record the read effect:

DYN-FIELD-ACCESS

(this, o) ∈ Σ H(o) = (O, C<r>) F (C, f ) = T f inR

((this.f , Σ, ∅), H) → ((O(f ), Σ,readsσC<r>(R)), H)

In computing the effect, rule DYN-FIELD-ACCESSuses the substitutionσC<r>defined in Section 6.2.1. Field assignment: For field assignment this.f=e, we evaluate e, then update the heap and record the write effect:

DYN-FIELD-ASSIGN-EVAL fresh(i)

((this.f=e, Σ, ∅), H) → (this.f=(e, Σ, ∅)i, H) DYN-FIELD-ASSIGN-UPDATE

(this, o) ∈ Σ H(o) = (O, C<r>) F (C, f ) = T f inR

((this.f=(o′, Σ, E)

i, H) → (o′, Σ, E ∪writesσC<r>(R), H[o 7→ (O[f 7→ o′], C<r>)])

fresh(i) means that i is a fresh identifier. f [a 7→ b] denotes the function identical to f everywhere on its

domain, except that it mapsa to b.

Method invocation: For method invocation e.m(e′

), we evaluate e to o, evaluate e′

to o′

, execute the method body in the environment with the correct method parameter bindings, and accumulate the results. The aggregate effect of the expression is the union of the effects of evaluating the two arguments and the

method body.

DYN-INVOKE-EVAL-THIS fresh(i) ((e.m(e′

), Σ, ∅), H) → ((e, Σ, ∅)i.m(e′), H)

DYN-INVOKE-EVAL-ARG fresh(j)

((o, Σ, E)i.m(e), H) → ((o, Σ, E)i.m((e, Σ, ∅)j), H)

DYN-INVOKE-EVAL-METHOD-BODY

H(o) = (O, C<r>) M (C, m) = Trm(Txx) Em{ e } fresh(k)

((o, Σ, E)i.m((o′, Σ, E′)j), H) → (((e, (this, o) ∪ (x, o′), ∅)k, Σ, E ∪ E′), H)

DYN-INVOKE-ACCUMULATE

(((o, Σ, E)i, Σ′, E′), H) → ((o, Σ′, E ∪ E′), H)

Notice that ife evaluates tonull, then DYN-INVOKE-EVAL-METHOD-BODY cannot be applied. This is

effectively a “null dereference.” We don’t model error state or exceptions explicitly; instead a null derefer- ence just means that we have reached a “stuck state,” such that no successful program execution including that state is possible. All of our soundness results (Section 6.2.3) are stated in terms of successful executions. Variable access: For variablesv, we just read the value out of the environment:

DYN-VARIABLE

(v, o) ∈ Σ

((v, Σ, ∅), H) → ((o, Σ, ∅), H)

New objects: Fornew we create a new object of the correct type, initialize its fields to null, and add a reference to the object to the heap:

DYN-NEW

o 6∈Dom(H) O = ∪f ∈fields(C)(f 7→null)

((newC<R>, Σ, ∅), H) → ((o, Σ, ∅), H ∪ o 7→ (O, σΣ,H(C<R>)))

σΣ,H is the following function that takes regions to regions, types to types, and effects to effects:

1. If(this, o) does not appear in Σ for any o, then σΣ,H is the identity function.

Note thatσΣ,H is undefined if(this,null) ∈ Σ, but it is obvious that this cannot happen.

Sequential composition: For sequential composition seq(e,e′

), we first evaluate e to o, and then we evaluate e′

too′

. We useo′

as the result of the whole expression (o is thrown away; the evaluation of e is only for its side effects). The aggregate effect of the expression is the union of the effects of executing each branch. DYN-SEQ-EVAL-FIRST fresh(i) ((seq(e,e′ ), Σ), H) → (seq((e, Σ, ∅)i,e′), H) DYN-SEQ-EVAL-SECOND fresh(j)

(seq((o, Σ, E)i,e), H) → (seq((o, Σ, E)i,(e, Σ, ∅)j), H)

DYN-SEQ-ACCUMULATE

(seq((o, Σ, E)i,(o′, Σ, E′)j), H) → ((o′, Σ, E ∪ E′), H)

Deterministic parallel composition: For deterministic parallel compositioncobegin(e,e′

), we evaluate e to o and e′

too′

“in parallel,” i.e., we allow the evaluation steps of the two expressions to be arbitrarily interleaved. For the accumulation step, again we useo′

as the result of the whole expression.

DYN-COBEGIN-EVAL

fresh(i) fresh(j) ((cobegin(e,e′

), Σ, ∅), H) → (cobegin((e, Σ, ∅)i,(e′, Σ, ∅)j), H)

DYN-COBEGIN-ACCUMULATE

(cobegin((o, Σ, E)i,(o′, Σ, E′)j), H) → ((o′, Σ, E ∪ E′), H)

Notice that all rule applications are deterministic (i.e., there is only one next rule to apply) except in the case ofcobegin. Note also that cobeginstill provides deterministic results, because the type system guarantees noninterference of heap accesses between the two branches. However, the actual sequence of steps in the execution is nondeterministic.

6.2.3 Soundness

Static Environments: A static environmentΓ is valid if its elements are valid with respect to itself:

ENV ∀(v, T ) ∈ Γ.Γ ⊢ T

⊢ Γ

Our first theorem says that typing a valid expression in a valid environment produces a valid type and effect:

Theorem 6.2.1 (Validity of static expression typing). If⊢ P and ⊢ Γ and Γ ⊢ e : T, E, then Γ ⊢ T and Γ ⊢ E.

Proof. By induction on the structure ofe, showing the result for each expression typing rule in Section 6.2.1. Base cases: FIELD-ACCESS: Follows from the typing of class fields in Section 6.2.1.

VARIABLE: Follows from⊢ Γ.

NEW: Follows from the condition of the rule.

Inductive cases: FIELD-ASSIGN: Follows from the induction hypothesis applied to the typing ofe, plus the same argument as for FIELD-ACCESS.

INVOKE: The induction hypothesis gives thatR, E, and E′

are valid. Rule METHODgives thatTrand

Emare valid in the environment in whichthisis bound toC<ρ>. But thenσC<R>(Tr) and σC<R>(Em)

are valid inΓ, because Γ ⊢ R, and σC<R>substitutesR for ρ. SEQ: Follows directly from the induction hypothesis. COBEGIN: Follows directly from the induction hypothesis.

Reference types: The execution state includes the null typeN , which is the type ofnull:

T ::= . . . | N

We also add rules for typing references:

H ⊢ o : T TYPE-OBJECT-REF o 7→ (O, T ) ∈ H H ⊢ o : T TYPE-NULL H ⊢null: N

And because we have a null type, we need simple rules for subtyping: Γ ⊢ T  T′ SUBTYPE-REFLEXIVE Γ ⊢ T  T SUBTYPE-NULL Γ ⊢ N  T

Heaps: A heap is valid if its elements are valid:

⊢ H HEAP-NULL H ⊢null HEAP-OBJECT-REF H ⊢ (O, T ) H ⊢ o 7→ (O, T ) HEAP-UNION ⊢ H ⊢ H′ ⊢ H ∪ H′

An object-type pair(O, C<r>) is valid if (1) C<r>is a valid type in the empty environment; and (2) for every fieldf of C, O(f ) is defined, its type is valid and a subtype of the static type of f , after substituting r for the parameter ofC:

H ⊢ (O, T )

OBJECT

∅ ⊢ C<r> ∀(T finR ∈fields(C)).(∅ ⊢ σC<r>(T ) ∧ H ⊢ O(f ) : T′∧ H ⊢ T′ σC<r>(T ))

H ⊢ (O, C<r>)

r is a region name. Notice that we check the dynamic type of an object or object field in the empty environ- ment, because all region parameters have been substituted away.

Dynamic environments: A dynamic environmentΣ is valid if all its elements are valid with respect to a heapH: H ⊢ Γ DYN-ENV-EMPTY H ⊢ ∅ DYN-ENV-ELT H ⊢ o : T H ⊢ (v, o) DYN-ENV-UNION H ⊢ Γ H ⊢ Γ′ H ⊢ Γ ∪ Γ′

Instantiation of environments: The judgmentH ⊢ Σ  Γ says that the dynamic environment Σ instanti- ates the static environmentΓ. That means the heap and both environments are valid; the variables appearing in both environments match; and the corresponding types in the environments match, after translation to the dynamic environment. Instantiation lets us use the static typing of expressions to infer that the dynamic

execution of those expressions is well-behaved.

The basic rule for instantiation just checks everything for validity and records the original dynamic environment to the left of the⊢. This makes the original dynamic environment available as we dissect it to compare it to the static environment element by element:

H ⊢ Σ  Γ

INSTANTIATE

⊢ Γ ⊢ H H ⊢ Σ Σ, H ⊢ Σ  Γ

H ⊢ Σ  Γ

Next we have the element-by-element rules:

Σ, H ⊢ Σ′  Γ INST-EMPTY Σ, H ⊢ ∅  ∅ INST-UNION Σ, H ⊢ Σ′ ΓΣ, H ⊢ Σ′′ Γ′′ Σ, H ⊢ Σ′∪ Σ′′ Γ∪ Γ′′ INST-ELT H ⊢ o : C′ <r> ∅ ⊢ C′ <r> σΣ,H(C<R>) Σ, H ⊢ (v, o)  (v, C<R>)

σΣ,H is the translation function defined in Section 6.2.2.

Execution state: The judgmentΓ ⊢ ((e, Σ, ∅), H) : T, E states that local execution state ((e, Σ, ∅), H) is valid with respect to static environmentΓ with type T and effect E. That means Σ instantiates Γ, and e is well typed inΓ with type T and effect E.

Γ ⊢ ((e, Γ), H) : T, E

STATE

H ⊢ Σ  Γ Γ ⊢ e : T, E

Γ ⊢ ((e, Σ, ∅), H) : T, E

Preservation of Type and Effect: In this section we prove that for successful executions, the static types

and effects of expressions computed according to Section 6.2.1 approximate the dynamic types and effects produced during actual execution according to Section 6.2.2. First we need some technical lemmas. Again, σΣ,H is the translation function defined in Section 6.2.2.

AssumeΣ instantiates Γ with respect to heap H. If region R is valid in Γ, then region σΣ,H(R) is valid

Lemma 6.2.2. IfH ⊢ Σ  Γ and Γ ⊢ R, then ∅ ⊢ σΣ,H(R). The same result holds replacing R with T or

E.

Proof. For regions, the result is obvious unless R is a region parameter ρ. But in that case, we must have thisbound toC<ρ>inΓ andthisbound too in Σ, where H ⊢ o : C<r>for some valid region name r. (The last fact holds because ⊢ H implies H ⊢ o : T and ∅ ⊢ T , so T must be a class type with a region name for its region argument;o cannot benull.) Then σΣ,H substitutes r for ρ, so the result holds. For

types and effects, the result holds from the way that types and effects are constructed from regions. Again assumeΣ instantiates Γ in heap H. If effect E is included in E′

with respect toΓ, then effect σΣ,H(E) is included in σΣ,H(E′) with respect to the empty environment:

Lemma 6.2.3. IfH ⊢ Σ  Γ and Γ ⊢ E ⊆ E

, then∅ ⊢ σΣ,H(E) ⊆ σΣ,H(E′).

Proof. By the rules for unions of effects, it suffices to assume that E and E′

are both individual read or write effects. In that case, either reflexivity or rule SE-READS-WRITESmust apply, with the same regionR appearing in both effects. IfR is a region name r, then the result holds directly. If R is a region parameter ρ, then the result holds becauseσΣ,H substitutes the same region namer for the parameter in both effects.

Next we have the preservation result. Informally, if a program is well-typed and a local state expression (e, Σ, ∅) reduces to (o, Σ, E) starting with a good state, then the resulting heap is valid; the resulting type is valid and is a subtype of the static type ofe; E is valid; and E is a subeffect of the static effect of e. To