• No results found

Relation between syntactic substitution and semantic evaluation

the prestate of that instruction. This is done in Lemma 6.4.4. We use here an induction over the number of execution steps made in the execution path. The induction case uses Lemma 6.4.3.

Lemma 6.4.3 shows that if in an execution path the preconditions calculated by wp for the instructions in the path are such that the respective precondition holds in the prestate of the respective instruction then either the respective normal or exceptional method postcondition holds or if another execution step can be made then the weakest precondition of the next instruction holds. This is also known as a subject reduction property. The latter lemma is may be the most complicated one as it uses the argument of the reducibility of the execution graph (Section 3.9, Def. 3.9.1). The lemma has three cases:

• the case where the next instruction is not a loop entry instruction. In this case the proof is standard and uses the single step soundness ofwp.

• the case when the next instruction is a loop entry instruction and the current instruction is not a loop end. In this case, we use the single step soundness ofwp as well the special form of the precondition of the current instruction.

• the case where the next instruction is a loop entry and the current is a loop end instruction (see Def. 3.9.1). In this case, we use the reducibility of the control flow graph which gives us that the execution path has a prefix subpath which passes through the loop entry instruction but not through the current loop end instruction. This fact allows us to conclude that also in that case the Lemma 6.4.3 holds

What we mean by single step soundness of thewp function is that if the predicate calculated bywp for an instruction holds in its prestate then the postcondition upon which the precondition is calculated holds in its poststate (Lemma 6.4.2). The argument for the single step soundness uses the relation between syntactic substitution and semantic evaluation which looks like:

[[E1[E2\E3]]]s1 = [[E1]]s1(⊕[[E2]]s1→[[E3]]s1)

This equivalence is standardly used for establishing the soundness of predicate transformer function w.r.t. a program semantics and means that it does not matter if we use a syntactic substitution over the expression and evaluate the resulting expression or update the state and evaluate the original expression. The next section is dedicated to the relation between substitution and evaluation.

Note that we do the proof under several assumptions. The first one is that the bytecode has passed the bytecode verification. This guarantees that when the bytecode is executed every instructions gets from the operand stack values of the expected type. This assumption liberates of us from the obligation to make type checks in the verification condition generator. Next, we assume that the control flow graph of a method is reducible, or in other words there are no cycles in the graph with two entries. This means that if program have cycles then they should conform to Def. 3.9.1 from Section 3.9. As we shall in the following, control flow graph reducibility plays an important role in the proof of soundness of the verification condition generator. Note that this restriction (as we said earlier) is realistic as every non-optimizing Java compiler produces reducible control flow graphs and even hand written code is usually reducible.

6.3

Relation between syntactic substitution and semantic

evaluation

In this section, we will show what is the relation between the syntactic notion of substitution and the semantic notion of evaluation. Particularly, we shall see that they commute. As an intermediate execution state< H,Cntr,St,Reg,Pc>is composed from several elements, a heap H, the stack counter Cntr , the operand stack St and the array of registers Reg, we shall state for each component a separate lemma. In the following, we shall sketch the proof only of those lemmas, that we consider representative the others having a similar proof.

Let us now look at the next formal statement. It refers to the fact that if we substitute in an expression E1 the expression reg(i) which represents the local variable at index i with another

expressionE2 and evaluate the resulting expression in a state s1 we will get the same value if we

evaluateE1in the states1(⊕Reg(i)→[[E2]]s1).

Lemma 6.3.1 (Update a local variable). For any expressions E1,E2if we have that the states

s1 ands2 are such that s1=<H,Cntr,St,Reg,Pc>, s2=<H,Cntr,St,Reg(⊕i→[[E2]]s1),Pc>

andi is a valid index in the array of method registerRegthen the following holds: 1. [[E1[reg(i)\E2]]]s1 = [[E1]]s2

2. s1ψ[reg(i)\E2] ⇐⇒ s2ψ

Proof

1. we look at the first part of the lemma concerning expression evaluation. It is by structural induction on the structure ofE1. We look only at the simple case whenE1 =reg(i). The

other cases proceed in a similar way. [[reg(i)[reg(i)\E2]]]s1 =

{ apply substitution }

[[E2]]s1 =

{ evaluation of local variables and by the initial hypothesis for s2 }

[[reg(i)]]s2

2. second case of the lemma. It is by induction on the structure of the formulaψ. We sketch the case whenψ=E1 RE2

s1(E1 RE2)[reg(i)\E2] = { apply substitution}

