Spring 2014
Program Analysis and Verification
Lecture 7: Static Analysis I
Roman Manevich
Ben-Gurion University
Syllabus
Semantics
Static
Analysis
Abstract
Interpretation
fundamentals
Analysis
Techniques
Crafting your
own
Natural
Semantics
Automating
Hoare Logic
Lattices
Numerical
Domains
Soot
Structural
semantics
Control Flow
Graphs
Galois
Connections
CEGAR
From proofs to
abstractions
Axiomatic
Verification
Equation
Systems
Fixed-Points
Alias analysis
Systematically
developing
transformers
Collecting
Semantics
Widening/
Narrowing
Shape
Analysis
Domain
constructors
Interprocedural
Analysis
2
Previously
•
•
•
•
Axiomatic verification
Weakest precondition calculus
Strongest postcondition calculus
Total correctness
3
Axiomatic semantics for While
[assp] { P[a/x] } x := a { P }
[skipp] { P } skip { P }
{ P } S1 { Q }, { Q } S2 { R }
[compp]
{ P } S1; S2 { R }
{b
P } S1 { Q }, { b P } S2 { Q
}
[ifp]
{ P } if b then S1 else S2 { Q }
[whilep]
[consp]
{b P}S{P}
{ P } while b do S { b
{ P’ } S { Q’ }
{P}S{Q}
P}
if P P’ and Q’ Q
4
Strongest postcondition
• A forward-going predicate transformer
• The strongest postcondition for P is
’ sp(P, C)
if and only if there exists such that
P and C, ’
Propositions:
1. p { P } C { sp(P, C) }
2. If p { P } C { Q } then sp(P, C)
Q
5
Calculating sp
1.
2.
3.
4.
sp(skip, P) = P
sp(x := a, P) = v. x=a[v/x] P[v/x]
sp(S1; S2, P) = sp(S2, sp(S1, P))
sp(if b then S1 else S2, P) =
sp(S1, b P) sp(S2, b P)
5. sp(while b do { } S, P) =
b
where {b
}S{ }
and P b
6
Today
• Static analysis for compiler optimization
– Common Subexpression Elimination
– Available Expression domain
• Develop a static analysis for Simple Available
Expressions
7
Array-max example: Post3
nums : array
{ N 0
0 m<N } // N stands for num’s length
x := 0
{ x=0 }
res := nums[0]
{ x=0
res=nums(0) }
Inv = { 0 m<x nums(m) res }
while x < N
{ x=k
res=oRes
0 m<k nums(m) oRes }
if nums[x] > res then
{ nums(x)>oRes
res=oRes
x=k
0 m<k nums(m) oRes }
res := nums[x]
{ res=nums(x)
nums(x)>oRes
x=k
0 m<k nums(m) oRes }
{ x=k
0 m k nums(m) res }
{ (x=k
0 m k nums(m) res)
(ores nums(x)
res=oRes
x=k
res=oRes
0 m<k
nums(m) oRes)}
{ x=k
0 m k nums(m) res }
x := x + 1
{ x=k+1
0 m k nums(m) res }
{ 0 m<x nums(m) res }
{ x=N
0 m<x nums(m) res}
[univp]{ m. 0 m<N nums(m) res }
8
Can we find this proof automatically?
nums : array
N : int
{ N 0 }
x := 0
{ N 0
x=0 }
res := nums[0]
{ x=0 }
Inv = { x N }
while x < N
{ x=k
k<N }
if nums[x] > res then
{ x=k
k<N }
res := nums[x]
{ x=k
k<N }
{ x=k
k<N }
x := x + 1
{ x=k+1
k<N }
{ x N
x N }
{ x=N }
Observation: predicates in proof have
the general form
constraint
where constraint has the form
X-Y c
or
X c
9
Look
under the
street
lamp
…We may
move lamp
a bit
By Infopablo00 (Own work) [CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons
10
Zone Abstract Domain
• Developed by Antoine Mine
in his Ph.D. thesis
• Uses constraints of the form
X - Y c and X c
11
Analysis with Zone abstract domain
Static Analysis with Zone Abstraction
nums : array
N : int
{ N 0 }
x := 0
{ N 0
x=0 }
res := nums[0]
{ N 0
x=0 }
Inv = { N 0
0 x N }
while x < N
{ N 0
0 x<N }
if nums[x] > res then
{ N 0
0 x<N }
res := nums[x]
{ N 0
0 x<N }
{ N 0
0 x<N }
x := x + 1
{ N 0
0<x<N }
{N 0
0 x
x=N }
Manual Proof
nums : array
N : int
{ N 0 }
x := 0
{ N 0
x=0 }
res := nums[0]
{ x=0 }
Inv = { x N }
while x < N
{ x=k
k N }
if nums[x] > res then
{ x=k
k<N }
res := nums[x]
{ x=k
k<N }
{ x=k
k<N }
x := x + 1
{ x=k+1
k<N }
{ x N
x N }
{ x=N }
12
Static analysis
for compiler optimizations
13
Motivating problem: optimization
• A compiler optimization is defined by a
program transformation:
T : Stmt Stmt
• The transformation is semantics-preserving:
s . Ssos C s = Ssos T(C) s
• The transformation is applied to the program
only if an enabling condition is met
• We use static analysis for inferring enabling
conditions
14
Common Subexpression Elimination
• If we have two variable assignments
x := a op b
…
op {+, -, *, ==, <=}
y := a op b
and the values of x, a, and b have not changed
between the assignments, rewrite the code as
x = a op b
…
y := x
• Eliminates useless recalculation
• Paves the way for more optimizations
(e.g., dead code elimination)
15
What do we need to prove?
{ true }
C1
x := a op b
C2
{ x = a op b }
y := a op b
C3
CSE
Assertion
localizes
decision
{ true }
C1
x := a op b
C2
{ x = a op b }
y := x
C3
16
A simplified problem
{ true }
C1
x := a + b
C2
{ x = a + b }
y := a + b
C3
CSE
{ true }
C1
x := a + b
C2
{ x = a + b }
y := x
C3
17
Available Expressions analysis
• A static analysis that infers for every program
point a set of facts of the form
AV = { x = y | x, y Var }
{ x = op y | x, y Var, op {-, !} }
{ x = y op z | y, z Var, op {+, -, *, <=} }
• For every program with n=|Var| variables
number of possible facts is finite: |AV|=O(n3)
• Yields a trivial algorithm …
– Is it efficient?
18
Simple Available Expressions
• Define atomic facts (for SAV) as
= { x = y | x, y Var }
{ x = y + z | x, y, z Var }
– For n=|Var| number of atomic facts is O(n3)
• Define sav-predicates as = 2
19
Notation for conjunctive sets of facts
• For a set of atomic facts D
Conj(D) = D
, we define
– E.g., if D={a=b, c=b+d, b=c} then
Conj(D) = (a=b) (c=b+d) (b=c)
• Notice that for two sets of facts D1 and D2
Conj(D1 D2) = Conj(D1) Conj(D1)
• What does Conj({}) stand for…?
20
Towards an automatic proof
• Goal: automatically compute an annotated
program proving as many facts as possible of the
form x = y and x = y + z
• Decision 1: develop a forward-going proof
• Decision 2: draw predicates from a finite set D
– “looking under the light of the lamp”
– A compromise that simplifies problem by focusing
attention – possibly miss some facts that hold
• Challenge 1: handle straight-line code
• Challenge 2: handle conditions
• Challenge 3: handle loops
21
Challenge 1: handling straight-line code
By Zachary Dylan Tax (Zachary Dylan Tax) [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC-BY-3.0 (http://creativecommons.org/licenses/by/3.0)], via Wikimedia Commons
22
Straight line code example
{
x
{
z
{
b
{
}
:= a +
x=a+b
:= a +
x=a+b,
:= a *
z=a+c
b
}
c
z=a+c }
c
}
• Find a proof that satisfies both conditions
23
Straight line code example
sp
cons
{
x
{
z
{
b
{
}
:= a +
x=a+b
:= a +
x=a+b,
:= a *
z=a+c
b
}
c
z=a+c }
c
}
Frame
• Can we make this into an algorithm?
• What do we need to ensure for each triple?
24
Goal
• Given a program of the form
x1 := a1; … xn := an
• Find predicates P0, …, Pn such that
1. {P0} x1 := a1 {P1} … {Pn-1} xn := an {Pn} is a proof
That is: sp(xi := ai, Pi-1) Pi
2. Each Pi has the form Conj(Di) where Di is a set of
atomic
25
Algorithm for straight-line code
• Goal: find predicates P0, …, Pn such that
1. {P0} x1 := a1 {P1} … {Pn-1} xn := an {Pn} is a proof
That is: sp(xi := ai, Pi-1) Pi
2. Each Pi has the form Conj(Di) where Di is a set of
atomic facts
• Idea: define a function FSAV[x:=a] : s.t.
if
FSAV[x:=a](D) = D’
then sp(x := a, Conj(D)) Conj(D’)
–
We call F the abstract transformer of x:=a
• Unless D0 is given, initialize D0={}
• For each i: compute Di+1 = Conj(FSAV[xi := ai] Di)
• Finally Pi = Conj(Di)
26
Defining an SAV abstract transformer
• Goal: define a function FSAV[x:=a] : s.t.
if
FSAV[x:=a](D) = D’
then sp(x := a, Conj(D)) Conj(D’)
• Idea: define rules for individual facts
and generalize to sets of facts by the
conjunction rule
27
Defining an SAV abstract transformer
• Goal: define a function FSAV[x:=a] : s.t.
if
FSAV[x:=a](D) = D’
then sp(x := a, Conj(D)) Conj(D’)
• Idea: define rules for individual facts
and generalize to sets of facts by the
conjunction rule
28
Defining an SAV abstract transformer
• Goal: define a function FSAV[x:=a] : s.t.
if
FSAV[x:=a](D) = D’
then sp(x := a, Conj(D)) Conj(D’)
• Idea: define rules for individual facts
and generalize to sets of facts by the
conjunction rule
[kill-lhs]
{ x= } x:=a { }
Is either a variable v or
an addition expression v+w
[kill-rhs-1] { y=x+w } x:=a { }
[kill-rhs-2] { y=w+x } x:=a { }
[gen]
{ } x:=
{ x= }
[preserve] { y=z+w } x:=a { y=z+w }
29
SAV abstract transformer example
{
x
{
z
{
b
{
}
:= a +
x=a+b
:= a +
x=a+b,
:= a *
z=a+c
b
}
c
z=a+c }
c
}
Is either a variable v or an addition expression v+w
[kill-lhs]
{ x= } x:= aexpr { }
[kill-rhs-1] { y=x+w } x:= aexpr { }
[kill-rhs-2] { y=w+x } x:= aexpr { }
[gen]
{ } x:=
{ x= }
[preserve] { y=z+w } x:= aexpr { y=z+w }
30
Problem 1: large expressions
{
}
x := a + b + c
{
}
y := a + b + c
{
}
Missed CSE
opportunity
• Large expressions on the right hand sides of
assignments are problematic
– Can miss optimization opportunities
– Require complex transformers
• Solution: transform code to normal form
where right-hand sides have bounded size
31
Three-address code
{
}
x := a + b + c
{
}
y := a + b + c
{
}
{
i1 := a +
{ i1=a+b
x := i1 +
{ i1=a+b,
i2 := a +
{ i1=a+b,
y := i2 +
{ i1=a+b,
}
b
}
c
x=i1+c }
b
x=i1+c, i2=a+b }
c
x=i1+c, i2=a+b, y=i2+c }
• Main idea: simplify expressions by storing
intermediate results in new temporary variables
• Number of variables in simplified statements 3
32
Three-address code
{
}
x := a + b + c
{
}
y := a + b + c
{
}
Need to infer
i1=i2
{
i1 := a +
{ i1=a+b
x := i1 +
{ i1=a+b,
i2 := a +
{ i1=a+b,
y := i2 +
{ i1=a+b,
}
b
}
c
x=i1+c }
b
x=i1+c, i2=a+b }
c
x=i1+c, i2=a+b, y=i2+c }
• Main idea: simplify expressions by storing
intermediate results in new temporary variables
• Number of variables in simplified statements 3
33
Problem 2: transformer precision
Need to infer
i1=i2
{
i1 := a +
{ i1=a+b
x := i1 +
{ i1=a+b,
i2 := a +
{ i1=a+b,
y := i2 +
{ i1=a+b,
}
b
}
c
x=i1+c }
b
x=i1+c, i2=a+b }
c
x=i1+c, i2=a+b, y=i2+c }
• Our transformer only infers syntactically available
expressions – ones that appear in the code explicitly
• We want a transformer that looks deeper into the
semantics of the predicates
– Takes equalities into account
34
Defining a semantic reduction
• Idea: make as many implicit facts explicit by
– Using symmetry and transitivity of equality
– Commutativity of addition
– Meaning of equality – can substitute equal variables
• For an SAV-predicate P=Conj(D) define
Explicate(D) = minimal set D* such that:
1.
2.
3.
4.
5.
6.
7.
D D*
x=y D* implies y=x D*
x=y D* y=z D* implies x=z D*
x=y+z D* implies x=z+y D*
x=y D* and x=z+w D* implies y=z+w
x=y D* and z=x+w D* implies z=y+w
x=z+w D* and y=z+w D* implies x=y
D*
D*
D*
• Notice that Explicate(D) D
• Explicate is a special case of a semantic reduction
35
Sharpening the transformer
• Define: F*[x:=aexpr] = Explicate FSAV[x:= aexpr]
{
i1 := a +
{ i1=a+b,
x := i1 +
{ i1=a+b,
i2 := a +
{ i1=a+b,
i2=b+a,
y := i2 +
{ ... }
}
b
i1=b+a
}
c
i1=b+a, x=i1+c, x=c+i1 }
b
i1=b+a, x=i1+c, x=c+i1, i2=a+b,
i1=i2, i2=i1, x=i2+c, x=c+i2, }
c
Since sets of facts and their conjunction are
isomorphic we will use them interchangeably
36
An algorithm for annotating SLP
• Annotate(P, x:=aexpr) =
{P} x:=aexpr F*[x:= aexpr](P)
Annotate(P, S1; S2) =
let Annotate(P, S1) be {P} A1 {Q1}
let Annotate(Q1, S2) be {Q1} A2 {Q2}
return {P} A1; {Q1} A2 {Q2}
37
Challenge 2: handling conditions
38
Goal
{bexpr P } S1 { Q }, { bexpr P } S2 { Q }
[ifp] { P } if bexpr then S else S { Q }
1
2
• Annotate a program
if bexpr then S1 else S2
with predicates from
• Assumption 1: P is given
(otherwise use true)
• Assumption 2: bexpr is a
simple binary expression
e.g., x=y, xy, x<y (why?)
{P}
if bexpr then
{ bexpr P }
S1
{ Q1 }
else
{ bexpr P }
S2
{ Q2 }
{Q}
39
Joining predicates
{bexpr P } S1 { Q }, { bexpr P } S2 { Q }
[ifp] { P } if bexpr then S else S { Q }
1
2
Possibly an SAV-fact
1. Start with P or {bexpr P} and
annotate S1 (yielding Q1)
2. Start with P or { bexpr P}
and
annotate S2 (yielding Q2)
3. How do we infer a Q such that
Q1 Q and Q2 Q?
Possibly an SAV-fact
Q1=Conj(D1), Q2=Conj(D2)
Define: Q = Q1 Q2
= Conj(D1 D2)
{P}
if bexpr then
{ bexpr P }
S1
{ Q1 }
else
{ bexpr P }
S2
{ Q2 }
{Q}
40
Joining predicates
{bexpr P } S1 { Q }, { bexpr P } S2 { Q }
[ifp] { P } if bexpr then S else S { Q }
1
2
1. Start with P or {bexpr P} and
annotate S1 (yielding Q1)
2. Start with P or { bexpr P}
and
annotate S2 (yielding Q2)
3. How do we infer a Q such that
Q1 Q and Q2 Q?
Q1=Conj(D1), Q2=Conj(D2)
Define: Q = Q1 Q2
= Conj(D1 D2)
The join operator for SAV
{P}
if bexpr then
{ bexpr P }
S1
{ Q1 }
else
{ bexpr P }
S2
{ Q2 }
{Q}
41
Joining predicates
• Q1=Conj(D1), Q2=Conj(D2)
• We want to soundly approximate Q1
• Define: Q = Q1 Q2
= Conj(D1 D2)
• Notice that Q1 Q and Q2 Q
meaning Q1 Q2 Q
Q2 in
42
Simplifying conditions
• Extend While with
– Non-determinism (or) and
– An assume statement
sos s if B
assume b, s
b s = tt
• Now, the following two statements are
equivalent
– if b then S1 else S2
– (assume b; S1) or (assume b; S2)
43
Handling conditional expressions
• We want to soundly approximate D bexpr
and D
bexpr in
• Define (bexpr) = if bexpr is factoid
{bexpr} else {}
• Define F[assume bexpr](D) = D
(bexpr)
• Can sharpen
F*[assume bexpr] = Explicate FSAV[assume bexpr]
44
Handling conditional expressions
• Notice bexpr
• Examples
–
–
(bexpr)
(y=z) = {y=z}
(y<z) = {}
45
An algorithm for annotating conditions
let Pt = F*[assume bexpr] P
let Pf = F*[assume bexpr] P
let Annotate(Pt, S1) be {Pt} A1 {Q1}
let Annotate(Pf, S2) be {Pf} A2 {Q2}
return {P}
if bexpr then
{Pt} A1 {Q1}
else
{Pf} A2 {Q2}
{Q1 Q2}
46
Example
{
}
if (x = y)
{ x=y, y=x }
a := b + c
{ x=y, y=x, a=b+c, a=c+b }
d := b – c
{ x=y, y=x, a=b+c, a=c+b }
else
{
}
a := b + c
{ a=b+c, a=c+b }
d := b + c
{ a=b+c, a=c+b, d=b+c, d=c+b, a=d, d=a }
{ a=b+c, a=c+b }
47
Example
{
}
if (x = y)
{ x=y, y=x }
a := b + c
{ x=y, y=x, a=b+c, a=c+b }
d := b – c
{ x=y, y=x, a=b+c, a=c+b }
else
{
}
a := b + c
{ a=b+c, a=c+b }
d := b + c
{ a=b+c, a=c+b, d=b+c, d=c+b, a=d, d=a }
{ a=b+c, a=c+b }
48
Recap
• We now have an algorithm for soundly
annotating loop-free code
• Generates forward-going proofs
• Algorithm operates on abstract syntax tree of
code
– Handles straight-line code by applying F*
– Handles conditions by recursively annotating true
and false branches and then intersecting their
postconditions
49
Example
{
}
if (x = y)
{ x=y, y=x }
a := b + c
{ x=y, y=x, a=b+c, a=c+b }
d := b – c
{ x=y, y=x, a=b+c, a=c+b }
else
{
}
a := b + c
{ a=b+c, a=c+b }
d := b + c
{ a=b+c, a=c+b, d=b+c, d=c+b, a=d, d=a }
{ a=b+c, a=c+b }
50
Challenge 2: handling loops
By Stefan Scheer (Own work (Own Photo)) [GFDL (http://www.gnu.org/copyleft/fdl.html), CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0/) or CC-BY-SA-2.5-2.0-1.0
(http://creativecommons.org/licenses/by-sa/2.5-2.0-1.0)], via Wikimedia Commons
51
Goal
{bexpr P } S { P }
[whilep] { P } while b do S { bexpr P
}
• Annotate a program
{P}
while bexpr do S with
predicates from
Inv = { N }
– s.t. P N
while bexpr do
• Main challenge: find N
{
bexpr
N
}
• Assumption 1: P is given
S
(otherwise use true)
{Q}
• Assumption 2: bexpr is a
simple binary expression
{ bexpr N }
52
Example: annotate this program
{ y=x+a, y=a+x, w=d, d=w }
Inv = { y=x+a, y=a+x
}
while (x z) do
{ z=x+a, z=a+x, w=d, d=w
}
x := x + 1
{ w=d, d=w
}
y := x + a
{ y=x+a, y=a+x, w=d, d=w
}
d := x + a
{ y=x+a, y=a+x, d=x+a, d=a+x, y=d, d=y }
{ y=x+a, y=a+x, x=z, z=x
}
53
Example: annotate this program
{ y=x+a, y=a+x, w=d, d=w }
Inv = { y=x+a, y=a+x }
while (x z) do
{ y=x+a, y=a+x }
x := x + 1
{ }
y := x + a
{ y=x+a, y=a+x }
d := x + a
{ y=x+a, y=a+x, d=x+a, d=a+x, y=d, d=y }
{ y=x+a, y=a+x, x=z, z=x }
54
Goal
{bexpr P } S { P }
[whilep] { P } while b do S { bexpr P
}
• Idea: try to guess a loop
{P}
invariant from a small
number of loop unrollings Inv = { N }
– We know how to annotate S while bexpr do
(by induction)
{ bexpr N }
S
{Q}
{ bexpr N }
55
k-loop unrolling
{ P }
Inv =
while
x
y
d
{ N }
(x z) do
:= x + 1
:= x + a
:= x + a
{ y=x+a, y=a+x, w=d, d=w }
if (x z)
x := x + 1
y := x + a
d := x + a
Q1 = { y=x+a }
{ P }
if (x z)
x := x +
y := x +
d := x +
Q1 = { y=x+a
if (x z)
x := x +
y := x +
d := x +
Q2 = { y=x+a
1
a
a
}
1
a
a
}
…
56
k-loop unrolling
{ P }
Inv =
while
x
y
d
{ N }
(x z) do
:= x + 1
:= x + a
:= x + a
{ y=x+a, y=a+x, w=d, d=w }
if (x z)
x := x + 1
y := x + a
d := x + a
Q1 = { y=x+a, y=a+x }
{ P }
if (x z)
x := x + 1
y := x + a
d := x + a
Q1 = { y=x+a, y=a+x }
if (x z)
x := x + 1
y := x + a
d := x + a
Q2 = { y=x+a, y=a+x }
…
57
k-loop unrolling
{ P }
Inv =
while
x
y
d
{ N }
(x z) do
:= x + 1
:= x + a
:= x + a
The following must hold:
P N
Q1 N
Q2 N
…
Qk N
{ y=x+a, y=a+x, w=d, d=w }
if (x z)
x := x + 1
y := x + a
d := x + a
Q1 = { y=x+a, y=a+x }
{ P }
if (x z)
x := x + 1
y := x + a
d := x + a
Q1 = { y=x+a, y=a+x }
if (x z)
x := x + 1
y := x + a
d := x + a
Q2 = { y=x+a, y=a+x }
…
58
k-loop unrolling
{ P }
Inv =
while
x
y
d
{ N }
(x z) do
:= x + 1
:= x + a
:= x + a
The following must hold:
P N
Q1 N
Observation 1: No need to
Q2 N
explicitly unroll loop – we
…
can reuse postcondition
Qk N
from unrolling k-1 for k
…
We can compute the following sequence:
N0 = P
N1 = N1 Q 1
N2 = N1 Q 2
…
Nk = Nk-1 Qk
{ y=x+a, y=a+x, w=d, d=w }
if (x z)
x := x + 1
y := x + a
d := x + a
Q1 = { y=x+a, y=a+x }
{ P }
if (x z)
x := x + 1
y := x + a
d := x + a
Q1 = { y=x+a, y=a+x }
if (x z)
x := x + 1
y := x + a
d := x + a
Q2 = { y=x+a, y=a+x }
…
59
k-loop unrolling
{ P }
Inv =
while
x
y
d
{ N }
(x z) do
:= x + 1
:= x + a
:= x + a
The following must hold:
P N
Observation 2: Nk
Q1 N
monotonically decreases
Q2 N
set of facts.
…
Question: does it stabilizes
Qk N
for some k?
…
We can compute the following sequence:
N0 = P
N1 = N1 Q 1
N2 = N1 Q 2
…
Nk = Nk-1 Qk
{ y=x+a, y=a+x, w=d, d=w }
if (x z)
x := x + 1
y := x + a
d := x + a
Q1 = { y=x+a, y=a+x }
{ P }
if (x z)
x := x + 1
y := x + a
d := x + a
Q1 = { y=x+a, y=a+x }
if (x z)
x := x + 1
y := x + a
d := x + a
Q2 = { y=x+a, y=a+x }
…
60
Algorithm for annotating a loop
Annotate(P, while bexpr do S) =
Initialize N := Nc := P
repeat
let Annotate(P, if b then S else skip) be
{Nc} if bexpr then S else skip {N}
Nc := Nc N
until N = Nc
return {P}
INV= N
while bexpr do
F[assume bexpr](N)
Annotate(F[assume bexpr](N), S)
F[assume bexpr](N)
61
Putting it together
62
Algorithm for annotating a program
Annotate(P, S) =
case S is x:=aexpr
return {P} x:=aexpr {F*[x:=aexpr] P}
case S is S1; S2
let Annotate(P, S1) be {P} A1 {Q1}
let Annotate(Q1, S2) be {Q1} A2 {Q2}
return {P} A1; {Q1} A2 {Q2}
case S is if bexpr then S1 else S2
let Pt = F[assume bexpr] P
let Pf = F[assume bexpr] P
let Annotate(Pt, S1) be {Pt} A1 {Q1}
let Annotate(Pf, S2) be {Pf} A2 {Q2}
return {P} if bexpr then {Pt} A1 {Q1}
else {Pf} A2 {Q2}
{Q1 Q2}
case S is while bexpr do S
N := Nc := P // Initialize
repeat
let Pt = F[assume bexpr] Nc
let Annotate(Pt, S) be {Nc} Abody {N}
Nc := Nc N
until N= Nc
return {P} INV= {N} while bexpr do {Pt} Abody {F[assume bexpr](N)}
63
Exercise: apply algorithm
{
}
y := a+b
{
}
x := y
{
while (xz) do
{
w := a+b
{
x := a+b
{
a := z
{
}
}
}
}
}
64
Step 1/18
{}
y := a+b
{ y=a+b }*
x := y
while (xz) do
w := a+b
x := a+b
a := z
Not all factoids are
shown – apply Explicate
to get all factoids
65
Step 2/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
while (xz) do
w := a+b
x := a+b
a := z
66
Step 3/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’ = { y=a+b, x=y, x=a+b }*
while (xz) do
w := a+b
x := a+b
a := z
67
Step 4/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’ = { y=a+b, x=y, x=a+b }*
while (xz) do
{ y=a+b, x=y, x=a+b }*
w := a+b
x := a+b
a := z
68
Step 5/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’ = { y=a+b, x=y, x=a+b }*
while (xz) do
{ y=a+b, x=y, x=a+b }*
w := a+b
{ y=a+b, x=y, x=a+b, w=a+b, w=x, w=y }*
x := a+b
a := z
69
Step 6/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’ = { y=a+b, x=y, x=a+b }*
while (xz) do
{ y=a+b, x=y, x=a+b }*
w := a+b
{ y=a+b, x=y, x=a+b, w=a+b, w=x, w=y }*
x := a+b
{ y=a+b, w=a+b, w=y, x=a+b, w=x, x=y }*
a := z
70
Step 7/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’ = { y=a+b, x=y, x=a+b }*
while (xz) do
{ y=a+b, x=y, x=a+b }*
w := a+b
{ y=a+b, x=y, x=a+b, w=a+b, w=x, w=y }*
x := a+b
{ y=a+b, w=a+b, w=y, x=a+b, w=x, x=y }*
a := z
{ w=y, w=x, x=y, a=z }*
71
Step 8/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’ = { x=y }*
while (xz) do
{ y=a+b, x=y, x=a+b }*
w := a+b
{ y=a+b, x=y, x=a+b, w=a+b, w=x, w=y }*
x := a+b
{ y=a+b, w=a+b, w=y, x=a+b, w=x, x=y }*
a := z
{ w=y, w=x, x=y, a=z }*
72
Step 9/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’ = { x=y }*
while (xz) do
{ x=y }*
w := a+b
{ y=a+b, x=y, x=a+b, w=a+b, w=x, w=y }*
x := a+b
{ y=a+b, w=a+b, w=y, x=a+b, w=x, x=y }*
a := z
{ w=y, w=x, x=y, a=z }*
73
Step 10/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’ = { x=y }*
while (xz) do
{ x=y }*
w := a+b
{ x=y, w=a+b }*
x := a+b
{ y=a+b, w=a+b, w=y, x=a+b, w=x, x=y }*
a := z
{ w=y, w=x, x=y, a=z }*
74
Step 11/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’ = { x=y }*
while (xz) do
{ x=y }*
w := a+b
{ x=y, w=a+b }*
x := a+b
{ x=a+b, w=a+b, w=x }*
a := z
{ w=y, w=x, x=y, a=z }*
75
Step 12/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’ = { x=y }*
while (xz) do
{ x=y }*
w := a+b
{ x=y, w=a+b }*
x := a+b
{ x=a+b, w=a+b, w=x }*
a := z
{ w=x, a=z }*
76
Step 13/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’’ = { }
while (xz) do
{ x=y }*
w := a+b
{ x=y, w=a+b }*
x := a+b
{ x=a+b, w=a+b, w=x }*
a := z
{ w=x, a=z }*
77
Step 14/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’’ = { }
while (xz) do
{ }
w := a+b
{ x=y, w=a+b }*
x := a+b
{ x=a+b, w=a+b, w=x }*
a := z
{ w=x, a=z }*
78
Step 15/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’’ = { }
while (xz) do
{ }
w := a+b
{ w=a+b }*
x := a+b
{ x=a+b, w=a+b, w=x }*
a := z
{ w=x, a=z }*
79
Step 16/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’’ = { }
while (xz) do
{ }
w := a+b
{ w=a+b }*
x := a+b
{ x=a+b, w=a+b, w=x }*
a := z
{ w=x, a=z }*
80
Step 17/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv’’’ = { }
while (xz) do
{ }
w := a+b
{ w=a+b }*
x := a+b
{ x=a+b, w=a+b, w=x }*
a := z
{ w=x, a=z }*
81
Step 18/18
{}
y := a+b
{ y=a+b }*
x := y
{ y=a+b, x=y, x=a+b }*
Inv = { }
while (xz) do
{ }
w := a+b
{ w=a+b }*
x := a+b
{ x=a+b, w=a+b, w=x }*
a := z
{ w=x, a=z }*
{ x=z }
82
Next lecture:
abstract interpretation fundamentals
Canonical form for SAV
• For an available expressions element A define
Explicate(A) = minimal set B such that:
1.
2.
3.
4.
5.
6.
7.
A B
x=y B implies y=x B
x=y B and y=z B implies x=z B
x=y+z B implies x=z+y B
x=y B and x=z+w B implies y=z+w
x=y B and z=x+w B implies z=y+w
x=z+w B and y=z+w B implies x=y
B
B
B
• Makes all implicit facts explicit
• Define A* = Explicate(A)
• Define (for two subsets A1, A2 D)
A1 exp A2 if and only if A1* A2*
• Lemma: A1 exp A2 if and only A1 imp A2
84
© Copyright 2026 Paperzz