PPTX

Spring 2017
Program Analysis and Verification
Lecture 3: Axiomatic Semantics I
Roman Manevich
Ben-Gurion University
Assignment 1
• I uploaded a fix to 2.1
– Thanks to Morad for noticing the bug
• In 1.2 you have to reason about termination/nontermination without relying on external proofs that the
GCD algorithm terminates
– Look at the loop and reason about how each iteration
brings the program closer to termination or drives it
further away
• LaTeX
– Use \lsyn \rsyn for
– Use \Asem and \Bsem for A and B
– Look at how hw1.tex uses macros and notations and try to
follow
2
Warm-up exercises
1. Define program state:
2. Define structural semantics configurations:
3. Define the form of structural semantics
transitions:
3
Tentative syllabus
Program
Verification
Program
Analysis Basics
Abstract
Interpretation
fundamentals
Analysis
Techniques
Operational
semantics
From Hoare
Logic to Static
Analysis
Lattices
Numerical
Domains
Hoare Logic
Control Flow
Graphs
Fixed-Points
Pointer analysis
Applying Hoare
Logic
Equation
Systems
Chaotic
Iteration
Shape
Analysis
Weakest
Precondition
Calculus
Collecting
Semantics
Galois
Connections
Interprocedural
Analysis
Proving
Termination
Using Soot
Domain
constructors
Data structures
Widening/
Narrowing
Automated
Verification
4
Agenda
• Basic concepts of correctness
• Axiomatic semantics (pages 175-183)
– Motivation
– First-order logic reminder
– Hoare Logic
5
program correctness
6
Program correctness concepts
• Specification = a certain relationship between
initial state and final state Main focus of
this course
• Partial correctness = specifications that hold
if the program terminates
• Termination = program always terminates
– i.e., for every input state
partial correctness + termination = total correctness
Other correctness concepts exist:
liveness, resource usage, …
7
Verifying factorial
with structural semantics
8
Structural semantics for While
[ass]
x:=a,   [xAa]
[skip]
skip,   
[comp1]
S1,   S1’, ’
S1; S2,   S1’; S2, ’
[comp2]
S1,   ’
S1; S2,   S2, ’
[iftt]
if b then S1 else S2,   S1, 
if Bb  = tt
[ifff]
if b then S1 else S2,   S2, 
if Bb  = ff
[whilett]
while b do S,  
S; while b do S, 
if Bb  = tt
[whileff]
while b do S,   
if Bb  = ff
9
Factorial example
fac
y:=1; while (x1) do (y:=y*x; x:=x–1)
• Factorial partial correctness specification =
if the statement terminates then the final
value of y will be the factorial of the initial
value of x
– What if  x < 1?
• Formally, using structural semantics:
fac,  * ’ implies ’ y = ( x)!
10
Factorial proof strategy
fac
y:=1; while (x1) do (y:=y*x; x:=x–1)
Lemma 1
Lemma 2
Lemma 3
• Lemma 1:
if  x>1 then
y:=y*x; x:=x–1,  * ’ implies
 y * ( x)! = ’ y * (’ x)! and ’ x1
• Lemma 2:
if  x1 then
while (x=1) do (y:=y*x; x:=x–1),  * ’ implies
 y * ( x)! = ’ y * (’ x)! and ’ x=1
• Lemma 3:
if  x1 then fac,  * ’ implies ’ y = ( x)!
11
Factorial example: lemma 1
fac
y:=1; while (x1) do (y:=y*x; x:=x–1)
• Lemma 1:
if  x>1 then y:=y*x; x:=x–1,   * ’ implies
 y * ( x)! = ’ y * (’ x)! and ’ x1
• Proof:
Assume  x>1
y:=y*x; x:=x–1,   x:=x–1, [y y* x] 
[y y* x, x x–1] = ’
• Now ’ y * (’ x)! = ( y* x) * ( x–1)! =  y * ( x)!
And since’ x =  x-1 we have that ’ x1
• QED
12
Factorial example: lemma 2
fac
y:=1; while (x1) do (y:=y*x; x:=x–1)
• Lemma 2:
if  x1 then while (x1) do (y:=y*x; x:=x–1),  * ’
implies
 y * ( x)! = ’ y * (’ x)! and ’ x=1
