Spring 2017
Program Analysis and Verification
Lecture 6: Axiomatic Semantics IV
Data Structures
Roman Manevich
Ben-Gurion University
Previously
• Hoare logic
– Inference system
– Annotated programs
– Soundness and completeness
• Weakest precondition calculus
• Strongest postcondition calculus
2
Useful rules
{P}C{Q}
{ P’ } C { Q’ }
[conjp]
{ P P’ } C {Q Q’ }
{P}C{Q}
{ P’ } C { Q’ }
[disjp]
{ P P’ } C {Q Q’ }
{P}C{Q}
[existp] { v. P } C { v. Q v FV(C
}
)
{P}C{Q}
v FV(C
[univp]
{ v. P } C { v. Q }
)
[Invp]{ F } C { F } Mod(C) FV(F)={}
• Mod(C) = set of variables assigned to in sub-statements of C
• FV(F) = free variables of F
3
wlp rules
1.
2.
3.
4.
wlp(skip, Q) = Q
wlp(x := a, Q) = Q[a/x]
wlp(S1; S2, Q) = wlp(S1, wlp(S2, Q))
wlp(if b then S1 else S2, Q) =
(b wlp(S1, Q))
( b wlp(S2, Q))
5. wlp(while b do { } S, Q) =
where {b
}S{ }
and b
Q
4
Strongest postcondition rules
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
5
Warm-up
6
Exponentiation prog. – specify
{
}
t := 0;
res := 1;
while (t < y) do
res := res * x;
t := t + 1;
{
}
7
Exponentiation prog. – loop invariant
{ y0 }
t := 0;
res := 1;
Inv = {
while (t < y) do
res := res * x;
t := t + 1;
{ res=xy }
}
8
Exponentiation prog. – prove
{ y0 }
t := 0;
res := 1;
Inv = { y0 ty res=xt }
while (t < y) do
res := res * x;
t := t + 1;
{ res=xy }
9
Exponentiation prog. – prove
{ y0 }
t := 0;
{ y0 t=0 }
res := 1;
{ y0 t=0 res=1 }
Inv = { y0 ty res=xt }
while (t < y) do
res := res * x;
t := t + 1;
{ res=xy }
Background axioms:
x0 = 1
10
Exponentiation prog. – prove
Background
{ y0 }
t := 0;
x0 = 1
{ y0 t=0 }
res := 1;
{ y0 t=0 res=1 }
Inv = { y0 ty res=xt }
while (t < y) do
{ y0 ty res=xt t<y }
{ y0 ot=t ores=res ores=xot ot<y }
res := res * x;
{ y0 ot=t ores*x=res ores=xot ot<y }
t := t + 1;
{ y0 ot+1=t ores*x=res ores=xot ot<y }
{ res=xy }
axioms:
11
Exponentiation prog. – prove
Background axioms:
{ y0 }
t := 0;
x0 = 1
{ y0 t=0 }
xt-1 * x = xt
res := 1;
{ y0 t=0 res=1 }
Inv = { y0 ty res=xt }
while (t < y) do
{ y0 ty res=xt t<y }
{ y0 ot=t ores=res ores=xot ot<y }
res := res * x;
{ y0 ot=t ores*x=res ores=xot ot<y }
t := t + 1;
{ y0 ot+1=t ores*x=res ores=xot ot<y }
{ y0 ot+1=t xt-1*x=res ores=xot t-1<y }
{ y0 xt*x=res t<y+1 }
{ y0 res=xt ty }
{ res=xy }
12
Exponentiation prog. – prove
Background axioms:
{ y0 }
t := 0;
x0 = 1
{ y0 t=0 }
xt-1 * x = xt
res := 1;
{ y0 t=0 res=1 }
Inv = { y0 ty res=xt }
while (t < y) do
{ y0 ty res=xt t<y }
{ y0 ot=t ores=res ores=xot ot<y }
res := res * x;
{ y0 ot=t ores*x=res ores=xot ot<y }
t := t + 1;
{ y0 ot+1=t ores*x=res ores=xot ot<y }
{ y0 ot+1=t xt-1*x=res ores=xot t-1<y }
{ y0 xt*x=res t<y+1 }
{ y0 res=xt ty }
{ y0 ty res=xt ty }
{ res=xy }
13
Tentative syllabus
Program
Verification
Program
Analysis Basics
Abstract
Interpretation
fundamentals
Analysis
Techniques
Operational
semantics
Control Flow
Graphs
Lattices
Numerical
Domains
Hoare Logic
Equation
Systems
Fixed-Points
Alias analysis
Predicate
Calculus
Collecting
Semantics
Chaotic
Iteration
Interprocedural
Analysis
Data Structures
Using Soot
Galois
Connections
Shape
Analysis
Domain
constructors
CEGAR
Termination
Widening/
Narrowing
14
Agenda
• Modeling and handling data structures
15
Handling data structures
16
Problems with Hoare logic and heaps
• { P[a/x] } x := a { P }
• Consider the annotated program
{ y=5 }
y := 5;
The rule works on a syntactic
level unaware of possible
{ y=5 }
aliasing between different
x := &y;
terms (y and *x in our case)
{ y=5 }
*x := 7;
{ y=5 }
• Is it correct?
17
Problems with Hoare logic and heaps
• { P[a/x] } x := a { P }
• {(x=&y
z=5)
(x&y
y=5)}
*x = z;
{ y=5 }
• What should the precondition be?
18
Problems with Hoare logic and heaps
• { P[a/x] } x := a { P }
• {(x=&y
z=5)
(x&y
y=5)}
*x = z;
{ y=5 }
• We split into cases depending on possible aliasing
19
Problems with Hoare logic and heaps
• { P[a/x] } x := a { P }
• {(x=&y
z=5)
(x&y
y=5)}
*x = z;
{ y=5 }
• What should the precondition be?
• Joseph M. Morris: A General Axiom of
Assignment
Employed by Dafny
• A different approach: heaps as arrays
• Really successful approach for heaps is based on
Separation Logic
20
Extending While with function variables
S ::= x := a | x := y[a] | y[x] := z
| skip | S1; S2
| if b then S1 else S2
| while b do S
• We added a new type of variables – array
variables
– Model array variable as a function y : Z Z
• Re-define program states
State =
21
Extending While with function variables
S ::= x := a | x := y[a] | y := y[xz]
| skip | S1; S2
| if b then S1 else S2
A very general approach – allows
handling many data types
| while b do S
• Define operational semantics
x := y[a],
y[x] := z,
• Treat an array assignment y[x] := z as an
update to the array function y
– y := y[xz] meaning y’= v. v=a ? z : y(v)
22
Array update rules (wlp)
[array-update] { P[y[x z]/y] } y[x] := z { P }
[array-load] { P[y(a)/x] } x := y[a] { P }
• We need the two following axioms:
{ y[x z](x) = z }
{ wx y[x z](w) = y(w) }
• Examples
{x=y[i 7](i)} y[i]:=7 {x=y(i)}
{x=7} y[i]:=7 {x=y(i)}
{y(a)=7} x:=y[a] {x=7}
23
Array update rules (sp)
{P}
[array-loadF] x := y[a]
{ v. x=y(a[v/x])
[array-updateF]
{ y=g P }
y[x] := z
{ y=g[x z]
P[v/x] }
P[g/y]}
24
Small array update rules (sp)
[array-loadF] { a=b } x := y[a] { x=y(b) }
In both rules
g and b are fresh
[array-updateF] { y=g } y[x] := z { y=g[x z] }
25
practice
26
Rewrite assignment as function update
b[i] := a[j]
27
Calculate the postcondition 1
{ ob=b a(j)=x
b := b[ia(j)]
{
}
}
28
Calculate the postcondition 1
{
b
{
{
ob=b a(j)=x
}
:= b[ia(j)]
a(j)=x b=ob[ia(j)]
b=ob[ix] }
}
29
Calculate the postcondition 2
{ ob=b a(j)=x
z.0z<i ob(z)=x }
b := b[ia(j)]
{
}
30
Simplify the postcondition 2
{ ob=b a(j)=x
z.0z<i ob(z)=x }
b := b[ia(j)]
{ ob=b a(j)=x b=ob[ix]
z.0z<i ob(z)=x
}
31
Simplify the postcondition 2
{ ob=b a(j)=x
z.0z<i ob(z)=x }
b := b[ia(j)]
{ a(j)=x z.0zi b(z)=x
}
32
More practice with arrays
Array max
33
Array-max program – specify
nums : array
N : int // N stands for num’s length
{ N 0
nums=orig_nums }
x := 0
res := nums[0]
while x < N
if nums[x] > res then
res := nums[x]
x := x + 1
1. { x=N }
2. { m. (m 0
m<N) nums(m) res }
3. { m. m 0
m<N
nums(m)=res }
4. { nums=orig_nums }
34
Array-max program
nums : array
N : int // N stands for num’s length
{ N 0
nums=orig_nums }
x := 0
res := nums[0]
while x < N
if nums[x] > res then
Dafny has modifies
res := nums[x]
clauses
x := x + 1
Post1: { x=N }
Post2: { nums=orig_nums }
Post3: { m. 0 m<N nums(m) res }
Post4: { m. 0 m<N
nums(m)=res }
35
Proof strategy
• Prove each goal 1, 2, 3, 4 separately and use
conjunction rule to prove them all
• After proving
– {N 0} C {x=N}
– {nums=orig_nums} C {nums=orig_nums}
• We have proved
– {N 0
{x=N
nums=orig_nums}
C
nums=orig_nums}
• We can refer to assertions from earlier proofs in
writing new proofs
36
Array-max example: Post1
nums : array
N : int // N stands for num’s length
{ N 0 }
x := 0
{ N 0
x=0 }
res := nums[0]
{ N 0
x=0 }
Inv = { x N }
Use frame rule
while x < N
(invariance rule)
{ x=k
k<N }
if nums[x] > res then
res := nums[x]
{ x=k
k<N }
x := x + 1
{ x=k+1
k<N }
{ x N
x N }
{ x=N }
37
Array-max example: Post2
nums : array
N : int // N stands for num’s length
{ nums=orig_nums }
x := 0
res := nums[0]
while x < N
if nums[x] > res then
res := nums[x]
{ nums=orig_nums }
Use frame rule
38
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)
(res≥nums(x)
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 x-1 nums(m) res }
{ 0 m<x nums(m) res }
{ x=N
0 m<x nums(m) res} // We add x=N from Post1
[univp]{ m. 0 m<N nums(m) res }
39
practice proving programs
with arrays
array reversal
40
Array reversal
• Write a While program with arrays that
accepts two arrays – a and b and an integer
N>0 and stores in b the contents of a[0..N] in
reverse order
41
Array reversal
i := 0;
while i < N
b[i] := a[N-i-1];
i := i + 1;
42
Array reversal – arrays as functions
i := 0;
while i < N
b := b[ia(N-i-1)];
i := i + 1;
43
Array reversal
{N0}
i := 0;
{N0
i=0}
Inv = { 0 i N
z.0 z<i b(z)=a(N-z-1)}
while i < N
{ lb=b
0 i<N
z.0 z<i lb(z)=a(N-z-1)}
b := b[ia(N-i-1)];
{ b=lb[ia(N-i-1)]
0 i<N
z.0 z<i lb(z)=a(N-z-1)}
// Extend quantified formula up to i
{ 0 i<N
z.0 z i lb(z)=a(N-z-1)}
i := i + 1;
{ 0 i-1<N
z.0 z i-1 lb(z)=a(N-z-1)}
// Simplify for i
{ 0 i N
z.0 z<i lb(z)=a(N-z-1)}
44
see you next time
45
© Copyright 2026 Paperzz