CS221/321 Lecture 7, Nov 3,8, 2011 Where do we go from here? ------------------------- Various possible directions: (1) (functional) control flow continuations exceptions coroutines (pseudo)concurrent threads (2) state reference cells with assignment imperative commands (vs expressions) monadic state (3) types static typing judgements and inference rules type soundness We are going to first look at types. ---------------------------------------------------------------------- Section 4: Static Semantics --------------------------- Lets first do a simpler exercise in "static semantics" involving SEAL. This will allow us to develop the main results with fewer complicating details to worry about. Here we have only one type of value being expressed: natural numbers. So there is no possibility of conventional type errors. But there is a way that syntactically correct expressions can fail to be evaluated: the presence of free variables. So a "bad" expression is one that has free variables: Bad = {e ∈ expr | FV(e) ≠ ∅} We want to create a system of rules that will exclude bad expressions, thereby defining the set of good expressions whose evaluation can be completed. These are the expressions that have a "meaning". This property of being good cannot be captured by a simple inductive definition on SAEL expressions, because, for instance: let x = 3 in x is good -- it has no free variables -- but it contains a bad subexpression, the body x. So we need to define a more liberal property of being good with respect to a given set of variables (that are assumed to be properly bound in some outer context). Defn: Judgement: Let Γ be a set of variables. The judgement Γ ⊦ e ok says that e is good with respect to Γ, i.e. FV(e) ⊆ Γ. We can also say that e is "closed relative to Γ" or e is "closed in Γ". We call Γ the "context" of the judgement, and e the "subject" of the judgement. The "truly good" expression are those for which we can prove ∅ ⊦ e ok. These are good with respect to the empty set of variables. ---------------------------------------------------------------------- Fig 4.1: SEAL[ok] - Rules for relative closure judgements: Γ ⊦ e ok ---------------------------------------------------------------------- Rules: (1) ---------------- Γ ⊦ Num(n) ok (x ∈ Γ) (2) ----------- Γ ⊦ x ok Γ ⊦ e1 ok Γ ⊦ e2 ok (3) ---------------------------- Γ ⊦ Bapp(bop,e1,e2) ok Γ ⊦ e1 ok Γ ⋃ {x} ⊦ e2 ok (4) ---------------------------------- Γ ⊦ let x = e1 in e2 ok ---------------------------------------------------------------------- So asserting that "Γ ⊦ e ok" is really asserting that there is a derivation of that judgement using these rules. (We will refer to these rules by "ok(1)", etc.) Of course, for this property, it is not clear that we have gained much by expressing it through an inference system as opposed to using the computed property of the expression given by FV(e) = ∅. But when we go to full type systems, using inference rules be more clearly useful. [But keep asking why.] So now we want to show that for good expressions, small-step evaluation will successfully terminate in a value, i.e. "Nothing will go wrong". We will assume that we are talking about bind-by-value evaluation (SEAL[SSv], Figure 2.4, Lecture 4), which can easily be shown to terminate (Homework 3.1a). Theorem 4.1: ∅ ⊦ e ok => ∃n. e ↦! Num(n). Intuition: If e is closed (no free variables), we will never find outselves trying to evaluate a variable. We can be sure of this if we can show that: (1) At each point in the transition sequence, the current expression is closed, i.e. the property of being closed is preserved by all transitions. (2) If e is closed, either e is a value, and we are finished with evaluation, or, if not, then there is a transition defined for e (by the SEAL[SSv] rules). (3) A small-step (bind-by-value) transition sequence cannot go on forever, and hence will terminate with a value (Homework 3.1). We call the first property "preservation" (of closure), and the second property is called "progress" (we can always make progress if we have a closed, nonvalue expression). We formalize the first two propositions as the Preservation and Progress Lemmas. Lemma [Preservation]: ∅ ⊦ e ok ∧ e ↦ e' => ∅ ⊦ e' ok. Lemma [Progress]: ∅ ⊦ e ok => e a value ∨ ∃e'. e ↦ e'. What these lemmas amount to is that evaluation of a SEAL expression will not get "stuck" at some point where the only way evaluation could get stuck in SEAL is that we encounter a free variable. We haven't been explicit about whether ↦ denotes the bind-by-value or bind-by-name transition relation. It actually doesn't make much difference to the proofs whether it is by-value or by-name, unlike the question of termination, where the proofs are radically different (see Homework 3.1 vs 4.1b). ------------------- We will prove the Preservation lemma by induction on the derivation of the premise e ↦ e', using the rules in Fir. 2.4 for SAEL[SSv]. For the Rule (5) base case, we will need two technical lemmas: Inversion for the ok rules (Fig 4.1 above), and a Substitution lemma. Lemma 4.2 [Inversion]: (1) Γ ⊦ x ok => x ∈ Γ (2) Γ ⊦ Bapp(bop,e1,e2) ok => Γ ⊦ e1 ok ∧ Γ ⊦ e2 ok (3) Γ ⊦ let x = e1 in e2 ok => Γ ⊦ e1 ok ∧ Γ⋃{x} ⊦ e2 ok Proof: The proof consists simply of observing that a derivation of an ok judgement entails derivations of its premises. (1) A derivation of Γ ⊦ x ok must be by rule ok(2), because that is the only rule that applies for a variable exression like x. Hence in that derivation, the premise of ok(2) must hold, i.e. x ∈ Γ. [X] (2) A derivation of Γ ⊦ Bapp(bop,e1,e2) ok must have ok(3) as its final rule, because only that rule matchines the expression Bapp(bop,e1,e2). Hence the premises of that rule, namely Γ ⊦ e1 ok and Γ ⊦ e2 ok must be the conclusions of the subderivations. [X] (3) Similar. [X] Lemma 4.3 [Weakening]: Γ ⊦ e ok & Γ ⊆ Γ' => Γ' ⊦ e ok. Proof. Induction on the derivation of Γ ⊦ e ok. [Exercise] We prove the following Substitution lemma in a general form, where we are substiting an arbitrary expression rather than a Num expression, since the general form can also be used for a bind-by-name (SEAL[SSn]) version of the Preservation Lemma. Lemma 4.4 [Substitution]: Γ ⊦ e1 ok ∧ Γ⋃{x} ⊦ e2 ok ∧ x ∉ Γ => Γ ⊦ [e1/x]e2 ok. Discussion: The Substitution Lemma says that if e1 has free variables in Γ, and e2 has free variables in Γ⋃{x}, then substituting e1 for a variable x ∉ Γ in e2 yields an expression having free variables in Γ, the additional free variable x having been eliminated by the substitution. The conclusion (Γ ⊦ [e1/x]e2 ok) would still be true even if x ∈ Γ, and hence Γ⋃{x}=Γ, but the point is to eliminate the variable x through the substitution, so we are only interested in the case where x is not free in e1. Hence we specify that x ∉ Γ. In the application of the Substitution Lemma we will actually have ⊦ e1 ok, i.e. e1 will be closed. The proof will be to use induction on the derivation d of Γ⋃{x} ⊦ e2 ok, using the rules of Fig. 4.1. From any such derivation d we can derive two values: the context Γ and the subject expression e of the derivations final conclusion, Γ ⊦ e ok. We will call these context(d) and subject(d). We might proceed naively, doing the case analysis on the (final) rule used for deriving the Γ⋃{x} ⊦ e2 ok judgement, but not making the derivation explicit. Lets consider the case for rule (4) (from Fig 4.1 above). Case: Γ⋃{x} ⊦ e2 ok by Rule (4). Then e2 is of the form e2 = let y = e3 in e4 for some y, e3, and e4. We can also assume, without loss of generality, that y ≠ x, since if not, we could convert e2 to an equivalent expression by changing the bound variable x (= y) to a different variable (α-conversion). By inversion of rule (4), we then have (a) Γ⋃{x} ⊦ e3 ok (b) (Γ⋃{x})⋃{y} ⊦ e4 ok or, equivalently, (b') Γ'⋃{x} ⊦ e4 ok where Γ' = Γ⋃{y} By backward chaining (i.e. working backward from a desired conclusion to premises that would imply it) via rule (4) from the desired conclusion Γ ⊦ [e1/x](let y = e3 in e4) ok or, equivalently (choosing y so that y ≠ x and y ∉ FV(e1)) Γ ⊦ (let y = [e1/x]e3 in [e1/x]e4) ok, it suffices to prove (c) Γ ⊦ [e1/x]e3 ok (d) Γ⋃{y} ⊦ [e1/x]e4) ok We can see how an obvious Induction Hypothesis could allow us to get from (a) to (c): IH1: Γ⋃{x} ⊦ e3 ok => Γ ⊦ [e1/x]e3 ok The obvious Induction Hypothesis for e4 would be: IH2: Γ⋃{x} ⊦ e4 ok => Γ ⊦ [e1/x]e4 ok but unfortunately this does not get us from (b') to (d). We would have to replace Γ with Γ' = Γ⋃{y}, giving IH2': Γ'⋃{x} ⊦ e4 ok => Γ' ⊦ [e1/x]e4 ok (Γ' = Γ⋃{y}) But what is the justification of replacing Γ with Γ' in IH2'? To support the required variation in the context in the two IHs, we need to reconsider the statement of the Lemma and be more explicit about the Induction Principle being used. We could try to strengthen or generalize the statement of the Lemma to express the required flexibility in the context by introducing a second context, as in the following version: (1) ∀e1.∀Γ1. Γ1 ⊦ e1 ok => (∀e2.∀Γ2.∀x∈Var. x ∉ Γ1 ∧ Γ1 ⊆ Γ2 ∧ Γ2⋃{x} ⊦ e2 ok => Γ2 ⊦ [e1/x]e2 ok) The quantification over the superset Γ2 of Γ1 may provide the flexibility needed derive both IH1 and IH2' above. But we still need to explain how derive the desired Induction Hypotheses from this proposition. Since we are proving this be induction on _derivations_ of the ok judgement, it will be clearer to restate (1) in terms of derivations d in Der[ok], the inductively defined set of ok derivations. (1a) ∀e1.∀Γ1. Γ1 ⊦ e1 ok => (∀d∈Der[ok].∀x∈Var. x ∉ Γ1 ∧ Γ1 ⊆ context(d) ∧ context(d) ⊦ subject(d) ok => context(d)\{x} ⊦ [e1/x]subject(d) ok) where subject(d) is the expression part of the conclusion judgement of d, i.e. e2, and context(d) is the context part of that judgment, i.e. Γ2. Of course, the conjunct (context(d) ⊦ subject(d) ok) is true by definition, so it is redundant, and (1a) can be simplified to: (1b) ∀e1.∀Γ1. Γ1 ⊦ e1 ok => (∀d∈Der[ok].∀x∈Var. x ∉ Γ1 ∧ Γ1 ⊆ context(d) => context(d)\{x} ⊦ [e1/x]subject(d) ok) Finally, we can replace the e1 and Γ quantifiers and the outer hypothesis Γ ⊦ e1 ok with a quantification over derivations: Prop A: ∀d1∈Der[ok]. ∀d2∈Der[ok]. ∀x∈Var. x ∉ context(d1) => context(d1) ⊆ context(d2) => context(d2)\{x} ⊦ [subject(d1)/x]subject(d2) ok) Proof: ------ First let us be precise about the structure of derivations and the definitions of context and subject of a derivation. Derivations d in Der[ok] are inductively constructed using rule-constructors corresponding to the four rules of Fig 4.1: d ::= OK1(Γ, n) | OK2(Γ, z) | OK3(bop,d1,d2) -- d1 and d2 are the derivations for e1 and e2 | OK4(z,d1,d2) -- d1 is derivation for definiens, d2 for body These rule constructors are not "free" constructors, because a valid construction of a derivation has to satisfy some side constrains, specified as follows: OK2(Γ,z) : z ∈ Γ OK3(bop,d1,d2) : context(d1) = context(d2) OK4(z,d1,d2) : context(d2) = context(d1) ⋃ {z} We define the subject and context functions for derivations as follows: S1: subject(OK1(Γ, n)) = Num n S2: subject(OK2(Γ, z)) = Var z S3: subject(OK3(bop,d1,d2)) = Bapp(bop,subject(d1),subject(d2)) S4: subject(OK4(z,d1,d2)) = Let(z,subject(d1),subject(d2)) C1: context(OK1(Γ, n)) = Γ C2: context(OK2(Γ, z)) = Γ C3: context(OK3(bop,d1,d2)) = context(d1) C4: context(OK4(x,d1,d2)) = context(d1) The Induction Principle for these derivations is as follows: IP[ok]: (P a predicate over d) ∀Γ.∀n.P(OK1(Γ,n)) ∧ ∀Γ.∀z.P(OK2(Γ,z)) ∧ ∀bop.∀d1.∀d2.(P(d1) ∧ P(d2) ^ context(d1) = context(d2) => P(OK3(bop,d1,d2))) ∧ ∀z.∀d1.∀d2.(P(d1) ∧ P(d2) ∧ context(d2) = context(d1)⋃{z} => P(OK4(z,d1,d2))) => ∀d.P(d) where it is understood that Γ ranges over variable sets, n over Nat, z over variables, bop over primitive operators, and d,d1,d2 over Der[ok]. Now we give two proofs of Prop A. The first is in conventional "proof prose" style, and the second is a semi-formal proof. ---------------------------------------------------------------------- Conventional Proof: ---------------------------------------------------------------------- We will assume we are given a derivation d1 of a judgement Γ1 ⊦ e1 ok (i.e., Γ1 = context(d1) and e1 = subject(d1)), which will be fixed for the rest of the proof. We also assume a variable x ∉ Γ1 is given. Then we will prove that ∀d∈Der[ok].P(d), where P is the property: (2) P(d) == Γ1 ⊆ context(d) => context(d)\{x} ⊦ [e1/x]subject(d) ok The proof is by induction on the the structure of a derivation d ∈ Der[ok] as defined above in terms of derivation constructors OK1, OK2, OK3, and OK4. Base Case: d = OK1(Γ2,n). Then let e2 = subject(d) = Num(n), and note that context(d) = Γ2. Then [e1/x]e2 = Num(n) by the definition of substitution. By ok(1), Γ1 ⊦ Num(n) ok for any context Γ, and in particular for Γ2\{x}. [X] Base Case: d = OK2(Γ2,y). Then let e2 = subject(d) = Var(y), and note that context(d) = Γ2. We can assume that Γ1 ⊆ Γ2, since otherwise the premise of the implication P(d) is false and P(d) holds vacuously. There are two subcases. (a) y = x: In this case, [e1/x]e2 = e1. We know that Γ1 ⊦ e1 ok, and hence Γ2\{x} ⊦ e1 ok, by Lemma 4.3, since Γ1 ⊆ Γ2\{x} because of the assumption that x ∉ Γ1. (b) y ≠ x: In this case, [e1/x]e2 = e2 = Var(y). It must be the case that y ∈ Γ2 by the OK2 constraint, and since y ≠ x, y ∈ Γ2\{x}. Hence Γ1\{x} ⊦ Var(y) ok by ok(2). So Γ2\{x} ⊦ [e1/x]e2 ok. [X] Ind Case: d = OK3(bop,d3,d4). Let e3 = subject(d3) and e4 = subject(d4) and Γ2 = contect(d) = context(d3) = context(d4), by the OK3 constraint and the defn of context. So e2 = subject(d) = Bapp(bop,e3,e4). If Γ1 ⊄ Γ2, then P(d) holds vacuously, so we can assume Γ1 ⊆ Γ2. IH1: P(d3) == Γ1 ⊆ Γ2 => Γ2\{x} ⊦ [e1/x]e3 ok IH2: P(d4) == Γ1 ⊆ Γ2 => Γ2\{x} ⊦ [e1/x]e4 ok By IH1 and the assumption that Γ1 ⊆ Γ2, we have Γ2\{x} ⊦ [e1\x]e3 ok. Similarly, by IH2 we have Γ2\{x} ⊦ [e1\x]e4 ok. Then by rule ok(3) we have Γ2\{x} ⊦ [e1\x]Bapp(bop,e3,e4) ok, and hence Γ2\{x} ⊦ [e1\x]e2 ok by the defn of substitution. [X] Ind Case: d = OK4(y,d3,d4). Let e3 = subject(d3) and e4 = subject(d4) and Γ2 = contect(d3). Then it must be the case that Γ3 = context(d4) = Γ2⋃{y} by the OK4 constraint. We then have e2 = Let(y, e3, e4). We can assume that the local let-bound variable y is chosen so that y ≠ x and y ∉ FV(e3) (by α-converting, if necessary, to make it so). We can also assume that Γ1 ⊆ Γ2, since otherwise P(d) is true vacuously. Since Γ1 ⊆ Γ2, we also have Γ1 ⊆ Γ3. IH1: P(d3) == Γ1 ⊆ Γ2 => Γ2\{x} ⊦ [e1/x]e3 ok IH2: P(d2) == Γ1 ⊆ Γ3 => Γ3\{x} ⊦ [e1/x]e4 ok By IH1 and the fact that Γ1 ⊆ Γ2, we have Γ2\{x} ⊦ [e1/x]e3 ok (1) and by IH2 and Γ1 ⊆ Γ3 we have Γ3\{x} ⊦ [e1/x]e4 ok (2) Since Γ3\{x} = (Γ2\{x})⋃{y}, we can conclude from (1), (2) and rule ok(4) that Γ2\{x} ⊦ Let(y,[e1/x]e3,[e1/x]e4) ok (3) But by the definition of substitution and the assumption that y ≠ x and y ∉ FV(e1), Let(y,[e1/x]e3,[e1/x]e4) = [e1/x](Let(y,e3,e4)) = [e1/x]e2. (4) Hence by (3) and (4), we have Γ2\{x} ⊦ [e1/x]e2 ok. [XX] ---------------------------------------------------------------------- Semi-formal Proof ---------------------------------------------------------------------- [Note: We are using a new numbering scheme for semi-formal proofs starting with this one. The proof is structured like an outline, with subproofs indented. Steps are numbered in a hierarchical way, e.g. (6.2.2), but this is abbreviated to (.2) in the context of the current hierarchical level. References to steps outside the current level use repeated carets (^) to refer to parent levels. E.g. at line 6.2.3.2.1, ^^^.2 refers to 6.2.2.] (0) let d1 ∈ Der[ok] [decl d1] (1) let e1 = subject(d1) [defn e1] (2) let Γ1 = context(d1) [defn Γ1] (3) Γ1 ⊦ e1 ok [(.1),(.2)] (4) let x ∈ Var [decl x] (5) x ∉ Γ1 [hyp] (6) let P(d) == Γ1 ⊆ context(d) => context(d)\{x} ⊦ [e1/x]subject(d) ok [defn P] (7) let d2 ∈ Der[ok] [decl d2] (8) let Γ2 = context(d2) [defn Γ2] (9) let e2 = subject(d2) [defn e2] (10) TBS: P(d2) [induction on d2 ∈ Der[ok]] [ P(d2) == Γ1 ⊆ Γ2 => Γ2\{x} ⊦ [e1/x]e2 ok ] (.1) case: d2 = OK1(Γ2,n) [case hyp] (.1) e2 = Num(n) [(9),case,S1] (.2) [e1/x]e2 = Num(n) [subst] (.3) Γ2\{x} ⊦ Num(n) ok [ok(1)] (.4) Γ2\{x} ⊦ [e1/x]e2 ok [(.2), (.3)] (.5) P(d2) [impl; QED case] (.2) case: d2 = OK2(Γ2,y) [case hyp] (.1) let e2 = subject(d2) [defn e2] (.2) e2 = Var(y) [S2] (.3) cases on y = x [cases] (.1) case: y=x [case hyp] (.1) [e1/x]e2 = e1 [subst] (.2) Γ1 ⊆ Γ2\{x} [(2),(5)] (.3) Γ2\{x} ⊦ e1 ok [(.2), Lemma 4.3] (.4) Γ2\{x} ⊦ [e1/x]e2 ok [(.1), (.3); QED case] (.2) case: y≠x [case hyp] (.1) [e1/x]e2 = y [^^^.2, case, defn subst] (.2) y ∈ Γ2 [OK2 constraint] (.3) y ∈ Γ2\{x} [(.2), case] (.4) Γ2\{x} ⊦ y ok [ok(2), (.3)] (.5) Γ2\{x} ⊦ [e1/x]e2 ok [ok(2), (.3); QED case] (.4) Γ2\{x} ⊦ [e1/x]e2 ok [(.3)] (.5) P(d2) [impl; QED case] (.3) case: d2 = OK3(bop,d3,d4) [case hyp] (.0) Γ1 ⊆ Γ2 [hyp] (.1) let e3 = subject(d3) [defn e3] (.2) let e4 = subject(d4) [defn e4] (.3) let e2 = subject(d) [defn e2] (.4) e2 = Bapp(bop,e3,e4) [C3] (.5) context(d3) = Γ2 [(4), constraint OK3] (.7) context(d4) = Γ2 [(4), constraint OK3] (.7) Γ1 ⊆ Γ2 => Γ2\{x} ⊦ [e1/x]e3 ok [IH: P(d3)] (.8) Γ1 ⊆ Γ2 => Γ2\{x} ⊦ [e1/x]e4 ok [IH: P(d4)] (.9) Γ2\{x} ⊦ [e1/x]e3 ok [(.7), (5)] (.10) Γ2\{x} ⊦ [e1/x]e4 ok [(.8), (5)] (.11) Γ2\{x} ⊦ Bapp(bop,[e1/x]e3,[e1/x]e4) ok [(.9), (.10), ok(3)] (.12) Γ2\{x} ⊦ [e1/x]Bapp(bop,e3,e4) ok [defn subst] (.13) Γ2\{x} ⊦ [e1/x]e2 ok [(.4), (.12)] (.14) P(d2) [(.0),(.13), => Intro; QED case] (.4) case: d = OK4(y,d3,d4) [case hyp] (.0) Γ1 ⊆ Γ2 [hyp] (.1) let e3 = subject(d3) [defn e3] (.2) let e4 = subject(d4) [defn e4] (.3) let Γ3 = context(d4) [defn Γ3] (.4) context(d3) = Γ2 [(4), C4] (.5) Γ3 = Γ2 ⋃ {y} [(.3), constraint OK4] (.6) let e2 = subject(d) [defn] (.7) e2 = Let(y,e3,e4) [S4] (.8) y ≠ x & y ∉ FV(e3) [α-conversion] (.9) Γ1 ⊆ Γ2 [hyp] (.10) Γ1 ⊆ Γ3 [(.5), (.9)] (.11) Γ1 ⊆ Γ2 => Γ2\{x} ⊦ [e1/x]e3 ok [IH: P(d3)] (.12) Γ1 ⊆ Γ3 => Γ3\{x} ⊦ [e1/x]e4 ok [IH: P(d4)] (.13) Γ2\{x} ⊦ [e1/x]e3 ok [(.9), (.11)] (.14) Γ3\{x} ⊦ [e1/x]e4 ok [(.10), (.12)] (.15) Γ2\{x} ⊦ Let(y,[e1/x]e3,[e1/x]e4) ok [(.13),(.14),ok(4)] (.16) Let(y,[e1/x]e3,[e1/x]e4) = [e1/x](Let(y,e3,e4)) = [e1/x]e2 [defn subst, (.8)] (.17) Γ2\{x} ⊦ [e1/x]e2 ok [(.15),(.16)] (.18) P(d2) [(.0),(.17), => Intro; QED case] (11) ∀d. P(d) [(10.1),(10.2), (10.3),(10.4), I.P; QED] ---------------------------------------------------------------------- We can now proof the original Substitution Lemma as a corollary of Prop A. Lemma 4.4 [Substitution]: Γ ⊦ e1 ok ∧ Γ⋃{x} ⊦ e2 ok ∧ x ∉ Γ => Γ ⊦ [e1/x]e2 ok. Proof: We simply instantiate the universally quantified derivation variables d1 and d2 to be derivations of Γ ⊦ e1 ok and Γ⋃{x} ⊦ e2 ok, respectively. Then we note that context(d1) = Γ1 and context(d2) = Γ ⋃ {x}, so context(d1) ⊆ context(d2). The we conclude by Prop A that Γ ⊦ [e1/x]e2 ok. QED -------------------------- Lemma 4.5 [Preservation]: ∅ ⊦ e ok ∧ e ↦ e' => ∅ ⊦ e' ok. Proof: By induction on the derivation d of e ↦ e'. We will use the Rule constructs for SEAL[SSv] (Figure 2.4, Lect 4) given in the solution of Homework 3.1 (hw3_sol.txt). Let metavariable d range over D = Der(SEAL[SSv]), the set of derivations of (e ↦ e') judgements. d ::= R1(bop,n1,n2) (Rule (1)) | R2(bop,d,e) (Rule (2)) | R3(bop,n,d) (Rule (3)) | R4(x,d,e) (Rule (4)) | R5(x,n,e) (Rule (5)) S1: source(R1(bop,n1,n2)) = Bapp(bop, Num n1, Num n2) S2: source(R2(bop,d,e)) = Bapp(bop, source(d), e) S3: source(R3(bop,n,d)) = Bapp(bop, Num n, source(d)) S4: source(R4(x,d,e)) = Let(x, source(d), e) S5: source(R5(x,n,e)) = Let(x, Num n, e) T1: target(R1(bop,n1,n2)) = Num(prim(bop,n1,n2)) T2: target(R2(bop,d,e)) = Bapp(bop, target(d), e) T3: target(R3(bop,n,d)) = Bapp(bop, Num n, target(d)) T4: target(R4(x, d, e)) = Let(x, target(d), e) T5: target(R5(x, n, e)) = [Num n/x]e We must prove ∀d. P(d), where P(d) = ∅ ⊦ source(d) ok => ∅ ⊦ target(d) ok (0) P(d) = ∅ ⊦ source(d) ok => ∅ ⊦ target(d) ok [defn] (1) ∀d. P(d) [TBS] (2) induction on structure d (.1) case: d = R1(bop,n1,n2) [case hyp] (.1) target(d) = Num(p) where p = prim(bop,n1,n2) [T1] (.2) ∅ ⊦ target(d) ok [ok(1)] (.3) P(d) [logic; QED] (.2) case: d = R2(bop,d',e2) [case hyp] (.1) ∅ ⊦ source(d) ok [hyp] (.2) let e = source(d) [defn] (.3) let e' = target(d) [defn] (.4) let e1 = source(d') [defn] (.5) let e1' = target(d') [defn] (.6) e = Bapp(bop,e1,e2) [S2] (.7) e' = Bapp(bop,e1',e2) [T2] (.8) ∅ ⊦ e1 ok => ∅ ⊦ e1' ok [IH: P(d')] (.9) ∅ ⊦ Bapp(bop,e1,e2) ok [(.1),(.2),(.6)] (.10) ∅ ⊦ e1 ok [Inversion of ok(3)] (.11) ∅ ⊦ e2 ok [Inversion of ok(3)] (.12) ∅ ⊦ e1' ok [(.10),(.8): induction] (.13) ∅ ⊦ Bapp(bop,e1',e2) ok. [(.11),(.12),ok(3)] (.14) ∅ ⊦ e' ok. [(.7),(.13)] (.15) ∅ ⊦ target(d) ok [(.3)] (.16) P(d) [(.1),(.15), => Intro; QED case] (.3) case: d = R3(n1,d') [Similar to R2 case] (.4) case: d = R4(x,e2,d') [case hyp] (.1) ∅ ⊦ source(d) ok [hyp] (.2) let e = source(d) [defn] (.3) let e' = target(d) [defn] (.4) let e1 = source(d') [defn] (.5) let e1' = target(d') [defn] (.6) e = Let(x,e1,e2) [S4] (.7) e' = Let(x,e1',e2) [T4] (.8) ∅ ⊦ e1 ok => ∅ ⊦ e1' ok [IH: P(d')] (.9) ∅ ⊦ Let(x,e1,e2) ok [(.1),(.2),(.6)] (.10) ∅ ⊦ e1 ok [Inversion of ok(4)] (.11) {x} ⊦ e2 ok [Inversion of ok(4)] (.12) ∅ ⊦ e1' ok [(.8),(.10): induction] (.13) ∅ ⊦ Let(x,e1',e2) ok [(.11),(.12),ok(4)] (.14) ∅ ⊦ e' ok [(.7),(.13)] (.15) ∅ ⊦ target(d) ok [(.3),(.14)] (.16) P(d) [(.1),(.15), => Intro; QED case] (.5) case: d = R5(x,n,e2) (.1) ∅ ⊦ source(d) ok [hyp] (.2) let e = source(d) [defn] (.2) let e' = target(d) [defn] (.3) e = Let(x, Num(n), e2) [S5] (.4) e' = [Num(n)/x]e2 [T5] (.5) ∅ ⊦ Let(x,Num(n),e2) ok [(.1),(.2),(.3)] (.6) ∅ ⊦ Num(n) ok [(.5), inversion of ok(5)] (.7) {x} ⊦ e2 ok [(.5), inversion of ok(5)] (.8) ∅ ⊦ [Num(n)/x]e2 ok [(.6),(.7), Subst. Lemma] (.9) ∅ ⊦ e' ok (.10) ∅ ⊦ target(d) ok (.11) P(d) [(.1),(.10),=> Intro; QED case] (3) ∀d. P(d) [(2), I.P; QED] ------------------------- Lemma 4.6 [Progress]: ∅ ⊦ e ok => e a value ∨ ∃e'. e ↦ e'. Proof: By induction on the derivation of ∅ ⊦ e ok. We define a function value: expr → bool by value(Num n) = true value(e) = false otherwise (0) P(d) = context(d) = ∅ => value(subject(d)) ∨ ∃e'. subject(d) ↦ e' [defn] (1) ∀d. P(d) [TBS] (2) let d ∈ Der[ok] [decl d] (3) Induction on structure of d [induction] (.1) case: d = OK1(Γ,n) [case hyp] (.1) let e = subject(d) = Num(n) [defn, S1] (.2) value(e) [defn value] (.3) P(d) [(.2): QED case] (.2) case: d = OK2(Γ, y) [case hyp] (.1) let Γ = context(d) [defn Γ] (.2) y ∈ Γ [L4.2(1): inversion] (.3) Γ ≠ ∅ [(.2)] (.4) P(d) [(.3),vacuously: QED case] (.3) case: d = OK3(bop,d1,d2) [case hyp] (.1) context(d) = ∅ [hyp] (.2) Let e1 = subject(d1) [defn e1] (.3) Let e2 = subject(d2) [defn e2] (.4) Let e = subject(d) [defn e] (.5) e = Bapp(bop, e1, e2) [S3] (.6) context(d1) = ∅ [(.1), L4.2(2)] (.7) context(d2) = ∅ [(.1), L4.2(2)] (.8) context(d1) = ∅ => value(e1) ∨ ∃e1'.e1 ↦ e1' [IH: P(d1)] (.9) context(d2) = ∅ => value(e2) ∨ ∃e2'.e2 ↦ e2' [IH: P(d2)] (.10) value(e1) ∨ ∃e1'.e1 ↦ e1' [(.6),(.8)] (.11) value(e2) ∨ ∃e2'.e2 ↦ e2' [(.7),(.9)] (.12) cases (.10) [∨ cases] (.1) case: value(e1) [case hyp] (.1) e1 = Num(n1) [defn n1] (.2) cases (.11) [∨ cases] (.1) case: value(e2) [case hyp] (.1) e2 = Num(n2) [defn n2] (.2) e ↦ Num(n1+n2) [↦(1)] (.3) ∃e'.e ↦ e' [(.2), ∃ Intro] (.4) value(e) ∨ ∃e'.e ↦ e' [(.2), ∨ Intro] (.5) P(d) [(3.3.1),(.4), => Intro] (.2) case: ∃e2'. e2 ↦ e2' [case hyp] (.1) e2 ↦ e2' [case, ∃ Elim(e2')] (.2) e ↦ Bapp(bop,e1',e2) [↦(2)] (.3) ∃e'.e ↦ e' [(.2), ∃ Intro] (.4) value(e) ∨ ∃e'.e ↦ e' [(.2), ∨ Intro] (.5) P(d) [(.1),(.4), => Intro] (.2) case: ∃e1'. e1 ↦ e1' [case hyp] (.1) e1 ↦ e1' [case, ∃ Elim(e1')] (.2) e ↦ Bapp(bop,e1',e2) [↦(2)] (.3) ∃e'.e ↦ e' [(.2), ∃ Intro] (.4) value(e) ∨ ∃e'.e ↦ e' [(.2), ∨ Intro] (.5) P(d) [(.1),(.4), => Intro] (.13) P(d) [(.12): QED case] (.4) case: d = OK4(x,d1,d2) [case hyp] (.1) context(d) = ∅ [hyp] (.2) let e1 = subject(d1) [defn e1] (.3) let e2 = subject(d2) [defn e2] (.4) let e = subject(d) [defn e] (.5) e = Let(x,e1,e2) [S4] (.6) context(d1) = ∅ [(.1), L4.2(3)] (.7) context(d1) = ∅ => value(e1) ∨ ∃e1'.e1 ↦ e1' [IH: P(d1)] (.8) value(e1) ∨ ∃e1'.e1 ↦ e1' [(.7),(.8)] (.9) cases (.8) [∨ cases] (.1) case: value(e1) [case hyp] (.1) e ↦ [e1/x]e2 [↦(5)] (.2) ∃e'. e ↦ e' [(.1), ∃ Intro] (.3) value (e) ∨ ∃e'. e ↦ e' [(.2), ∨ Intro] (.4) P(d) [(.3),(3.4.1), => Intro] (.2) case: ∃e1'.e1 ↦ e1' [case hyp] (.1) e1 ↦ e1' [case, ∃ Elim(e1')] (.2) e ↦ Let(x,e1',e2) [↦(4)] (.3) ∃e'. e ↦ e' [(.2), ∃ Intro] (.4) value (e) ∨ ∃e'. e ↦ e' [(.3), ∨ Intro] (.5) P(d) [(.4), (3.4.1), => Intro] (.10) P(d) [(.9): QED] ---------------------------------------------------------------------- The following Theorem is often paraphrased as "evaluation of a closed expression will not get stuck". Theorem 4.7. If ∅ ⊦ e ok, then either evaluation of e diverges, or ∃n. e ↦! Num(n). Proof. Suppose e ↦* e'. We can prove that ∅ ⊦ e' ok using the Preservation Lemma (Lemma 4.5) and induction on the definition of ↦*. Thus each step of evaluation Lemma 4.6 applies, and we are either finished, if e' = Num(n), or we can continue with another transition, e' ↦ e''.