### Slides - Index of

```Automated Verification with
HIP and SLEEK
Asankhaya Sharma
Goal
• Design and build software that is correct by
construction
• Needed: Automatic tools for establishing
software correctness
• Such tools can
– Search for standard problems like memory access
violations or array index out of bounds
– Check if a program does what it is supposed to do
with respect to a specification
Why a Need for Automatic Tools?
Let the tool fill in the details
A Tale of Two Tools
• HIP
– Automatically applies a given set of Hoare rules
• SLEEK
– Discharges the proof obligations resulting from
the rule of consequence and the frame rule
• Under development since 2006
– 180k lines of OCaml
– Currently 6 PhD students; 3 graduated
Overview
Code
Pre/Post
code verifier
(HIP)
Predicates
Lemmas
separation
logic prover
(SLEEK)
range of pure provers …
Omega, MONA, Isabelle, Coq, SMT, Redlog, MiniSAT, Mathematica
An Example – List Length
struct node{
int val;
struct node* next;
};
int length(struct node* p)
{
if(p == NULL) return 0;
else return 1 + length(p->next);
}
List Predicate
Example of Acyclic List : list(x)
x
null
list(self)  self=null
 ∃r . self node(_,r)  list(r)
pointer to memory
spatial conjunction
Syntactic Abbreviation (ASCII)
list(self)  self=null
 ∃ r . self node(_, r)  list(r)
list == self=null
or self::node_, r  r::list
implicit existential instantiation
Verify with Shape Property
struct node{
int val;
struct node* next;
};
/*@
list<> == self=null or self::node<_,q>*q::list<>;
*/
int length(struct node* p)
/*@
requires p::list<>
ensures p::list<>;
*/
{
if(p == NULL) return 0;
else return 1 + length(p->next);
}
Predicate Definition
Method Pre and
Post condition
Memory Safety
With Size
parameter on length of linked list
listn == self=null & n=0
or self::node_, r  r::listn-1
inv n >= 0
predicate invariant
x::ll5
x
null
Verify with Shape and Size
int length(struct node* p)
/*@
requires p::list<n>
Memory Safety
ensures p::list<n> & res=n;
*/
Length of the List
{
if(p == NULL) return 0;
else return 1 + length(p->next);
}
With Size and Bag
listn,B == self=null & n=0 & B={}
or self::nodev, r  r::listn-1,B1
& B = B1 U {v}
inv n >= 0 & n=|B|
Verify with Shape, Size and Bag
int length(struct node* p)
/*@
requires p::list<n,B>
ensures p::list<n,B> & res=n;
*/
{
if(p == NULL) return 0;
else return 1 + length(p->next);
}
Memory Safety
Length of the List
Bag of Values
Automated Verification
int length(struct node* p)
/*@
requires p::list<n>
Pre condition Checking
ensures p::list<n> & res=n;
*/
{
if(p == NULL) return 0;
Memory dereference Checking
// p=null & n = 0 & res = 0 |- p::list<n> & res = n
// p::ll<n> & p!=null |- p::node<val,nxt>
// p::node<_,q> * q::ll<n-1> & p!=null & q = r |- r::ll<m>
else return 1 + length(p->next);
// p::node<_,q> * q::ll<n-1> & x!=null & res = 1 + n – 1
|- p::ll<n> & res = n
Post condition Checking
}
SLEEK
• Automatic Checking of Entailment
• Custom decision procedure for the spatial
fragment (Separation Logic)
– Handles user-defined data structures and inductive
predicates
• Uses off-the-shelf provers to discharge:
– Linear Arithmetic (using Omega)
• Also available as a tactic in Coq
– Bag Expressions (using MONA)
• Sound but incomplete
Numerical Examples for SLEEK
Checking implications with integer constraints:
Valid.
checkentail x > 5 |- x > 0.
InValid.
checkentail x > 5 |- x < 0.
InValid.
checkentail x > 5 |- x > 6.
checkentail x > 1 & y > 1 & r = x + y |- r > 3.
Valid.
SLEEK uses Omega for these examples
List Examples for SLEEK
checkentail x::node<1,null> |- x::list<n,B>. Valid.
checkentail x::node<17,null> |Valid.
x::list<n,B> & B = {17}.
checkentail x::node<2,y> * y::list<m,{2} |Valid.
x::list<n,B>.
checkentail x::list<1,{2}> |- x::node<2,null>.
Valid.
checkentail x::list<2,{2,3}> |- x::node<2,null>.
InValid.
HIP
• Automatic checking of pre/post for methods
– Handle conditional, loops, methods
– With arrays, data structures, dynamic memory
allocation
– Supports Multiple pre/post specifications,
structured specifications, termination
specifications
• Sound but incomplete
• Automated with the help of SLEEK
Append Example with HIP
• What should be the specification for the
following method ?
void append(node* x, node* y)
requires ?
ensures ?
{
if(x->next==NULL) x->next=y;
else append(x->next,y);
}
Append Example with HIP
• Is the following specification which aims to
guarantee memory safety correct?
void append(node* x, node* y)
requires x::list<> * y::list<>
ensures x::list<>
{ No, null pointer dereference possible
if(x->next==NULL) x->next=y;
else append(x->next,y);
}
Append Example with HIP
• Correct specification for safety
void append(node* x, node* y)
requires x::list<> * y::list<> & x!=null
ensures x::list<>
{
if(x->next==NULL) x->next=y;
else append(x->next,y);
}
Append Example with HIP
• With size and bag properties
void append(node* x, node* y)
requires x::list<n1,B1> * y::list<n2,B2> & x!=null
ensures x::list<n1 + n2, B1 U B2>
{
if(x->next==NULL) x->next=y;
else append(x->next,y);
}
Multiple Specifications
• Same method may be called in different
calling contexts
• Verify using different specifications for each
scenario
• Which sorting algorithm may require an
append function for two sorted lists ?
– Quick Sort (and Merge Sort)
With Bag and Sortedness
lsortn,B == self=null & n=0 & B={}
or self::nodev, r  r::lsortn-1,B1
& B = B1 U {v} & ∀x ∈ B1. v<=x
inv n >= 0 & n=|B|
Verify with Multiple Specifications
void append(node* x, node* y)
requires x::list<n1,B1> * y::list<n2,B2> & x!=null
ensures x::list<n1 + n2, B1 U B2>
requires x::lsort<n1,B1> * y::lsort<n2,B2>
& x!=null & ∀a ∈ B1. ∀b ∈ B2. a<=b
ensures x::lsort<n1 + n2, B1 U B2>
{
if(x->next==NULL) x->next=y;
else append(x->next,y);
}
List Segment with Size
lsegp,n == self=p & n=0
or self::node_,r  r::lsegp,n-1
inv n >= 0
x
x::lsegy,3
y
y::lsegx,2
Circular List with Size
clistn == self::node_,r  r::lsegself,n-1
inv n >= 1
x::clist3
x
r
r::lsegx,2
Use of Multiple Pre/Post
void append(node* x, node* y)
requires x::list<n> & x != null & x = y
ensures x::clist<n>
requires x::list<n> & x != null
ensures x::lseg<y,n>
{
if(x->next==NULL) x->next=y;
else append(x->next,y);
}
Binary Search Tree
How do we express a binary search tree ?
tree<> == self=null
or self::node<v,l,r> * l::tree<> * r::tree<>
Shape Property for Tree
Binary Search Tree
5
3
1
7
Sortedness property
4
bst<B> == self=null & B = {}
or self::node<v,l,r> * l::bst<B1> * r::bst<B2>
& B = {v} U B1 U B2
& ∀w ∈ B1. v>=w & ∀w ∈ B2. v<=w
AVL Tree
How do we specify height balanced trees ?
avl<h,B> == self=null & B = {} & h = 0
or self::node<v,l,r> * l::avl<h1,B1> * r::avl<h2,B2>
& B={v}UB1UB2 & ∀w∈B1.v>=w & ∀w∈B2.v<=w
& h = 1 + max(h1,h2) & h2<=h1+1 & h1<=h2+1
Conclusions
• HIP and SLEEK Verification System
– Automated
• Given pre/post and loop invariants
– Modular and scalable
• Each method verified independently
– Expressive
• From shape, size, bag properties towards functional
correctness
• Total correctness with Termination and NonTermination proving
Perspectives
• Hardware community has accepted
verification in their design phase
• Verified software is the future for guarantying
high assurance and reliability
• Many challenges remain on scalability,
automation, expressivity, concurrency,
inference and higher order programs
Questions?
• We will try out some examples in Lab
tomorrow using TeachHIP
• TeachHIP is a Web Interface to
– Try out HIP and SLEEK without installing any
software
– Available at
http://loris-7.ddns.comp.nus.edu.sg/~project/TeachHIP/
• Contact
– [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */