Hendrik van Antwerpen
IN4303 Compiler Construction
TU Delft
September 2017
Declare Your Language
Chapter 6: Name & Type Constraints
Reading Material
2
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
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
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
Documentation for NaBL2 at
the metaborg.org website.
http://www.metaborg.org/en/latest/source/langdev/meta/lang/nabl2/index.html
Types and Type Checking
7
8
Source
Code
Editor
Parse
Abstract
Syntax
Tree
Type Check
Check that names are used correctly and that expressions are well-typed
Errors
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
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
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
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
Type Checking
with Constraints
13
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
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())
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())
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())
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())
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())
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())
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())
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())
18
Source
Code
Editor
Parse
Abstract
Syntax
Tree
Type Check
Check that names are used correctly and that expressions are well-typed
Errors
19
Source
Code
Editor
Abstract
Syntax
Tree
ErrorsCollect Constraints Solve
Type checking proceeds in two steps
Parse
19
Source
Code
Editor
Abstract
Syntax
Tree
ErrorsCollect Constraints Solve
Type checking proceeds in two steps
language
specific
Parse
19
Source
Code
Editor
Abstract
Syntax
Tree
ErrorsCollect Constraints Solve
Type checking proceeds in two steps
language
specific
language
independent
Parse
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
[[ 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
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
Scope Graph Example
23
let
var x : int := x + 1
in
x + 1
end
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"))]
)
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"))]
)
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) ]] :=
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
D(s0)
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
D(s1)
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
R(s2)
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
V(s1)/Var
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
W(s1)/Var
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
(W(s1) minus D(s1)/Var)
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
(R(s1) isect/name D(s1))
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
(R(s1) lsect/name D(s1))
Name Set Examples
25
s0
s1
s2
Var
x1
Var
x2
Type
y5
Type
y3
Var
x4
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
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"))]
)
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"))]
)
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"))]
)
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
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
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
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
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
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
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
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
Tiger in NaBL2
29
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 !.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Alternative (Nominal) Record Encoding
40
s0
s1
s3
s0
s1
s3
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s1
s3
s0
s1
s3
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s0
Type
point1
s1 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
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s0
Type
point1
s1 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
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s5
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
Var
p8
s5
Field
x9
d_rec s_recRECORD(d_rec)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s5
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
Var
p8
s5
Field
x9
d_rec s_recRECORD(d_rec)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s5
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
Var
p8
s5
Field
x9
d_rec s_recRECORD(d_rec)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s5
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
Var
p8
s5
Field
x9
d_rec s_recRECORD(d_rec)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s5
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
Var
p8
s5
Field
x9
d_rec s_recRECORD(d_rec)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s5
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
Var
p8
s5
Field
x9
d_rec s_recRECORD(d_rec)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Alternative (Nominal) Record Encoding
40
s0
s2
s1
s3
s5
s4
s0
Type
point1
s1 s2
Field
x2
Field
y3
s3
INT
INT
Type
point5
s4
Field
x6
Field
y7
Var
p4
RECORD(point1)
Var
p8
s5
Field
x9
d_rec s_recRECORD(d_rec)
let
type point1 = { x2 : int, y3 : int }
var p4 := point5{ x6 = 4, y7 = 5 }
in
p8.x9
end
Full Tiger Specification Online
41
https://github.com/MetaBorgCube/metaborg-tiger
https://github.com/MetaBorgCube/metaborg-tiger/blob/master/org.metaborg.lang.tiger/trans/static-semantics/static-semantics.nabl2
Conclusion
42
Constraint-based type checking
- Language-specific specification
- Language-independent solver
- Support inference
NaBL2 specifications
- Meta-language for constraint generators
- Rich binding structure using scope graphs
- Many examples of constraint rules for Tiger language
Summary
43
Open research topics
- Extensions with new type system features
‣ Structural typing
‣ Type normalization
- Dealing with ambiguity
‣ Ambiguous references
‣ Overload resolution
- Parametric polymorphism
- Incremental analysis
Future Work
44
What are we discussing next week?
- How do we describe the meaning of constraints? (semantics)
- What are techniques to solve constraints?
‣ Unification
‣ Simplification and propagation
- Describe the relation between constraint semantics and solver
‣ Soundness
‣ Completeness
Next Week
45