• Proof:
– Case 1:  x=1
– Case 2:  x1 – meaning  x>1
13
Factorial example: lemma 2, case 1
fac
y:=1; while (x1) do (y:=y*x; x:=x–1)
• Lemma 2:
if  x1 then while (x1) do (y:=y*x; x:=x–1),  * ’
implies
 y * ( x)! = ’ y * (’ x)! and ’ x=1
• Proof:
W,  
• Claim holds
14
Factorial example: lemma 2, case 2
fac
y:=1; while (x1) do (y:=y*x; x:=x–1)
• Lemma 2:
if  x1 then while (x1) do (y:=y*x; x:=x–1),  * ’ implies
 y * ( x)! = ’ y * (’ x)! and ’ x=1
• Proof: (by induction on the length of the derivation sequence)
W,   (y:=y*x; x:=x–1); W,  * W, ’’ * ’
• From lemma 1 we have that
 y * ( x)! = ’’ y * (’’ x)! and ’’ x1
• Applying Lemma by induction (case 1 is the base case) gives us that
’’ y * (’’ x)! = ’ y * (’ x)! and ’ x=1
• Combining the two, we get
’ y * (’ x)! = ’’ y * (’’ x)! =  y * ( x)!
• and ’ x=1
• QED
15
Factorial example: lemma 3
fac
y:=1; while (x1) do (y:=y*x; x:=x–1)
• Lemma 3:
if  x1 then fac,  * ’ implies ’ y = ( x)!
• Proof:
• Assume  x1
• Now y:=1; W,   W, [y1] and [y1] x =  x
• Therefore, we can apply lemma 2 and obtain
W, [y1]  * ’ and
 [y1] y * ( [y1] x)! = ’ y * (’ x)! and ’ x=1
• Simplifying this yields:
• 1 * ( x)! = ’ y * 1! and ’ x=1
Meaning: ’ y = ( x)!
• QED
16
How easy was that?
• Proof is very laborious
– Need to connect all transitions and argue about
relationships between their states
– Reason: too closely connected to semantics of
programming language
• Proof is long
– Makes it hard to find possible mistakes
• How did we know to find this proof?
– Is there a methodology?
17
I’ll use
operational
semantics
Can you
prove my
program
correct?
Better use
axiomatic
verification
18
A systematic approach
to program verification
19
Axiomatic verification approach
• What do we need in order to prove that the
program does what it supposed to do?
• A language to express specifications
• Compare the behavior with the one obtained by the
operational semantics
• Develop a proof system for showing that the
program satisfies the specification
• Mechanically use the proof system to show
correctness
20
Axiomatic semantics originators
Robert Floyd
1967: use assertions
as foundation for static
correctness proofs
C.A.R. Hoare
1969: use Floyd’s ideas
to define axiomatic
semantics
“An axiomatic basis for
computer programming”
Edsger W. Dijkstra
Predicate transformer
semantics: weakest
precondition and
strongest postcondition
21
Assertions, a.k.a Hoare triples
{P}C{Q}
precondition
statement
a.k.a command
postcondition
• P and Q are state predicates expressed as logical formulas
– Example: x>0
• If P holds in the initial state, and
if execution of C successfully terminates on that state,
then Q will hold in the state in which C halts
• C is not required to always terminate
{true} while true do skip {false}
22
Total correctness assertions
[P]C[Q]
• If P holds in the initial state,
execution of C must terminate on that state,
and Q will hold in the state in which C halts
23
Specifying correctness
of factorial
24
Factorial example:
specify precondition/postcondition
{?}
y := 1; while (x=1) do (y := y*x; x := x–1)
{?}
25
First attempt
We need a way to
“remember” value of
x before execution
{ x>0 }
y := 1; while (x=1) do (y := y*x; x := x–1)
{ y=x! }
Holds only for value of x at
state after execution finishes
26
Fixed assertion
A logical variable, must not appear in statements – immutable.
Also called a ghost variable.
{ x=n
n>0 }
y := 1; while (x=1) do (y := y*x; x := x–1)
{ y=n! }
27
The proof outline
Background
axiom
{ n!=n*(n-1)! }
{ x>0
x=n }
y := 1;
{ x>0
y*x!=n!
n x }
while (x=1) do
{ x-1>0
(y*x)*(x-1)!=n!
n (x-1)
}
y := y*x;
{ x-1>0
y*(x-1)!=n!
n (x-1) }
x := x–1
{ y*x!=n!
n>0
x=1 }
28
Factorial spec and proof in Dafny
function Factorial(n: int): int
requires n >= 1
{
if n == 1 then 1 else n * Factorial(n - 1)
}
method ComputeFactorial(n: int) returns (y: int)
requires n >= 1
ensures y == Factorial(n)
{
var x := n;
y := 1;
while x != 1
invariant y * Factorial(x) == Factorial(n)
decreases x
{
y := y * x;
x := x - 1;
}
}
online
Method arguemnts are
immutable in Dafny
29
Formalizing partial
correctness via Hoare logic
30
States and predicates
•
– program states (State)
– undefined
• A state predicate P
is a (possibly infinite)
set of states
•  P
P