s1E1[reg(i)\E2]RE2[reg(i)\E2] = { interpretation of formulas }

[[E1[reg(i)\E2]]]s1 R[[E2[reg(i)\E2]]]s1 =

{ from the first part of the lemma and the initial hypothesis fors2 we get }

[[E1]]s2 R[[E2]]s2 =

{ from definition of formula interpretation in a state}

s2E1 RE2

Lemma 6.3.2 (Update of the heap). For any expressions E1,E2,E3and any fieldfif we have

that the states s1 ands2 are such that the evaluation of E1 [[E2]]s1 is different fromnull and the

evaluation of E3 is either an instance in the heap or of typeint,s1=<H,Cntr,St,Reg,Pc>,and

s2=<H(⊕f→f(⊕[[E2]]s1 →[[E3]]s1)),Cntr,St,Reg,Pc>the following holds

1. [[E1[f\f(⊕E2→E3)]]]s1= [[E1]]s2

2. s1ψ[f\f(⊕E2→E3)] ⇐⇒ s2ψ

Proof

We sketch only the first part of the lemma, the second part is by structural induction as in the previous lemma, second case.

1. By structural induction on the structure ofE1. We look at the case whenE1=E2.f

[[E2.f[f\f(⊕E2→E3)]]]s1 =

{ apply substitution over fields as described in subsection 2.4.1 page 19 }

[[E2.f(⊕E2→E3)]]s1 =

{ simplify the expression as in subsection 2.4.1 page 19 }

[[E3]]s1 =

{ evaluation of field access expression and by the initial hypothesis for s2 }

6.3 Relation between syntactic substitution and semantic evaluation 85

Lemma 6.3.3 (Update of the heap with a newly allocated object). For any expressions E1 if we have that the states s1 and s2 are such that s1 =< H,Cntr,St,Reg,Pc > and s2 =<

H0,Cntr,St(⊕Cntr→[[ref]]s1),Reg,Pc>where newRef(H,C) = (H0,ref)the following holds

1.

[[E1[st(cntr)\ref][f\f(⊕ref→defVal(f.Type))]subtype(f.declaredIn, C)

f ]]s1

= [[E1]]s2

2.

s1ψ[st(cntr)\ref][f\f(⊕ref→defVal(f.Type))]subtype(

f.declaredIn,C) f

⇐⇒

s2ψ

Proof

We sketch only the first part of the lemma, the second part is by structural induction as in the first lemma, second case.

1. By structural induction on the structure ofE1. We look at the case whenE1 =st(cntr).g

where the fieldgis declared in classC.

[[st(cntr).g[st(cntr)\ref][f\f(⊕ref→defVal(f.Type))]subtypef (f.declaredIn,C)]]s1 =

{ applying the first substitution over st(cntr).g }

[[ref.g[f\f(⊕ref→defVal(f.Type))]subtypef (f.declaredIn,C)]]s1 =

{as by initial hypothesisgis declared in class C the series of substitutions over the fields declared in any subtype of C results in }

[[ref.g(⊕ref→defVal(g.Type))]]s1=

{ simplify the field update expression }

[[defVal(g.Type)]]s1 =

{by initial hypothesis about the states2 and definition of the functionnewRef(H,C)

in section 3.4.1 we get }

[[st(cntr).g]]s2

Lemma 6.3.4 (Update the stack). For any expressions E1,E2,E3if we have that the statess1

ands2are such thats1=<H,Cntr,St,Reg,Pc>ands2=<H,Cntr,St(⊕[[E2]]s1 →[[E3]]s1),Reg,Pc>

then the following holds:

1. [[E1[st(E2)\E3]]]s1 = [[E1]]s2

2. s1ψ[st(E2)\E3] ⇐⇒ s2ψ

Lemma 6.3.5 (Update the stack counter). For any expressions E1,E2 if we have that the

statess1 and s2 are such that s1 =<H,Cntr,St,Reg,Pc>, s2 =<H,[[E2]]s1,St,Reg,Pc> then

the following holds:

1. [[E1[cntr\E2]]]s1 = [[E1]]s2

2. s1ψ[cntr\E2] ⇐⇒ s2ψ

Lemma 6.3.6 (Return value property). For any expression E1and E2, for any two statess1

ands2 such thats1=<H,Cntr,St,Reg,Pc>,s2=<H,[[E2]]s1 >

normthen the following holds:

1. [[E1[result\E2]]]s1 = [[E1]]s2