Declare Your Language: Type Checking

  • 1.
    Hendrik van Antwerpen IN4303Compiler Construction TU Delft September 2017 Declare Your Language Chapter 6: Name & Type Constraints
  • 2.
  • 3.
    3 Type checkers arealgorithms 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 This paper introducesscope 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 Separating type checkinginto 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 Documentation for NaBL2at the metaborg.org website. http://www.metaborg.org/en/latest/source/langdev/meta/lang/nabl2/index.html
  • 7.
    Types and TypeChecking 7
  • 8.
    8 Source Code Editor Parse Abstract Syntax Tree Type Check Check thatnames are used correctly and that expressions are well-typed Errors
  • 9.
    Goal of typechecking - 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.
    Many different typesystem 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.
    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.
    What should atype 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.
  • 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.
    Computing Type ofExpression (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.
    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.
    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.
    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.
    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.
    Use Variables andConstraints 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.
    Use Variables andConstraints 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.
    Use Variables andConstraints 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.
    18 Source Code Editor Parse Abstract Syntax Tree Type Check Check thatnames are used correctly and that expressions are well-typed Errors
  • 24.
  • 25.
    19 Source Code Editor Abstract Syntax Tree ErrorsCollect Constraints Solve Typechecking proceeds in two steps language specific Parse
  • 26.
    19 Source Code Editor Abstract Syntax Tree ErrorsCollect Constraints Solve Typechecking proceeds in two steps language specific language independent Parse
  • 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.
    [[ 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.
    Scope Graph Constraints 22 news // 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.
    Scope Graph Example 23 let varx : int := x + 1 in x + 1 end
  • 31.
    Scope Graph Example 23 let varx : int := x + 1 in x + 1 end Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] )
  • 32.
    Scope Graph Example 23 let varx : int := x + 1 in x + 1 end s Let( [VarDec( "x" , Tid("int") , Plus(Var("x"), Int("1")) )] , [Plus(Var("x"), Int("1"))] )
  • 33.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    Scope Graph Example 23 let varx : 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.
    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.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    NaBL2 Configuration 28 signature namespaces Var name resolution labelsP I order D < P, D < I, I < P well-formedness P* I* relations reflexive, transitive, anti-symmetric sub : Type * Type
  • 74.
  • 75.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Variable Declarations andReferences 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Scoping of LoopVariable 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    Function Declarations andReferences 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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    Sequential Let 33 s2 x1 s3y2 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.
    Sequential Let 33 s2 x1 s3y2 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.
    Sequential Let 33 s2 x1 s3y2 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.
    Sequential Let 33 s2 x1 s3y2 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.
    Sequential Let 33 s2 x1 s3y2 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.
    Sequential Let 33 s2 x1 s3y2 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.
    Sequential Let 33 s2 x1 s3y2 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.
    Sequential Let 33 s2 x1 s3y2 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.
    Sequential Let 33 s2 x1 s3y2 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.
    Mutually Recursive Functions 34 s1odd1 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.
    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.
    Explicit versus InferredVariable 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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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
  • 222.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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
  • 223.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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
  • 224.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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
  • 225.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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
  • 226.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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
  • 227.
    Record Field Access 39 s0 s2 s1 s3 s0 Type point1 s1s2 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
  • 228.
    Alternative (Nominal) RecordEncoding 40 s0 s1 s3 s0 s1 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 229.
    Alternative (Nominal) RecordEncoding 40 s0 s1 s3 s0 s1 s3 let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 230.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s0 Type point1 s1 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
  • 231.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s0 Type point1 s1 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
  • 232.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 233.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 234.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 235.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 236.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 237.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 238.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s5 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) Var p8 s5 Field x9 d_rec s_recRECORD(d_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 239.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s5 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) Var p8 s5 Field x9 d_rec s_recRECORD(d_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 240.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s5 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) Var p8 s5 Field x9 d_rec s_recRECORD(d_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 241.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s5 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) Var p8 s5 Field x9 d_rec s_recRECORD(d_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 242.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s5 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) Var p8 s5 Field x9 d_rec s_recRECORD(d_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 243.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s5 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) Var p8 s5 Field x9 d_rec s_recRECORD(d_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 244.
    Alternative (Nominal) RecordEncoding 40 s0 s2 s1 s3 s5 s4 s0 Type point1 s1 s2 Field x2 Field y3 s3 INT INT Type point5 s4 Field x6 Field y7 Var p4 RECORD(point1) Var p8 s5 Field x9 d_rec s_recRECORD(d_rec) let type point1 = { x2 : int, y3 : int } var p4 := point5{ x6 = 4, y7 = 5 } in p8.x9 end
  • 245.
    Full Tiger SpecificationOnline 41 https://github.com/MetaBorgCube/metaborg-tiger https://github.com/MetaBorgCube/metaborg-tiger/blob/master/org.metaborg.lang.tiger/trans/static-semantics/static-semantics.nabl2
  • 246.
  • 247.
    Constraint-based type checking -Language-specific specification - Language-independent solver - Support inference NaBL2 specifications - Meta-language for constraint generators - Rich binding structure using scope graphs - Many examples of constraint rules for Tiger language Summary 43
  • 248.
    Open research topics -Extensions with new type system features ‣ Structural typing ‣ Type normalization - Dealing with ambiguity ‣ Ambiguous references ‣ Overload resolution - Parametric polymorphism - Incremental analysis Future Work 44
  • 249.
    What are wediscussing next week? - How do we describe the meaning of constraints? (semantics) - What are techniques to solve constraints? ‣ Unification ‣ Simplification and propagation - Describe the relation between constraint semantics and solver ‣ Soundness ‣ Completeness Next Week 45