– P holds in state 
31
Formalizing Hoare triples
C =
’
if C,  *’
else
Q
P

C
’
• {P}C{Q}
. ( P C,  * ’)
alternatively
– Convention:
P for all P

. P
C  Q
–
, ’
’
Q
32
How do we express predicates?
• Extensional approach
– Abstract mathematical functions
P : State {tt, ff}
• Intensional approach
– via language of formulae
33
An assertion language
• Bexp is not expressive enough to express
predicates needed for many proofs
– Extend Bexp
• Allow quantification
– z. …
– z. …
• z. z = kn
• Import well-known mathematical concepts
– n!  n  (n-1)   2  1
34
An assertion language
Either a program variables
or a logical variable
a ::= n | x | a1 + a2 | a1 a2 | a1 – a2
A ::= true | false
| a1 = a2 | a1 a2 | A | A1 A2 | A1
| A1 A2 | z. A | z. A
A2
35
Some
FO logic
definitions
before we get
to the rules
36
Free/bound variables
• A variable is said to be bound in a formula
when it occurs in the scope of a quantifier
Otherwise it is said to be free
– i. k=im
– (i+10077)i. j+1=i+3)
• FV(A)  the free variables of A
• Defined inductively on the abstract syntax tree
of A
37
Computing free variables
FV(n)
FV(x)
FV(true)
{x}
FV(a1+a2)
FV(a1 a2)
FV(A1
FV(A1
FV(false) {}
FV(a1 a2)
A2)
A2)
FV(a1)
FV(a1-a2)
FV(a2)
FV(A1
A2)
FV(A1)
FV(A2)
FV( A) FV(A)
FV( z. A) FV( z. A)
FV(a1=a2)
FV(A) \ {z}
38
Substitution
• An expression t is pure if it does not contain
quantifiers
• A[t/z] denotes the assertion A’ which is the
same as A, except that all instances of the free
variable z are replaced by t
• A i. k=i m
A[5/k] = …?
A[5/i] = …?
39
Calculating substitutions
n[t/z] = n
x[t/z] = x
x[t/x] = t
(a1 + a2)[t/z] = a1[t/z] + a2[t/z]
(a1 a2)[t/z] = a1[t/z] a2[t/z]
(a1 - a2)[t/z] = a1[t/z] - a2[t/z]
40
Calculating substitutions
true[t/x] = true
false[t/x] = false
(a1 = a2)[t/z] = a1[t/z] = a2[t/z]
(a1 a2)[t/z]
= a1[t/z] a2[t/z]
( A)[t/z] = (A[t/z])
(A1 A2)[t/z] = A1[t/z] A2[t/z]
(A1 A2)[t/z] = A1[t/z] A2[t/z]
(A1 A2)[t/z] = A1[t/z] A2[t/z]
(
(
(
(
z. A)[t/z] =
z. A)[t/y] =
z. A)[t/z] =
z. A)[t/y] =
z. A
z. A[t/y]
z. A
z. A[t/y]
41
Equivalence in FO logic
• We write A B if for all states 
if  A then  B
– { |  A } { |  B }
– For every predicate A: false
• We write A
– false
B if A
A
B and B
true
A
5=7
• In writing Hoare-style proofs, we will often
replace a predicate A with A’ such that A A’
and A’ is “simpler”
42
six are
completely
enough
and now…
the rules
43
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 }
What’s different
about this rule?
[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
44
Assignment rule
[assp]
{ P[a/x] } x := a { P }
• A “backwards” rule
• x := a always finishes
• Why is this true?
[xAa]
P
– Recall operational semantics:
x:= a,  
[ass]
[xAa]
• { | [xAa   P}  {[xAa | [xAa
 P}
45
Practice with Dafny { P[a/x] } x := a { P }
Ghost methods do not get
compiled to code
Filters out states that do
not satisfy the predicate
A proof obligation
ghost method AssignRuleTest1() {
var x, y, z;
assume ???;
x := y * z;
assert x < 9;
}
{
} x:=y*z {x<9}
ghost method AssignRuleTest2() {
var x: int, y: int , z: int;
assume ???;
x := x + 1;
assert x > 8;
}
{
} x:=x+1 {x>8}
ghost method AssignRuleTest3() {
var x: int, y: int , z: int , w: int;
assume ???;
x := y * z;
assert w == 5;
}
{
} x:=y*z {w=5}
46
skip rule
[skipp] { P } skip { P }
48
Composition rule
{ P } S1 { Q }, { Q } S2 { R }
[compp]
{ P } S1; S2 { R }
Lemma:
S1,  * ’, S2, ’ * ’’
S1; S2,  * ’’
• Holds when S1 terminates in every state where P
holds and then Q holds
and S2 terminates in every state where Q holds
and then R holds
49
Practice with Dafny
ghost method CompositionRuleTest() {
var x: int;
assume x < 9;
x := x + 1;
assert ???;
x := x * 2;
assert x < 20;
}
{
x
{
x
{
x < 9
}
:= x + 1
}
:= x * 2;
x < 20
}
50
Condition rule
{ b P } S1 { Q }, { b P } S2 { Q }
[ifp]
{ P } if b then S1 else S2 { Q }
• Intuitively, it means:
– Split cases on either b holds or not
– For each case make sure Q holds
– Conclude that Q holds on both cases
51
Practice with Dafny
ghost method ConditionRuleTest() {
var x: int, y: int;
assume x > 8 || x < -8;
if x > 0
{
y := x;
}
else {
y := -1 * x;
}
assert ???;
}
52
Loop rule
{b P}S{P}
[whilep] { P } while b do S { b
}
P
• Here P is called an invariant for the loop
– Holds before and after each loop iteration
– Finding loop invariants – most challenging part of
proofs
• When loop finishes, b is false
53
Example: write a specification
{ }
while (timer  0) do
timer := timer – 1
{ }
• “The program should count to zero”
54
Practice with Dafny
ghost method Timer(x: int) returns (timer: int)
requires x >= 0;
ensures timer == 0;
{
timer := x;
while (timer != 0)
invariant timer >= 0;
{
timer := timer - 1;
}
}
55
Rule of consequence
{ P’ } S { Q’ }
[consp]
{P}S{Q}
if P P’ and Q’ Q
• Allows strengthening the precondition and
weakening the postcondition
• The only rule that is not related to any specific
type of statement
56
Rule of consequence
{ P’ } S { Q’ }
[consp]
{P}S{Q}
if P P’ and Q’ Q
• Why do we need it?
• Allows the following
{y*z<9} x:=y*z {x<9}
{y*z<9 w=5} x:=y*z {x<9}
57
See you next time
58