ReynoldsCh05

ReynoldsCh05 - Adding Effects The fail Command Syntax...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Adding Effects: The fail Command Syntax: comm ::= fail Semantics: Must terminate program execution immediately, reporting the last state encountered. ⇒ failure is similar to nontermination: if any executed command diverges, the whole program diverges if any executed command fails, the whole program fails ⇒ semantics of sequencing may use a lifting function similar to (−)⊥ ⊥ but propagating failure instead of nontermination The Failure Domain The semantic domain must be extended to account for failure: ˆ def Σ = Σ ∪ ({abort} × Σ) ￿ ￿ {normal, abort} × Σ (more abstract) Σ+Σ The meanings of commands are now of type [[c]]comm ˆ ∈ Σ → (Σ)⊥ [[fail]]comm σ = ￿abort, σ ￿ Semantic equations for the primitive commands remain “unchanged”: [[v := e]]comm σ = [σ | v : [[e]]intexp σ ] [[skip]]comm σ = σ but more abstractly they are modified to [[v := e]]comm σ = ￿normal, [σ | v : [[e]]intexp σ ]￿ [[skip]]comm σ = ￿normal, σ ￿ Sequential Composition with Failure Semantics of sequential composition uses another lifting: [[c0 ; c1]]comm = ([[c1]]comm )∗ · [[c0]]comm ˆ ˆ ˆ where for every f ∈ S → T⊥ the function f∗ ∈ S⊥ → T⊥ is defined by f∗ ⊥ = ⊥ f∗￿normal, x￿ = f x f∗￿abort, x￿ = ￿abort, x￿ The semantics of while was defined using that of sequencing, so def [[while b do c]]comm = Y[Σ→Σ ]F ˆ ⊥ where F f σ = if [[b]]boolexp σ = true then f∗([[c]]comm σ ) else ￿normal, σ ￿ Note: These commands are semantically equivalent (for any command c) in a language without failure, but not in one with: c ; while true do skip while true do skip Local Declarations with Failure: Problem Recall the semantics of local declarations [[newvar v := e in c]]comm σ = ([− | v : σ v ])⊥ ([[c]]comm [σ | v : [[e]]intexp σ ]) ⊥ The na¨ve generalization in the presence of failure ı [[newvar v := e in c]]comm σ = ([− | v : σ v ])∗ ([[c]]comm [σ | v : [[e]]intexp σ ]) doesn’t quite work: if c fails, the result shows the state when c failed: [[newvar x:= 1 in fail]]comm σ = ￿abort, [σ | x : 1]￿ so names of local variables can be exported out of scope ⇒ renaming does not preserve meaning: [[x:= 0 ; newvar x:= 1 in fail]]comm σ = ￿abort, [σ | x : 1]￿ [[x:= 0 ; newvar y:= 1 in fail]]comm σ = ￿abort, [σ | x : 0 | y : 1]￿ Conclusion: The old bindings of local variables must be restored even when the result is in {abort} × Σ. Local Declarations with Failure: Solution ˆ ˆ Use yet another lifting function to restore bindings: if f ∈ S → T , then f† ∈ S⊥ → T⊥ f† ⊥ = ⊥ f†￿abort, x￿ = ￿abort, f x￿ Then f†￿normal, x￿ = ￿normal, f x￿ [[newvar v := e in c]]comm σ = ([− | v : σ v ])† ([[c]]comm [σ | v : [[e]]intexp σ ]) Effectively failure is “caught” at local declarations and “re-raised” after the old binding is restored. Semantics of Failure ˆ Σ = {normal, abort} × Σ [[c]]comm ˆ ∈ Σ → (Σ)⊥ [[fail]]comm σ = ￿abort, σ ￿ [[v := e]]comm σ = ￿normal, [σ | v : [[e]]intexp σ ]￿ [[skip]]comm σ = ￿normal, σ ￿ [[c0 ; c1]]comm σ = ([[c1]]comm )∗([[c0]]comm σ ) [[newvar v := e in c]]comm σ = ([− | v : σ v ])† ([[c]]comm [σ | v : [[e]]intexp σ ]) f∗ ⊥ = ⊥ f∗￿normal, σ ￿ = f σ f∗￿abort, σ ￿ = ￿abort, σ ￿ f† ⊥ = ⊥ f†￿normal, σ ￿ = ￿normal, f σ ￿ f†￿abort, σ ￿ = ￿abort, f σ ￿ (the equations for the conditional and the loop look unchanged) Specifications with Failure Recall semantics of total and partial correctness: [[[p] c [q ]]]spec = ∀σ ∈ Σ. [[p]]assert σ ⇒ ([[c]]comm σ ￿= ⊥ and [[q ]]assert ([[c]]comm σ )) [[{p} c {q }]]spec = ∀σ ∈ Σ. [[p]]assert σ ⇒ ([[c]]comm σ = ⊥ or [[q ]]assert ([[c]]comm σ )) Our assertion language cannot handle results in {abort} × Σ, so we treat these results as failing to satisfy an assertion: [[[p] c [q ]]] = ∀σ ∈ Σ. [[p]]σ ⇒ ([[c]]σ ∈ {⊥} ∪ ({abort} × Σ) and [[q ]]([[c]]σ )) / [[{p} c {q }]] = ∀σ ∈ Σ. [[p]]σ ⇒ ([[c]]σ ∈ {⊥} ∪ ({abort} × Σ) or [[q ]]([[c]]σ )) Then the strongest rules for fail are (FLT) [false] fail [false] (FLP) {true} fail {false} More Effects: Intermediate Output Syntax: comm ::= !intexp Intended semantics: !e outputs the value of e (and then the execution continues). Major change in program meaning: Even two nonterminating programs may have observably different behaviors. Part of the result of executing a program is its output, which can be an infinite object. Semantics of Output: The Domain of Sequences Example: !0 ; while n ≥ 0 do if n ￿= 0 then (!n ; n:= n+1) else skip A program can behave in one of three ways: Output a finite sequence and then terminate (normally or failing) Output a finite sequence and then diverge without further output Output an infinite sequence ⇒ the output domain can be defined (up to isomorphism) as def Ω= ∞ ￿ n=0 (Zn ˆ × Σ) ∪ ∞ ￿ n=0 Zn ∪ ZN Partial Order in the Domain of Sequences The partial order should reflect the idea that ω ￿ ω ￿ if output ω ￿ is “more defined” than output ω . If “more defined” is interpreted with respect to the length of observation, we get ω ￿ ω ￿ ⇐⇒ ω is a prefix of ω ￿ Then the empty sequence ￿￿ is the least element of Ω. There are three kinds of chains in Ω: (diverging with finite output) ￿￿ ￿ ￿7￿ ￿ ￿7, 0￿ ￿ ￿7, 0￿ ￿ ￿7, 0￿ ￿ . . . ￿￿ ￿ ￿7￿ ￿ ￿7, 0￿ ￿ ￿7, 0, σ ￿ ￿ ￿7, 0, σ ￿ ￿ . . . ˆ ˆ (terminating) ￿￿ ￿ ￿7￿ ￿ ￿7, 0￿ ￿ ￿7, 0, 7￿ ￿ ￿7, 0, 7, 1￿ ￿ . . . Only chains of the latter kind are interesting, and their limits are in Ω since ZN ⊆ Ω: if ω0 ￿ ω1 ￿ . . . is such a chain, then ∞ ￿ n=0 ωn = { [i, ωj i] | j ∈ N and i ∈ dom ωj } The Domain of Sequences as an Initial Continuous Algebra Idea: represent Ω = ∞ ￿ n=0 ˆ (Zn × Σ) ∪ ∞ ￿ n=0 Zn ∪ ZN using abstract syntax. The constructors are ι⊥ ∈ {{}} → Ω ιterm ∈ Σ → Ω ιabort ∈ Σ → Ω ιout ∈ Z × Ω → Ω (+ is concatenation of sequences) + ι⊥ ￿￿ = ￿￿ ιterm σ = ￿σ ￿ ιabort σ = ￿￿abort, σ ￿￿ ιout ￿n, ω ￿ = ￿n￿ + ω + Finite applications of constructors define an initial algebra – the finite sequences in Ω. Completing this set with its limits defines Ω as an initial continuous algebra. Semantics in the Domain of Sequences The semantic equations become [[−]]comm ∈ comm → Σ → Ω [[skip]]comm σ = ιterm σ [[v := e]]comm σ = ιterm [σ | v : [[e]]intexp σ ] [[fail]]comm σ = ιabort σ [[!e]]comm σ = ιout ￿[[e]]intexp σ, ιterm σ ￿ [[c0 ; c1]]comm σ = ([[c1]]comm )∗([[c0]]comm σ ) [[newvar v := e in c]]comm σ = ([− | v : σ v ])† ([[c]]comm [σ | v : [[e]]intexp σ ]) f∗ ⊥ = ⊥ f∗(ιterm σ ) = f σ f∗(ιabort σ ) = ιabort σ f∗(ιout ￿n, ω ￿) = ιout ￿n, f∗ ω ￿ f† ⊥ = ⊥ f†(ιterm σ ) = ιterm (f σ ) f†(ιabort σ ) = ιabort (f σ ) f†(ιout ￿n, ω ￿) = ιout ￿n, f† ω ￿ (the equations for the conditional and the loop still look unchanged) Semantics of Output: An Example [[!3 ; !6 ; fail]] σ = = = = = = = = = [[fail]]∗ ([[!6]]∗ ([[!3]] σ )) [[fail]]∗ ([[!6]]∗ (ιout ￿3, ιterm σ ￿)) [[fail]]∗ (ιout ￿3, [[!6]]∗ (ιterm σ )￿) [[fail]]∗ (ιout ￿3, [[!6]] σ ￿) [[fail]]∗ (ιout ￿3, ιout ￿6, ιout ￿3, [[fail]]∗ (ιout ￿6, ιterm σ ￿￿) ιterm σ ￿)￿ ιout ￿3, ιout ￿6, [[fail]]∗ (ιterm σ )￿￿ ιout ￿3, ιout ￿6, [[fail]] σ ￿￿ ιout ￿3, ιout ￿6, ιabort σ ￿￿ f∗ (ιout ￿n, ω ￿) = ιout ￿n, f∗ ω ￿ f∗ (ιterm σ ) = f σ Products of Predomains If P1, . . . , Pn are predomains, then P1 × . . . × Pn is the predomain over their Cartesian product { ￿x1, . . . , xn￿ | x1 ∈ P1 and . . . and xn ∈ Pn } with the induced componentwise partial order ￿x1, . . . , xn￿ ￿ ￿y1, . . . , yn￿ ⇐⇒ x1 ￿1 y1 and . . . and xn ￿n yn and limit ∞ ￿ ∞ ∞ ￿ 1 (i) ￿ n (i) (i) (i) ￿ x1 , . . . , x n ￿ = ￿ x1 , . . . , xn ￿ i=0 i=0 i=0 If Pk are domains, then ￿⊥1, . . . , ⊥n￿ is the least element of P1 × . . . × Pn. n Then the projections πk are continuous functions, and if fi are continuous, then so are f1 ⊗ . . . ⊗ fn and f1 × . . . × fn. Sums of Predomains If P1, . . . , Pn are predomains, then P1 + . . . + Pn is the predomain over their sum { ￿0, x￿ | x ∈ P1 } ∪ . . . ∪ { ￿n − 1, x￿ | x ∈ Pn } ordered by the injected partial orders of the components: ￿i, x￿ ￿ ￿j, y ￿ ⇐⇒ i = j and x ￿i y. All elements in a chain in P1 + . . . + Pn have the same tag, and the limit is ∞ ￿ i=0 ￿j, xi￿ = ￿j, ∞ ￿ i=0 j xi ￿ P1 + . . . + Pn is a domain only if n = 1 and P1 is a domain. The injections ιn are continuous functions, and if fi are continuous, then so are k f1 ⊕ . . . ⊕ fn and f1 + . . . + fn. Recursive Isomorphism for the Domain of Outputs Ω ∼ = ￿σ ￿ ￿￿￿￿￿￿. . .￿￿￿￿￿￿ ￿￿abort,￿ σ ￿￿ ￿ ... ￿￿￿ ￿￿￿ ￿￿ ￿ ￿￿ ￿￿ ￿ ￿￿￿ ￿￿￿ ￿￿ ￿ ￿ ￿￿ ￿ ￿￿￿ ￿￿￿ ￿ ￿ ￿￿ ￿ ￿￿￿ ￿ ￿￿ ￿ ￿ ￿￿￿ ￿ ￿￿ ￿￿￿ ￿￿￿ ￿ ￿ ￿￿ ￿ ￿ ￿￿ ￿ ￿￿￿ ￿ ￿￿￿ ￿ ￿￿ ￿￿￿ ￿ ￿￿￿ ￿ ￿￿ ￿ ￿ ￿￿ ￿￿ ￿￿￿ ￿ ￿ ￿￿ ￿ ￿￿￿ ￿ ￿￿￿ ￿￿￿ ￿ ￿￿￿ ￿￿ ￿ ￿ ￿￿ ￿ ￿￿￿ ￿ ￿ ￿￿ ￿ ￿ ￿ ￿￿￿ ￿￿￿ ￿ ￿￿￿ ￿￿￿ ￿ ￿￿ ￿ ￿￿ ￿ ￿￿ ￿ ￿￿ ￿ ￿￿￿ ￿ ￿ ￿￿ ￿ ￿ ￿￿￿￿ ￿￿￿￿ ￿ ￿ ￿ ￿￿ ￿￿ ￿￿ ￿ ￿￿ ￿￿￿ ￿￿￿ ￿￿ ￿￿￿￿ ￿￿ ￿￿￿ ￿0, Ω ￿ ￿1, Ω ￿ ... ￿￿ ￿￿￿ ￿￿￿ ￿ ￿ ￿￿ ￿￿￿ ￿￿￿ ￿ ￿￿￿ ￿￿￿ ￿￿￿ ￿ ￿￿￿ ￿￿ ￿￿ ￿￿ ￿ ￿￿￿ ￿￿￿ ￿￿￿ ￿￿￿ ￿￿￿ ￿￿￿ ￿￿ ￿ ￿￿ ￿ ￿￿ ￿ ￿￿￿ ￿￿￿ ￿￿￿ ￿￿￿ ￿￿￿￿￿ ￿￿￿ ￿￿ ￿ ￿ ￿￿ ￿￿ ￿ ￿￿￿ ￿￿ ￿￿￿ ￿￿￿ ￿￿￿￿￿￿￿￿￿￿ ￿￿￿ ￿ ￿￿ ￿￿￿ ￿ ￿￿￿ ￿￿￿￿ ￿￿ ￿￿￿ ￿￿￿￿ ￿￿ ￿￿ ￿￿￿￿￿ ￿￿ ￿ ￿￿ ￿￿ ∼ Ω = (Σ + Σ + Z × Ω)⊥ ∃ φ ∈ Ω → (Σ + Σ + Z × Ω)⊥ ψ ∈ (Σ + Σ + Z × Ω) → Ω ⊥ such that ψ · φ = IΩ φ · ψ = I(Σ+Σ+Z×Ω)⊥ ιterm = ψ · ι↑ · ι0 ∈ Σ → Ω ιabort = ψ · ι↑ · ι1 ∈ Σ → Ω ιout = ψ · ι↑ · ι2 ∈ Z × Ω → Ω Intermediate Input: the Domain of Resumptions Syntax: comm ::= ?var Domain of program behaviors Ω ￿ ω : ω = ⊥ ⇒ the program runs forever without output or input ω = ιterm σ ⇒ the program terminates normally in state σ ω = ιabort σ ⇒ the program fails in state σ ω = ιout ￿n, ω ￿￿ ⇒ the program outputs n and then has behavior ω ￿ for g ∈ Z → Ω: ω = ιin g ⇒ if the program inputs n, it has behavior g n. ∼ Ω = (Σ + Σ + (Z × Ω) + (Z → Ω))⊥ ιin = ψ · ι↑ · ι3 ∈ (Z → Ω) → Ω Semantics of Intermediate Input [[?v ]]comm σ = ιin (λn ∈ Z. ιterm [σ | v : n]) f∗ ⊥ = ⊥ f† ⊥ = ⊥ f∗(ιterm σ ) = f σ f∗(ιabort σ ) = ιabort σ f∗(ιout ￿n, ω ￿) = ιout ￿n, f∗ ω ￿ f∗(ιin g ) = ιin (λn ∈ Z. f∗ (g n)) [[?x ; !x]]σ = = = = = = f†(ιterm σ ) = ιterm (f σ ) f†(ιabort σ ) = ιabort (f σ ) f†(ιout ￿n, ω ￿) = ιout ￿n, f† ω ￿ f†(ιin g ) = ιin (f† · g ) [[!x]]∗ ([[?x]] σ ) [[!x]]∗ (ιin (λn ∈ Z. ιterm [σ | x : n])) ιin (λn ∈ Z. [[!x]]∗ (ιterm [σ | x : n])) ιin (λn ∈ Z. [[!x]] [σ | x : n]) ιin (λn ∈ Z. ιout ￿[[x]] [σ | x : n], ιterm [σ | x : n]￿) ιin (λn ∈ Z. ιout ￿n, ιterm [σ | x : n]￿) Continuation Semantics In an implementation of c0 ; c1, the semantics of c1 has no bearing on the result if c0 fails to terminate ⇒ the semantics of c0 determines whether c1 will be executed or not. But from the direct semantics of sequencing [[c0 ; c1]] σ = [[c1]]∗ ([[c0]] σ ) it looks as if the semantics of c1 determines the result; much machinery hidden in (−)∗ to rectify this. The semantics of output ω = ιout ￿n, ω ￿￿ ⇒ the program outputs n and then has behavior ω ￿ also suggests it would be easier to explain a behavior in terms of what to do next, or its continuation behavior. Continuation Semantics cont’d Idea: let the semantic function take an extra argument κ ∈ Σ → Ω which describes the behavior of the rest of the program. Then [[−]]comm ∈ comm → (Σ → Ω) → Σ → Ω [[skip]] κ σ = κ σ [[v := e]] κ σ = κ [σ | v : [[e]]intexp σ ] [[if b then c else c￿]] κ σ = if [[b]]assert σ then [[c]] κ σ else [[c￿]] κ σ [[c0 ; c1]] κ σ = [[c0]] (λσ ￿ ∈ Σ. [[c1]] κ σ ￿) σ = [[c0]] ([[c1]] κ) σ i.e. [[c0 ; c1]] = [[c0]] · [[c1]] [[while b do c]] κ = YΣ→Ω F where F κ￿ σ = if [[b]]σ then [[c]] κ￿ σ else κ σ [[newvar v := e in c]] κ σ = [[c]] (λσ ￿ ∈ Σ. κ [σ ￿ | v : σ v ]) [σ | v : [[e]]σ ] [[c]]cont κ σ = κ⊥ ([[c]]direct σ ), in particular [[c]]direct = [[c]]cont ι↑ ⊥ comm comm comm comm Continuation Semantics def Idea: let the semantic function take an extra argument κ ∈ K (where K = Σ → Ω) which is its continuation: it describes the behavior of the rest of the program, produces an answer in Ω when applied to an initial state in Σ. [[−]]comm ∈ comm → (Σ → Ω) → Σ → Ω i.e. the semantics of a command maps continuations to continuations: [[−]]comm ∈ comm → K → K [[skip]] κ = λσ ∈ Σ. κ σ =κ i.e. [[skip]] = IK [[v := e]] κ = λσ ∈ Σ. κ [σ | v : [[e]]intexp σ ] [[c0 ; c1]] κ = λσ ∈ Σ. [[c0]] (λσ ￿ ∈ Σ. [[c1]] κ σ ￿) σ = λσ ∈ Σ. [[c0]] ([[c1]] κ) σ = [[c0]] ([[c1]] κ) i.e. [[c0 ; c1]] = [[c0]] · [[c1]] More Continuation Semantics [[if b then c else c￿]] κ = λσ ∈ Σ. if [[b]]assert σ then [[c]] κ σ else [[c￿]] κ σ [[while b do c]] κ = [[if b then (c ; while b do c) else skip]] κ = λσ ∈ Σ. if [[b]]assert σ then ([[c]] · [[while b do c]]) κ σ else κ σ = λσ ∈ Σ. if [[b]]assert σ then [[c]] ([[while b do c]] κ) σ else κ σ = F ([[while b do c]] κ), where F κ￿ = λσ ∈ Σ. if [[b]]assert σ then [[c]] κ￿ σ else κ σ [[while b do c]] κ = YΣ→Ω F where F κ￿ σ = if [[b]]σ then [[c]] κ￿ σ else κ σ [[newvar v := e in c]] κ = λσ ∈ Σ. [[c]] (λσ ￿ ∈ Σ. κ [σ ￿ | v : σ v ]) [σ | v : [[e]]σ ] Relationship Between Direct and Continuation Semantics The connection is that [[c]]cont κ σ = κ⊥ ([[c]]direct σ ) ⊥ comm comm i.e. [[c]]cont κ = κ⊥ · [[c]]direct ⊥ comm comm which can be shown by structural induction on comm , e.g. [[skip]]cont κ = IK κ = κ κ⊥ · [[skip]]direct = κ⊥ · IΣ = κ ⊥ ⊥ [[c ; c￿]]cont κ = [[c]]cont ([[c￿]]cont κ) = [[c]]cont (κ⊥ · [[c￿]]direct ) ⊥ = (κ⊥ · [[c￿]]direct )⊥ · [[c]]direct ⊥ ⊥ = κ⊥ · ([[c￿]]direct )⊥ · [[c]]direct = κ⊥ · [[c ; c￿]]direct ⊥ ⊥ ⊥ When the “final” (or “top-level”) continuation is the injection ι↑ ∈ Σ → Σ⊥, then [[c]]cont ι↑ = (ι↑)⊥ · [[c]]direct ⊥ comm comm i.e. [[c]]direct = [[c]]cont ι↑ comm comm Continuation Semantics of Extensions For input and output, [[!e]] κ = λσ ∈ Σ. ιout ￿[[e]]intexp σ, κ σ ￿ [[?v ]] κ = λσ ∈ Σ. ιin (λn ∈ Z. κ [σ | v : n]) The relationship between direct and continuation semantics is then [[c]]cont κ σ = κ∗ ([[c]]direct σ ) comm comm or [[c]]cont κ = κ∗ · [[c]]direct comm comm Failure ignores the given continuation and directly produces a result ⇒ one might expect [[fail]] κ σ = ιterm σ but this does not work: local variables are not reset to their original bindings. Continuation Semantics of Failure So we have to introduce a second, abortive continuation, which the semantics of failure invokes and of local declarations augments: [[−]]comm ∈ comm → K → K → K [[skip]] κt κf = κt [[v := e]] κt κf = λσ ∈ Σ. κt [σ | v : [[e]]intexp σ ] [[c0 ; c1]] κt κf = [[c0]] ([[c1]] κt κf ) κf [[if b then c else c￿]] κt κf = λσ ∈ Σ. if [[b]]assert σ then [[c]] κt κf σ else [[c￿]] κt κf σ [[while b do c]] κt κf = YΣ→Ω F where F κ￿ σ = if [[b]]σ then [[c]] κ￿ κf σ else κt σ [[newvar v := e in c]] κt κf = λσ ∈ Σ. [[c]] (λσ ￿ ∈ Σ. κt [σ ￿ | v : σ v ]) (λσ ￿ ∈ Σ. κf [σ ￿ | v : σ v ]) [σ | v : [[e]]σ ] [[!e]] κt κf = λσ ∈ Σ. ιout ￿[[e]]intexp σ, κt σ ￿ [[?v ]] κt κf = λσ ∈ Σ. ιin (λn ∈ Z. κt [σ | v : n]) [[fail]] κt κf = κf ...
View Full Document

{[ snackBarMessage ]}

Ask a homework question - tutors are online