COP 5021 Lecture -*- Outline -*- * Structural Operational Semantics (2.2.1) *** varieties ------------------------------------------ KINDS OF STRUCTURAL OPERATIONAL SEMANTICS Big step: specifies relation between initial and final state Small step: specifies relation between a state and next state ------------------------------------------ Q: How would infinite loops be treated in each type of semantics? For big step would need a way to represent infinite loops (\bot) For small step can just keep going... *** terminal transition system, little step, computation semantics terminal transition system (Plotkin), little step (C. Gunter), computation (M. Hennessy) essentially using rewriting as a universal machine This is currently the most widely used kind of semantics (possibly because it handles parallelism and nondeterminism well) **** idea To give the semantics of a programming language, use two auxiliary functions: input and output ------------------------------------------ COMPUTATION (LITTLE STEP) SEMANTICS Meaning Programs <- -- - -> Answers | ^ input | | output | | v reducesto* | Gamma <-----------> T def: a in Meaning[[P]] iff ------------------------------------------ the Meaning relation is often partial, and defined by going around the diagram ... there is a g in T such that input[[P]] reducesto* g and output(g) = a. Meaning[[P]] is a function when reducesto* is Church-Rosser (confluent) **** terminal transition systems this is the guts of the system, defining the abstract machine by defining --> (reducesto) ------------------------------------------ TERMINAL TRANSITION SYSTEM (TTS) (Gamma, -->, Terminal) Gamma : --> : Terminal : reducesto* reflexive, transitive closure ------------------------------------------ ... a set of configurations (e.g., g) i.e., configurations of the abstract machine ... a binary relation on Gamma (steps, transitions) --> is sometimes written as ==> (I used reducesto in Prolog) ... subset of terminal configurations (Plotkin called it T), must be such that if g in Terminal, then there is no g' such that (g --> g') *** semantics of the while language (2.2.1) ------------------------------------------ CONFIGURATIONS AND TRANSITIONS Configurations (Gamma): Gamma = (Stmt x State) + State s in State = Var -> Z Terminal Configurations: Terminal = State ------------------------------------------ Q: What does a configuration of the form (S, s) mean? statement S is executing and state s is the current state Q: What does a configuration of the form s mean? state s is a terminal (final) state Q: Must every execution reach a final state? no, there could be an infinite loop! Note that we're ignoring errors like division by zero... but those could be modeled with a special kind of "error state" Q: What part of the state does an expression depend on? only the values of its free variables Lemma: Let a \in AExp be given. If (\forall x \in FV(a) :: s1(x) = s2(x)) then A[[a]]s1 = A[[a]]s2. The proof is by structural induction (on the structure of expressions) ------------------------------------------ TRANSITIONS (Table 2.6) [asg] ([x := a]^l, s) --> s[x |-> A[[a]]s] [skip] ([skip]^l, s) --> s (S1, s) --> (S1', s') [seq1] -------------------------- (S1;S2, s) --> (S1';S2, s') (S1, s) --> s' [seq2] -------------------------- (S1;S2, s) --> (S2, s') [if1] (if [b]^l then S1 else S2, s) --> (S1, s) if B[[b]]s = true [if2] (if [b]^l then S1 else S2, s) --> (S2, s) if B[[b]]s = false [wh1] (while [b]^l do S, s) --> (S; while [b]^l do S, s) if B[[b]]s = true [wh2] (while [b]^l do S, s) --> s if B[[b]]s = false ------------------------------------------ Q: What do the sequence rules do? Q: Do the rules allow evaluation of the true or false part of an if-statement before evaluating the condition? no Q: How do the wh1 and wh2 rules work? The wh1 rule puts the body S to be executed in sequence with the loop, if the condition is true, so it will execute the body S and then loop again The wh2 rule finishes the execution, if the condition is false ------------------------------------------ EXAMPLE Program [q := 0]^1; [r := x]^2; while [r >= y]^3 do ([r := r-y]^4; [q := q+1]^5) Name each statement S_i if it has label i Let S_123 be the whole program (a sequence) Let S_3 be the while loop Let S_23 be the sequential composition of S_2 and S_3 Let S_45 be the body of the while loop Let sqrxy be the state in which q has value q, ..., y has value y E.g, s7062(q) = 7, s0062(x) = 6. (S_123, s7062) --> {by [seq2]} * ([q := 0]^1, s7062) --> {by [asg]} s0062 . (S_23, s0062) --> {by [seq2]} * <[r := x]^2, s0062) --> {by [asg]} s0662 . (S_3, s0662) --> {by [wh1], since B[[r >= y]](s0662) = true} (S_45; S_3, s0662) --> {by [seq1]} * (S_45, s0662) --> {by [seq2]} * <[r := r-y]^4, s0662) --> {by [asg]} s0462 . (S_5, s0462) . (S_5; S_3, s0462) --> ------------------------------------------ Q: How are the labels used in the semantics? they aren't Q: What would be the rule(s) for a one-armed if-statement? [if1-true] (if [b]^l then S, s) --> (S,s) if B[[b]]s = true [if1-false] (if [b]^l then S, s) --> s if B[[b]]s = false or [if1] (if [b]^l then S, s) --> (if [b]^l then S else skip, s) Q: How would you add rule(s) for a for loop of the form for x := a1..a2 do S ? [for-start] (for x:=a1..a2 do S, s) --> (for x=n1..n2 do S, s) if A[[a1]]s = n1, A[[a2]]s = n2, and a1, a2 \not\in NumericLiteral [for-do] (for x:=n1..n2 do S, s) --> (S; for x=n3..n2 do S, s[x |-> N(n1)]) if n1,n2 \in NumericLiteral and N(n1)<=N(n2) and N(n3)=N(n1)+1 [for-done] (for x:=n1..n2 do S, s) --> s' if N(n1)>N(n2) and s' is s with x removed from its domain Q: What would be the rule(s) for a exitblock statement, where blocks have the syntax begin S end and the exitblock statement has the syntax exitblock ? (S, s) --> (S', s') [block0] --------------------------------------- (block S end, s) --> (begin S' end, s') if S is not exitblock (S, s) --> s' [block1] --------------------------------------- (block S end, s) --> s' [exitblock0] (exitblock, s) --> s [seq1] (exitblock; S2, s) --> s Q: What would need to be done to have a semantics of assert statements with syntax: assert [b]^l ? need to add a new kind of error state State = normal:(Var -> Z) + error:(String) so err(msg) in State s in State [asrtT] (assert [b]^l, s) --> s if B[[b]] = true [asrtT] (assert [b]^l, s) --> error("assertion b at l failed!") if B[[b]] = false [seq2] (S, error(msg)) --> error(msg) Note: this last rule is essentially a rule that says "abort execution when there is an error" Q: What would need to be done to have a semantics of case statements with syntax case e of left(x) then S1 [] right(y) of S2 end that observes a tagged union expression (e) ? Need a domain of values Value = Z + ({left,right} x Z) and expressions with syntax injectLeft(a), injectRight(a) such that E[[injectLeft(a)]](s) = (left, E[[a]](s)) and E[[injectRight(a)]](s) = (right, E[[a]](s)) and then add the rules: E[[e]]s --> (left, a) [case-left] ---------------------------------- (case e of left(x) then S1 [] right(y) of S2 end, s) --> (S1, s[x |-> a]) E[[e]]s --> (right, a) [case-right] ---------------------------------- (case e of left(x) then S1 [] right(y) of S2 end, s) --> (S2, s[y |-> a]) *** properties of WHILE's semantics To try to prove something about an analysis based on the semantics we must relate the CFG and the configurations. Q: As the configurations evolve, does the CFG for the statement in the configuration change? If so, how? Yes, it can become a subgraph ------------------------------------------ PROPERTIES OF WHILE's SEMANTICS How does the flow graph change as the configurations change? Case 1: (S,s) --> (S',s') Compare vs. final(S) final(S') flow(S) flow(S') blocks(S) blocks(S') Case 2: (S,s) --> s' what can we say about the graph of S? ------------------------------------------ ... \supseteq ... \supseteq ... \supseteq (a homework problem) ... final(S) = {init(S)} (S is an elementary block) This is all in lemma 2.1.4