• No results found

Soundness for present types

The notion of soundness for present types is relatively straightforward. Given a derivation hs, Ti `p u : τ , we expect that the actual runtime type of the constant u after executing the current instruction in s to be a subtype of τ . This is formally expressed in the next theorem. Theorem 4.2. Consider the uninitialised state hΣ0, εi, which is executed n steps to yield an environmentΣ and a call stack S, i.e.,

0, εi→hΣ, Sin (4.3)

Suppose that this state is executed in a single step, hΣ, Si → hΣ0, S0i, to yield another state hΣ0, S0i. Let the inferred type τ

pof variableu be obtained by the judgement hs, T∅i `p u : τp, where s is a finite truncation of a stack S and T∅ is the empty trail, and letτr be the runtime type, i.e.,Σ0(u) : τr.

Then, the inferred type is an over-approximation of the runtime type, i.e.,

τr<: τp (4.4)

Proof. We proceed by induction on n.

Base case. For n = 0, we have hΣ, Si = hΣ0, εi, and hence s = ε. Since hΣ0, εi can only reduce to hΣI, hM, 0i :: εi in a single step, then hΣ0, S0i = hΣI, hM, 0i :: εi. Therefore, we need to show that (4.4) holds if we obtain our inferred type τp from hε, T∅i `p u : τp and our runtime type τrfrom ΣI(u) : τr. For hε, T∅i `pu : τpthe only possible rule used here is pINIT. By this rule, we conclude that τp = τr. This means that (4.4) holds since the subtype operator is reflexive.

Inductive case. We assume that the claim holds for some n > 0, i.e., when the inferred type τp of any variable u is obtained by the judgement hs, T∅i `p u : τp and the runtime type τr is obtained by the judgement Σ0(u) : τr.

We now show that the claim also holds for n+1. In particular, we consider the situation when the program hΣ0, S0i is executed a further step, i.e., hΣ0, S0i → hΣ00, S00i. In this case we obtain the inferred type using the judgement hs0, T∅i `p u : τp0 and the runtime type using the judgement Σ00(u) : τr0. We show that

τr0 <: τp0 (4.5)

by analysing all applicable preconditions and patterns for the `pjudgement.

We start by noting that the pINIT rule is not applicable because this relies on the call stack being empty. As n > 0, we know that s0 is non-empty because there is no step that yields an empty

stack, i.e., hΣ, Si 6→ hΣ0, εi. We therefore do not need to consider these cases. pRAISE is also not applicable because we cannot execute another step after reducing to a TypeError.

The pTRAIL rule is also not applicable because its precondition requires the variable u for execution point s0 to be in the trail. Since T∅ is empty, we have that if hs0, ui 6∈ T∅. For the remaining rules, we can assume that the corresponding preconditions on the trail hold.

We start by analysing the cases that apply to the remaining axioms shown in Figure4.3. We only show the case for pLC, however the remaining cases all follow the same pattern.

CasepLC, i.e., u is tos, s0 has the form hP0, pc0i :: ... and Ppc0 0 is LC c..

In this case, the inferred type τp0 is obtained using the judgement hs0, T∅i `p tos : τp0. By pLC, τp0 is such that c : τp0. In particular, τp0 is a primitive type, i.e., not a union type. To get the runtime type we consider the semantics of µPython when u is tos, s0 has the form hP0, pc0i :: ... and Ppc0 0 is LC c.. From this we see that Σ0(tos) is c and so τr0 is such that c : τr0. From this,

and the fact that τp0 is a primitive type, we can immediately conclude that τp0 = τr0 and thus (4.5) holds as required.

We now focus on the recursive rules shown in Figure4.4. The proofs for these cases follow the same pattern and we only elaborate on one case.

CasepLG1. u is tos, s0has the form hP0, pc0i :: ... and Ppc0 0 is LG x..

In this case, the inferred type τp0 is obtained using the judgement hs0, T∅i `p tos : τp0. By pLG1, we have τp0 =F τisuch that:

hsi, T ∪ {hs0, tosi}i `px : τi for each si∈ prev(s0)

for all si ∈ prev(s0). From (4.1), we know that at least one of the truncated call stacks re- turned by prev is a truncation of the runtime call stack at the previous runtime step. Hence s ∈ prev(s0). Let τp, τp00be such that

hs, Ti `p x : τp and hs, T∅∪ {hs0, tosi}i `p x : τp00

Since τp00must be one of the τijoined together to compute τp0, we know that τp00 <: τp0 and since T∅ ⊆ T∅, we use Lemma4.3to conclude that

τp<: τp0

Recall that our assumption in the inductive hypothesis states that τr<: τp

where τris such that Σ(x) : τr. By using this assumption, our previous conclusion τp<: τp0 and by exploiting the transitivity property of the subtype operator, we know that

τr<: τp0

