Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Declare Your Language: Type Checking

677 views

Published on

Lecture 6 of compiler construction course about type checking using constraints

Published in: Software
  • Be the first to comment

  • Be the first to like this

Declare Your Language: Type Checking

  1. 1. Hendrik van Antwerpen IN4303 Compiler Construction TU Delft September 2017 Declare Your Language Chapter 6: Name & Type Constraints
  2. 2. Reading Material 2
  3. 3. 3 Type checkers are algorithms that check names and types in programs. This paper introduces the NaBL Name Binding Language, which supports the declarative definition of the name binding and scope rules of programming languages through the definition of scopes, declarations, references, and imports associated. http://dx.doi.org/10.1007/978-3-642-36089-3_18 SLE 2012 Background
  4. 4. 4 This paper introduces scope graphs as a language-independent representation for the binding information in programs. http://dx.doi.org/10.1007/978-3-662-46669-8_9 ESOP 2015
  5. 5. 5 Separating type checking into constraint generation and constraint solving provides more declarative definition of type checkers. This paper introduces a constraint language integrating name resolution into constraint resolution through scope graph constraints. This is the basis for the design of the NaBL2 static semantics specification language. https://doi.org/10.1145/2847538.2847543 PEPM 2016
  6. 6. 6 Documentation for NaBL2 at the metaborg.org website. http://www.metaborg.org/en/latest/source/langdev/meta/lang/nabl2/index.html
  7. 7. Types and Type Checking 7
  8. 8. 8 Source Code Editor Parse Abstract Syntax Tree Type Check Check that names are used correctly and that expressions are well-typed Errors
  9. 9. Goal of type checking - Prove the absence of certain (wrong) runtime behavior ‣ “Well-typed programs cannot go wrong.” [Reynolds1985] - Check correct usage of names, and types of expressions - Beyond catching runtime errors ‣ How many resources are use? ‣ Do calculations respect units? ‣ Is any sensitive information leaked through this function? Types influence language design - Types abstract over implementation ‣ Any value with the correct type is accepted - Types enable separate or incremental compilation ‣ As long as the public interface is implemented, using modules do not change Why types? 9
  10. 10. Many different type system features - Simple types - Sub-typing - Nominal versus structural types - Ad-hoc polymorphism (overloading) - Parametric polymorphism (generics) - Dependent types (vector with length) - Units of numbers (meters vs seconds) 
 
 Feature interaction is not trivial! Why types? 10
  11. 11. Type system specification - (Formal) description of the typing rules - For human comprehension - To prove properties Type checking algorithm - Executable version of the specification - Often contains details that are omitted from the specification 
 
 Developing both is a lot of work, often only an algorithm Type system of a language 11
  12. 12. What should a type checker do? - Resolve names, and check or compute types - Report useful error messages - Provide a representation of name and type information ‣ Type annotated AST ‣ Scope graphs for name binding structure This information is used for - Next compiler steps (optimization, code generation, …) - IDE (error reporting, code completion, refactoring, …) - Other tools (API documentation, …) How are type checkers implemented? - Algorithms for specific languages / feature combinations - Common elements (unification, constraints) How to check types? 12
  13. 13. Type Checking with Constraints 13
  14. 14. Two phase approach - First record constraints (type equality, name resolution) - Then solve constraints Separation of concern - Language specific specification in terms of constraints - Language independent algorithm to solve constraints - Write specification, get an executable checker Advantages - Order of solving independent of order of collection - Natural support for inference - Many constraint-based formulations of typing features exist - Constraint variables act as interface between different kinds of constraints 
 Combining different kinds of constraints is still non-trivial! Constraint-based type checking 14
  15. 15. Computing Type of Expression (recap) 15 function (a : int) = a + 1 rules type-check(|env): Fun(x, t, e) -> FUN(t, t') where <type-check(|[(x, t) | env])> e => t' type-check(|env): Var(x) -> t where <lookup> (x, env) => t type-check(|env): Int(_) -> INT() type-check(|env): Plus(e1, e2) -> INT() where <type-check(|env)> e1 => INT() where <type-check(|env)> e2 => INT() Fun("i", INT(), Plus(Var("i"), Int(1))) FUN(INT(), INT())
  16. 16. rules type-check(|env): Fun(x, e) -> FUN(??, t') where <type-check(|[(x, ??) | env])> e => t' type-check(|env): Var(x) -> t where <lookup> (x, env) => t type-check(|env): Int(_) -> INT() type-check(|env): Plus(e1, e2) -> INT() where <type-check(|env)> e1 => INT() where <type-check(|env)> e2 => INT() Inferring Type of Parameter? 16 function (a) = a + 1 Fun("i", Plus(Var("i"), Int(1))) FUN(??, INT())
  17. 17. rules type-check(|env): Fun(x, e) -> FUN(??, t') where <type-check(|[(x, ??) | env])> e => t' type-check(|env): Var(x) -> t where <lookup> (x, env) => t type-check(|env): Int(_) -> INT() type-check(|env): Plus(e1, e2) -> INT() where <type-check(|env)> e1 => INT() where <type-check(|env)> e2 => INT() Inferring Type of Parameter? 16 function (a) = a + 1 Fun("i", Plus(Var("i"), Int(1))) FUN(??, INT())
  18. 18. rules type-check(|env): Fun(x, e) -> FUN(??, t') where <type-check(|[(x, ??) | env])> e => t' type-check(|env): Var(x) -> t where <lookup> (x, env) => t type-check(|env): Int(_) -> INT() type-check(|env): Plus(e1, e2) -> INT() where <type-check(|env)> e1 => INT() where <type-check(|env)> e2 => INT() Inferring Type of Parameter? 16 function (a) = a + 1 Fun("i", Plus(Var("i"), Int(1))) FUN(??, INT())
  19. 19. rules type-check(|env): Fun(x, e) -> FUN(??, t') where <type-check(|[(x, ??) | env])> e => t' type-check(|env): Var(x) -> t where <lookup> (x, env) => t type-check(|env): Int(_) -> INT() type-check(|env): Plus(e1, e2) -> INT() where <type-check(|env)> e1 => INT() where <type-check(|env)> e2 => INT() Inferring Type of Parameter? 16 function (a) = a + 1 Fun("i", Plus(Var("i"), Int(1))) FUN(??, INT())
  20. 20. Use Variables and Constraints 17 Eq(VAR("a"), INT()) Eq(INT(), INT()) + VAR("a") => INT() rules type-con(|env): Fun(x, e) -> (FUN(t, t'), C) where !VAR(<fresh>) => t; <type-con(|[(x, t) | env])> e => (t', C) type-con(|env): Var(x) -> (t, []) where <lookup> (x, env) => t type-con(|env): Int(_) -> (INT(), []) type-con(|env): Plus(e1, e2) -> (INT(), [ C1, C2, Eq(t1, INT()), Eq(t2, INT()) ]) where <type-con(|env)> e1 => (t1, C2) where <type-con(|env)> e2 => (t2, C1) function (a) = a + 1 Fun("i", Plus(Var("i"), Int(1))) FUN(VAR("a"), INT())
  21. 21. Use Variables and Constraints 17 Eq(VAR("a"), INT()) Eq(INT(), INT()) + VAR("a") => INT() rules type-con(|env): Fun(x, e) -> (FUN(t, t'), C) where !VAR(<fresh>) => t; <type-con(|[(x, t) | env])> e => (t', C) type-con(|env): Var(x) -> (t, []) where <lookup> (x, env) => t type-con(|env): Int(_) -> (INT(), []) type-con(|env): Plus(e1, e2) -> (INT(), [ C1, C2, Eq(t1, INT()), Eq(t2, INT()) ]) where <type-con(|env)> e1 => (t1, C2) where <type-con(|env)> e2 => (t2, C1) function (a) = a + 1 Fun("i", Plus(Var("i"), Int(1))) FUN(VAR("a"), INT())
  22. 22. Use Variables and Constraints 17 Eq(VAR("a"), INT()) Eq(INT(), INT()) + VAR("a") => INT() rules type-con(|env): Fun(x, e) -> (FUN(t, t'), C) where !VAR(<fresh>) => t; <type-con(|[(x, t) | env])> e => (t', C) type-con(|env): Var(x) -> (t, []) where <lookup> (x, env) => t type-con(|env): Int(_) -> (INT(), []) type-con(|env): Plus(e1, e2) -> (INT(), [ C1, C2, Eq(t1, INT()), Eq(t2, INT()) ]) where <type-con(|env)> e1 => (t1, C2) where <type-con(|env)> e2 => (t2, C1) function (a) = a + 1 Fun("i", Plus(Var("i"), Int(1))) FUN(VAR("a"), INT())
  23. 23. 18 Source Code Editor Parse Abstract Syntax Tree Type Check Check that names are used correctly and that expressions are well-typed Errors
  24. 24. 19 Source Code Editor Abstract Syntax Tree ErrorsCollect Constraints Solve Type checking proceeds in two steps Parse
  25. 25. 19 Source Code Editor Abstract Syntax Tree ErrorsCollect Constraints Solve Type checking proceeds in two steps language specific Parse
  26. 26. 19 Source Code Editor Abstract Syntax Tree ErrorsCollect Constraints Solve Type checking proceeds in two steps language specific language independent Parse
  27. 27. What is NaBL2? - Domain-specific specification language… - … to write constraint generators - Comes with a generic solver What features does it support? - Rich binding structures using scope graphs - Type equality and nominal sub-typing - Type-dependent name resolution Limitations - Restricted to the domain-specific (= restricted) model ‣ Not all name binding patterns in the wild can be expressed - Hypothesis is that all sensible patterns are expressible NaBL2 20
  28. 28. [[ Let(x, e, e') ^ (s) : t' ]] := new s', s' -P-> s, Var{x} <- s', Var{x} : v, [[ e ^ (s') : t ]], v == t, [[ e' ^ (s') : t' ]]. Constraint Rules 21 match pattern scope parameters type (optional) subterm recursion constraints
  29. 29. Scope Graph Constraints 22 new s // create a new scope s1 -L-> s2 // edge labeled with L from scope s1 to scope s2 N{x} <- s // x is a declaration in scope s for namespace N N{x} -> s // x is a reference in scope s for namespace N N{x} =L=> s // declaration x is associated with scope s N{x} <=L= s // scope s imports via reference x N{x} |-> d // reference x resolves to declaration d [[ e ^ (s) ]] // subterm e is scoped by scoped s s s s N xis N xi s N xi s N xis N xi N xi
  30. 30. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end
  31. 31. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] )
  32. 32. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] )
  33. 33. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] :=
  34. 34. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_body Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope
  35. 35. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_body Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope P
  36. 36. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body P
  37. 37. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression P
  38. 38. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression P
  39. 39. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ Var(x) ^ (s') ]] := P
  40. 40. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' P
  41. 41. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' x P
  42. 42. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration x P
  43. 43. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration x ? P
  44. 44. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration x ? P
  45. 45. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ e_body ^ (s_body) ]]. // body expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration x ? P
  46. 46. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ e_body ^ (s_body) ]]. // body expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration s’ x ? P
  47. 47. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ e_body ^ (s_body) ]]. // body expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration s’ x ? P
  48. 48. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx x Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ e_body ^ (s_body) ]]. // body expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration s’ x ? P
  49. 49. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx x Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ e_body ^ (s_body) ]]. // body expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration s’ x ? P
  50. 50. Scope Graph Example 23 let var x : int := x + 1 in x + 1 end s s_bodyx x Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body [[ e ^ (s) ]], // init expression [[ e_body ^ (s_body) ]]. // body expression [[ Var(x) ^ (s') ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration s’ x ? P
  51. 51. Name Set Constraints & Expressions 24 distinct S distinct/name S // elements/names in S are distinct S1 subseteq S2 S1 subseteq/name S2 // elements/names in S1 are a subset of S2 S1 seteq S2 S1 seteq/name S2 // elements/names in S1 are equal to S2 0 // empty set D(s) D(s)/N // all/namespace N declarations in s R(s) R(s)/N // all/namespace N references in s V(s) V(s)/N // visible declarations in s (w/ shadowing) W(s) W(s)/N // reachable declarations in s (no shadowing) (S1 union S2) // union of S1 and S2 (S1 isect S2) (S1 isect/name S2) // intersection of elements/names S1 and S2 (S1 lsect S2) (S1 lsect/name S2) // elements/names in S1 that are in S2 (S1 minus S2) (S1 minus/name S2) // elements/names in S1 that are not in S2
  52. 52. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4
  53. 53. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4 D(s0)
  54. 54. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4 D(s1)
  55. 55. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4 R(s2)
  56. 56. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4 V(s1)/Var
  57. 57. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4 W(s1)/Var
  58. 58. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4 (W(s1) minus D(s1)/Var)
  59. 59. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4 (R(s1) isect/name D(s1))
  60. 60. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4 (R(s1) lsect/name D(s1))
  61. 61. Name Set Examples 25 s0 s1 s2 Var x1 Var x2 Type y5 Type y3 Var x4
  62. 62. Type Constraints 26 ty1 == ty2 // types ty1 and ty2 are equal ty1 <R! ty2 // declare ty1 to be related to ty2 in R ty1 <R? ty2 // require ty1 to be related to ty2 in R .... // … extensions … d : ty // declaration d has type ty [[ e ^ (s) : ty ]] // subterm e has type ty N xi ty
  63. 63. Type Example 27 s s_bodyx xs’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] )
  64. 64. Type Example 27 s s_bodyx x [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) : ty' ]] := s’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] )
  65. 65. Type Example 27 s s_bodyx x [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) : ty' ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body s’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] )
  66. 66. Type Example 27 s s_bodyx x [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) : ty' ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body Var{x} : ty, // associate type s’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) INT
  67. 67. Type Example 27 s s_bodyx x [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) : ty' ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body Var{x} : ty, // associate type [[ t ^ (s) : ty ]], // type of type s’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) INT
  68. 68. Type Example 27 s s_bodyx x [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) : ty' ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body Var{x} : ty, // associate type [[ t ^ (s) : ty ]], // type of type [[ e ^ (s) : ty ]], // type of expression s’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) INT
  69. 69. Type Example 27 s s_bodyx x [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) : ty' ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body Var{x} : ty, // associate type [[ t ^ (s) : ty ]], // type of type [[ e ^ (s) : ty ]], // type of expression [[ e_body ^ (s_body) : ty' ]]. // constraints for body s’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) INT
  70. 70. Type Example 27 s s_bodyx x [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) : ty' ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body Var{x} : ty, // associate type [[ t ^ (s) : ty ]], // type of type [[ e ^ (s) : ty ]], // type of expression [[ e_body ^ (s_body) : ty' ]]. // constraints for body [[ Var(x) ^ (s') : ty ]] := s’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) INT
  71. 71. Type Example 27 s s_bodyx x [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) : ty' ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body Var{x} : ty, // associate type [[ t ^ (s) : ty ]], // type of type [[ e ^ (s) : ty ]], // type of expression [[ e_body ^ (s_body) : ty' ]]. // constraints for body [[ Var(x) ^ (s') : ty ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration s’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) INT
  72. 72. Type Example 27 s s_bodyx x [[ Let([VarDec(x, t, e)], [e_body]) ^ (s) : ty' ]] := new s_body, // new scope s_body -P-> s, // parent edge to enclosing scope Var{x} <- s_body, // x is a declaration in s_body Var{x} : ty, // associate type [[ t ^ (s) : ty ]], // type of type [[ e ^ (s) : ty ]], // type of expression [[ e_body ^ (s_body) : ty' ]]. // constraints for body [[ Var(x) ^ (s') : ty ]] := Var{x} -> s', // x is a reference in s' Var{x} |-> d, // check that x resolves to a declaration d : ty. // type of declaration is type of reference s’ x let var x : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] ) INT
  73. 73. NaBL2 Configuration 28 signature namespaces Var name resolution labels P I order D < P, D < I, I < P well-formedness P* I* relations reflexive, transitive, anti-symmetric sub : Type * Type
  74. 74. Tiger in NaBL2 29
  75. 75. Variable Declarations and References 30 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  76. 76. Variable Declarations and References 30 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  77. 77. Variable Declarations and References 30 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  78. 78. Variable Declarations and References 30 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  79. 79. Variable Declarations and References 30 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  80. 80. Variable Declarations and References 30 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  81. 81. Variable Declarations and References 30 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  82. 82. Variable Declarations and References 30 x1s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  83. 83. Variable Declarations and References 30 x1s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  84. 84. Variable Declarations and References 30 x1s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  85. 85. Variable Declarations and References 30 x1s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  86. 86. Variable Declarations and References 30 x1s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  87. 87. Variable Declarations and References 30 x1x2 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  88. 88. Variable Declarations and References 30 x1x2 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  89. 89. Variable Declarations and References 30 x1x2 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  90. 90. Variable Declarations and References 30 x1x2 s1 Dec[[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. [[ Var(x) ^ (s) ]] := Var{x} -> s, Var{x} |-> d. s0 s1 s0 Let( [VarDec("x", INT(), Int("1"))] , [Plus(Var("x"), Int("1"))] ) let var x1 : int := 1 in x2 + 1 end
  91. 91. Scoping of Loop Variable 31 s1 x1 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  92. 92. Scoping of Loop Variable 31 s1 x1 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  93. 93. Scoping of Loop Variable 31 s1 x1 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  94. 94. Scoping of Loop Variable 31 s1 x1 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  95. 95. Scoping of Loop Variable 31 s1 x1 s2 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  96. 96. Scoping of Loop Variable 31 s1 x1 s2 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  97. 97. Scoping of Loop Variable 31 s1 x1 s2 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  98. 98. Scoping of Loop Variable 31 s1 x1 s2 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  99. 99. Scoping of Loop Variable 31 s1 x1 s2 i2 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  100. 100. Scoping of Loop Variable 31 s1 x1 s2 i2 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  101. 101. Scoping of Loop Variable 31 s1 x1 s2 i2 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  102. 102. Scoping of Loop Variable 31 s1 x1 s2 i2 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  103. 103. Scoping of Loop Variable 31 s1 x1 s2 i2x3 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  104. 104. Scoping of Loop Variable 31 s1 x1 s2 i2x3 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  105. 105. Scoping of Loop Variable 31 s1 x1 s2 i2x3 x4 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  106. 106. Scoping of Loop Variable 31 s1 x1 s2 i2x3 x4 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  107. 107. Scoping of Loop Variable 31 s1 x1 s2 i2x3 i5x4 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  108. 108. Scoping of Loop Variable 31 s1 x1 s2 i2x3 i5x4 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  109. 109. Scoping of Loop Variable 31 s1 x1 s2 i2x3 i5x4 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  110. 110. Scoping of Loop Variable 31 s1 x1 s2 i2x3 i5x4 x6 s1 [[ stm@For(Var(x), e1, e2, e3) ^ (s) ]] := new s_for, s_for -P-> s, Var{x} <- s_for, Loop{Break()@stm} <- s_for, [[ e1 ^ (s) ]], [[ e2 ^ (s) ]], [[ e3 ^ (s_for) ]]. s0 s0 s2 let var x1 : int := 0 in for i2 := 1 to 4 do x3 := x4 + i5; x6 * 7 end
  111. 111. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  112. 112. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  113. 113. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  114. 114. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  115. 115. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  116. 116. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  117. 117. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  118. 118. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 pow1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  119. 119. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 pow1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  120. 120. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  121. 121. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  122. 122. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  123. 123. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  124. 124. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  125. 125. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  126. 126. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 n3 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  127. 127. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 n3 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  128. 128. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 n3 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  129. 129. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 n3 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  130. 130. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 n3 n4 b5 n8 b7 pow6 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  131. 131. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 n3 n4 b5 n8 b7 pow6 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  132. 132. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 n3 n4 b5 n8 b7 pow6 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  133. 133. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 n3 n4 b5 n8 b7 pow6 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  134. 134. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1 b2 n3 n4 b5 n8 b7 pow6 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  135. 135. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1pow9 b2 n3 n4 b5 n8 b7 pow6 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  136. 136. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1pow9 b2 n3 n4 b5 n8 b7 pow6 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  137. 137. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1pow9 b2 n3 n4 b5 n8 b7 pow6 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  138. 138. Function Declarations and References 32 [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := Var{f} <- s, new s_fun, s_fun -P-> s, Map2[[ args ^ (s_fun, s_outer) ]], distinct/name D(s_fun), [[ e ^ (s_fun) ]]. [[ FArg(x, t) ^ (s_fun, s_outer) ]] := Var{x} <- s_fun, [[ t ^ (s_outer) ]]. [[ Call(f, exps) ^ (s) ]] := Var{f} -> s, Var{f} |-> d, Map1[[ exps ^ (s) ]]. s0 s1 s2 s0 s1 s2 pow1pow9 b2 n3 n4 b5 n8 b7 pow6 let function pow1(b2 : int, n3 : int) : int = if n4 < 1 then 1 else (b5 * pow6(b7, n8 - 1)) in pow9(2, 7) end
  139. 139. Sequential Let 33 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  140. 140. Sequential Let 33 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  141. 141. Sequential Let 33 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  142. 142. Sequential Let 33 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  143. 143. Sequential Let 33 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  144. 144. Sequential Let 33 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  145. 145. Sequential Let 33 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  146. 146. Sequential Let 33 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  147. 147. Sequential Let 33 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  148. 148. Sequential Let 33 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  149. 149. Sequential Let 33 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  150. 150. Sequential Let 33 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  151. 151. Sequential Let 33 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  152. 152. Sequential Let 33 s2 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  153. 153. Sequential Let 33 s2 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  154. 154. Sequential Let 33 s2 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  155. 155. Sequential Let 33 s2 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  156. 156. Sequential Let 33 s2 x1 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  157. 157. Sequential Let 33 s2 x1 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  158. 158. Sequential Let 33 s2 x1 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  159. 159. Sequential Let 33 s2 x1 s3 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  160. 160. Sequential Let 33 s2 x1 s3 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  161. 161. Sequential Let 33 s2 x1 s3 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  162. 162. Sequential Let 33 s2 x1 s3 s1 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  163. 163. Sequential Let 33 s2 x1 s3 y2 s1 z3 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  164. 164. Sequential Let 33 s2 x1 s3 y2 s1 z3 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  165. 165. Sequential Let 33 s2 x1 s3 y2 s1 z3 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  166. 166. Sequential Let 33 s2 x1 s3 y2 s1 z3 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  167. 167. Sequential Let 33 s2 x1 s3 y2 s1 z3 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  168. 168. Sequential Let 33 s2 x1 s3 y2 s1 z4x5 y6 z3 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  169. 169. Sequential Let 33 s2 x1 s3 y2 s1 z4x5 y6 z3 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  170. 170. Sequential Let 33 s2 x1 s3 y2 s1 z4x5 z7 y6 z3 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  171. 171. Sequential Let 33 s2 x1 s3 y2 s1 z4x5 z7 y6 z3 [[ Let(blocks, exps) ^ (s) ]] := new s_body, Decs[[ blocks ^ (s, s_body) ]], Seq[[ exps ^ (s_body) ]], distinct D(s_body). Decs[[ [] ^ (s_outer, s_body) ]] := s_body -P-> s_outer. Decs[[ [block] ^ (s_outer, s_body) ]] := s_body -P-> s_outer, Dec[[ block ^ (s_body, s_outer) ]]. Decs[[ [block | blocks@[_|_]] ^ (s_outer, s_body) ]] := new s_dec, s_dec -P-> s_outer, Dec[[ block ^ (s_dec, s_outer) ]], Decs[[ blocks ^ (s_dec, s_body) ]], distinct/name D(s_dec). s0 s0 s2 s3 s1 let var x1 := 2 var y2 := z3 + 11 var z4 := x5 * y6 in z7 end
  172. 172. Mutually Recursive Functions 34 s1 odd1 even6 s2 s3 even11 x2 x7odd9 even4 x3 x8 Dec[[ FunDecs(fdecs) ^ (s, s_outer) ]] := Map2[[ fdecs ^ (s, s_outer) ]]. [[ FunDec(f, args, t, e) ^ (s, s_outer) ]] := new s_fun, s_fun -P-> s, distinct/name D(s_fun), MapTs2[[ args ^ (s_fun, s_outer) ]], s0 s0 s1 s2 s3 x5 x10 let function odd1(x2 : int) : int = if x3 > 0 then even4(x5-1) else 0 function even6(x7 : int) : int = if x8 > 0 then odd9(x10-1) else 1 in even11(34) end
  173. 173. Namespaces 35 s1 s2 Type foo1 Var foo2 Type foo4 Var foo5 s3 Var x3 Var x6 [[ TypeDec(x, t) ^ (s) ]] := [[ t ^ (s) ]], Type{x} <- s. [[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) ]], [[ e ^ (s_outer) ]], Var{x} <- s. s0 s0 s1 s2 s3 let type foo1 = int var foo2 : int := 24 var x3 : foo4 := foo5 in x6 end
  174. 174. Explicit versus Inferred Variable Type 36 let var x : int := 20 + 1 var y := 21 in x + y end [[ VarDec(x, t, e) ^ (s, s_outer) ]] := [[ t ^ (s_outer) : ty1 ]], [[ e ^ (s_outer) : ty2 ]], ty2 <? ty1, Var{x} <- s, Var{x} : ty1 !. [[ VarDecNoType(x, e) ^ (s, s_outer) ]] := [[ e ^ (s_outer) : ty ]], ty != NIL(), Var{x} <- s, Var{x} : ty !.
  175. 175. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s1 s3 s0 s1 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  176. 176. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s1 s3 s0 s1 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  177. 177. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s1 s3 s0 Type point1 s1 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  178. 178. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s1 s3 s0 Type point1 s1 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  179. 179. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s1 s3 s0 Type point1 s1 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  180. 180. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  181. 181. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  182. 182. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  183. 183. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  184. 184. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  185. 185. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  186. 186. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  187. 187. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  188. 188. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 s3 INT let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  189. 189. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 s3 INT let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  190. 190. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  191. 191. Record Definitions 37 [[ RecordTy(fields) ^ (s) : ty ]] := new s_rec, ty == RECORD(s_rec), NIL() <! ty, distinct/name D(s_rec)/Field, Map2[[ fields ^ (s_rec, s) ]]. [[ Field(x, t) ^ (s_rec, s_outer) ]] := Field{x} <- s_rec, Field{x} : ty !, [[ t ^ (s_outer) : ty ]]. s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  192. 192. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s1 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  193. 193. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s1 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  194. 194. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s1 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  195. 195. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s1 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  196. 196. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s1 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  197. 197. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. Type point5 s_rec s1 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  198. 198. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. Type point5 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  199. 199. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. Type point5 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  200. 200. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  201. 201. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  202. 202. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  203. 203. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  204. 204. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  205. 205. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  206. 206. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  207. 207. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 Field x6 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  208. 208. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 Field x6 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  209. 209. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 Field x6 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  210. 210. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 Field x6 Field y7 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  211. 211. Record Creation 38 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 Var p4 INT INT s0 s2 s3 [[ r@Record(t, inits) ^ (s) : ty ]] := [[ t ^ (s) : ty ]], ty == RECORD(s_rec), new s_use, s_use -I-> s_rec, D(s_rec)/Field subseteq/name R(s_use)/Field, distinct/name R(s_use)/Field, Map2[[ inits ^ (s_use, s) ]]. [[ InitField(x, e) ^ (s_use, s) ]] := Field{x} -> s_use, Field{x} |-> d, d : ty1, [[ e ^ (s) : ty2 ]], ty2 <? ty1. s4 Type point5 s4 Field x6 Field y7 s_rec s1 RECORD(s_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  212. 212. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. RECORD(s2) Var p4 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  213. 213. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. RECORD(s2) Var p4 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  214. 214. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. RECORD(s2) Var p4 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  215. 215. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. RECORD(s2) Var p4 Var p8 s_rec let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  216. 216. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. RECORD(s2) Var p4 Var p8 s_rec let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  217. 217. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. s5 RECORD(s2) Var p4 Var p8 s5 s_rec let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  218. 218. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. s5 RECORD(s2) Var p4 Var p8 s5 s_rec let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  219. 219. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. s5 RECORD(s2) Var p4 Var p8 s5 s_rec let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  220. 220. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. s5 RECORD(s2) Var p4 Var p8 s5 s_rec let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  221. 221. Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1 s2 RECORD(s2) Field x2 Field y3 s3 INT INT [[ FieldVar(e, f) ^ (s) : ty ]] := [[ e ^ (s) : ty_e ]], ty_e == RECORD(s_rec), new s_use, s_use -I-> s_rec, Field{f} -> s_use, Field{f} |-> d, d : ty. s5 RECORD(s2) Var p4 Var p8 s5 Field x9 s_rec let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end

×