We now refer to the semantics of µPython in Figure3.4for this case. From this we know Σ(x) is Σ0(tos). Hence, τr= τr0 and therefore we conclude that τr0 <: τp0 as required.

The previous proof depends on the next two lemmas, which relate judgements with different elements in their respective trails. For instance, consider τ derived using hs, T i `pu : τ and τ00, derived using hs, T ∪ {hs0, vi}i `p u : τ00. We intuit that τ00 <: τ . This is because in the case of the proof tree deriving τ00, the rule pTRAIL is more likely to be applied. Indeed, we prove a stronger property in Lemma4.4. We now consider τ0, derived using hs0, T0i `p v : τ0. In the proof for the previous theorem, and in cases where a type is derived using any of the rules in Figure4.4, a pattern emerges. In these cases, throughout the proof we see that τ0 = τ00t . . . (and hence τ00 <: τ0) but we need to prove that τ <: τ0. We do so in the next lemma.

Lemma 4.3 (Bounding). For any variables u, v, execution points s, s0, and trailsT , T0 such thatT0⊆ T . We have that

hs, T i `p u : τ hs0, T0i `p v : τ0 hs, T ∪ {hs0, vi}i `pu : τ00 (4.6) andτ00<: τ0, then τ <: τ0 (4.7)

Proof. We proceed by induction on the size n of the set difference between the universal trail TU and the actual trail, i.e., size(TU− T ). The universal trail is defined as the trail containing all combinations of hs, ui for all u, s. Therefore we prove that the above lemma holds for all n. Base case. We start with n = 0, which means that size(TU − T ) = 0. Since there is no trail bigger than TU, T is the trail TU. We substitute T = TU into (4.6), and we rewrite our judgements as:

hs, TUi `pu : τ hs0, T0i `p v : τ0 hs, TU∪ {hs0, vi}i `p u : τ00

The universal trail contains all possible trail elements. Therefore hs, ui ∈ TU and by pTRAIL we conclude that τ = ⊥. This means that our claim τ <: τ0 holds since ⊥ is a subtype of any type.

Inductive case. We assume that the Lemma holds for some size(TU − T ) = n, i.e., for any variables u, v, execution points s, s0, and trails T , T0such that T0 ⊆ T and size(TU− T ) = n.

If hs, T i `p u : τ hs0, T0i `p v : τ0 hs, T ∪ {hs0, vi}i `pu : τ00 (4.8) and τ00<: τ0, then τ <: τ0 (4.9)

We then show that it also holds for n + 1. For this, we choose two trail variables T00and T000, where size(TU − T00) = n + 1, and T000 ⊆ T00. This means that the number of elements in T00 is one smaller than the number of elements in T as defined in (4.8). In particular, we have to show that for any variables u, v, execution points s, s0, and trails T00, T000 such that T000 ⊆ T00 and size(TU− T00) = n + 1, and

hs, T00i `p u : τ hs0, T000i `p v : τ0 hs, T00∪ {hs0, vi}i `pu : τ00 (4.10) and τ00<: τ0, then τ <: τ0 (4.11)

We proceed by analysing the proof of the judgement hs, T00∪ {hs0, vi}i `

p u : τ00 by a case analysis on the last rule (see Figure4.3and Figure4.4) used in the proof.

CasepINIT, i.e., looking up a variable in the entry point of the program.

We have s = ε and we rewrite some of our judgements from (4.10) correspondingly as: hε, T00i `p u : τ

hε, T00∪ {hs0, vi}i `pu : τ00 From the hypothesis of pINIT, we conclude that

ΣI(u) : τ ΣI(u) : τ00

From this we can see that τ = τ00, which implies that τ <: τ00. Since our inductive hypothesis states that τ00<: τ0, by transitivity we also have τ <: τ0as required.

CasepTRAIL.

In this case, hs, ui ∈ T00, i.e., the variable u for execution point s is already in the trail. If we assume hs, ui is not hs0, vi. hs, T00i `p u : τ becomes hs, T00i `p u : ⊥. Since τ is ⊥, then τ <: τ0 because ⊥ is a subtype of any type.

Now, if we assume hs, ui is hs0, vi, we rewrite our judgements from (4.10) to: hs, T00i `pu : τ

hs, T000i `pu : τ0

Since T000⊆ T00, the original claim τ <: τ0 holds according to Lemma4.4. CasepLC, u is tos, s has the form hP, pci :: ... and Ppcis LC c.

We rewrite our judgements from (4.10) to:

hs, T00i `p tos : τ hs0, T000i `p v : τ0 hs, T00∪ {hs0, vi}i `p tos : τ00

From the hypothesis of pLC, we conclude that c : τ and c : τ00. Since τ and τ00 are primitive types, τ = τ00and since our hypothesis states that τ00<: τ0, then τ <: τ0as required.

All other axioms in Figure4.3follow the same pattern as this case.

We now look at the recursive rules in Figure4.4. The proofs for these cases follow the same pattern. We will only look at the case for pLG1 and omit the other cases.

CasepLG1.

In this case u is tos, s has the form hP, pci :: ... and Ppcis LG x. and we rewrite our judgements from (4.10) accordingly to:

hs, T00i `p tos : τ hs0, T000i `p v : τ0 hs, T00∪ {hs0, vi}i `p tos : τ00 By pLG1 τ =F τiand τ00=F τi00where hsi, T00∪ {hs, tosi}i `px : τi hsi, T00∪ {hs, tosi} ∪ {hs0, vi}i `p x : τi00 for all si ∈ prev(s).

Let T be T00∪ {hs, tosi}, then we can rewrite the above as hsi, T i `px : τi hsi, T ∪ {hs0, vi}i `p x : τi00 for all si ∈ prev(s).

Note that since τ00 = F τ00

i , then τi00 <: τ00, and since τ00 <: τ0 by assumption, then τi00 <: τ0 for each τi00. Note also that hs0, T000i `p v : τ0 as part of our hypothesis. Furthermore note that T000 ⊆ T00 ⊆ T00∪ {hs, tosi} = T . The hypothesis in (4.8) all hold and size(T

U− T ) = n so by the inductive hypothesis, τi <: τ0for each τi. Therefore τ =F τi <: τ0as required.

All other recursive cases follow the same pattern.

The next lemma states that with fewer elements in a trail we get a more general type.

Lemma 4.4. For any variable u, execution point s and trails T , T0such thatT0 ⊆ T , τ <: τ0 where

hs, T i `p u : τ hs, T0i `p u : τ0

(4.12)

Proof. We proceed by induction on n, which we define as the size of the set difference between the universal trail TU and the actual trail, i.e., size(TU − T ). Therefore we prove that the above lemma holds for all n.

Base case.We start with n = 0 so that T is the universal trail TU. We substitute T with TUin the judgements (4.12):

hs, TUi `p u : τ hs, T0i `p u : τ0

Since hs, ui ∈ TU, by pTRAIL we can conclude that τ = ⊥. Hence our claim τ <: τ0holds as required.

Inductive case. We assume that the Lemma holds for some size(TU − T ) = n, i.e., that for all variables u, execution points s and trails T , T0 such that T0 ⊆ T , τ <: τ0where

hs, T i `p u : τ

hs, T0i `p u : τ0 (4.13)

We now show that it also holds for n + 1. For this we choose trail variable T00, where size(TU− T00) = n + 1 and some T000 such that T000 ⊆ T00. In particular, we show that for any variables u, v, execution points s, s0, and trails T00, T000such that T000 ⊆ T00and size(TU − T00) = n + 1, τ <: τ0 where

hs, T00i `pu : τ

hs, T000i `pu : τ0 (4.14)

We proceed by analysing the last rule used in the proof of hs, T000i `pu : τ0 CasepINIT, i.e., looking up a variable in the entry point of the program.

In this case s = ε, and we can therefore rewrite (4.14) as: hε, T00i `pu : τ hε, T000i `pu : τ0

From pINIT, we see that ΣI(u) : τ and ΣI(u) : τ0 hold. Both τ and τ0 are primitive types and hence τ <: τ0as required.

CasepTRAIL, hs, ui ∈ T00, i.e., the variable u for execution point s is already in the trail, and hence

τ is ⊥. Therefore τ <: τ0as required.

For the remaining cases we assume that hs, ui 6∈ T00and since T000 ⊆ T00, we also have hs, ui 6∈ T000.

The proofs for the cases that match the remaining rules in Figure4.3 follow the same pattern. We only elaborate the case that matches rule pLC.

CasepLC, i.e., u is tos, s has the form hP, pci :: ... and Ppc is LC c.. We rewrite our judgements from (4.14) as

hs, T00i `p tos : τ hs, T000i `p tos : τ0

In this case we see that rule pLC tells us that c : τ and c : τ0. Since τ and τ0 are primitive, τ <: τ0 as required.

The proofs for the cases that match the recursive rules in Figure4.4, all follow the same pattern. We only elaborate the case that matches rule pLG1.

CasepLG1, i.e., u is tos, s has the form hP, pci :: ... and Ppc is LG x.. We rewrite our judgements from (4.14) as

hs, T00i `p tos : τ hs, T000i `p tos : τ0 By pLG1 τ =F τiand τ00=F τi00where hsi, T00∪ {hs, tosi}i `p x : τi hsi, T000∪ {hs, tosi}i `p x : τi0 (4.15) for si∈ prev(s).

Let T be T00 ∪ {hs, tosi} and T0 be T000∪ {hs, tosi}. Then by rewriting (4.15) we have the hypothesis (4.13), where size(TU− T ) = n.

By the inductive hypothesis we have τi <: τi0for all τi, τi0as required.