120 likes | 236 Views
Automated Verification with HIP and SLEEK. Asankhaya Sharma. Recall the List length Example. 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.
E N D
Automated Verification withHIP and SLEEK Asankhaya Sharma
Recall the List length Example 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
With Immutability int length(struct node* p)/*@requires p::list<>@I ensures res=n;*/{ if(p == NULL) return 0; else return 1 + length(p->next);} With Immutability Annotation More concise and precise specification
Recall the List Append Example void append(node* x, node* y)requires x::list<n> & x != null & x = yensures requires x::list<n> & x != null ensures{ if(x->next==NULL) x->next=y; else append(x->next,y);} x::clist<n> x::lseg<y,n>
With Immutability void append(node* x, node* y)requires x::lseg<p>@I * p::node<a,null>ensures p::node<a,y>{ if(x->next==NULL) x->next=y; else append(x->next,y);} Immutable List Segment Cut point preservation
Aliasing Example int foo(cell x, cell y)requires x::cell<a> * y::cell<b> ensures x::cell<a> * y::cell<b> & res = a+b requires x::cell<a> & x = yensures x::cell<a> & res = 2*a;{ return x.val + y.val;}
Heap Sharing with Immutability int foo(cell x, cell y)requires x::cell<a>@I &y::cell<b>@Iensures res = a+b{ return x.val + y.val;} Allows Aliasing
Immutable Specifications • Many programs do not change their input • Use immutable specifications, where possible • More information (about the code) • More concise (for multiple pre/post) • More accurate (as cut points are preserved) • More efficient (as less folding is needed) • More control (don’t modify data)
Verification of Concurrent Programs • Fork/join concurrency + (mutex) locks + barriers • Properties • Functional correctness • Data-race freedom • Deadlock freedom • Permission-based heaps, e.g. x::cell(0.5)<1> * y::cell(0.5)<2>
Example : thread as resource data cell { intval;} • void thread1 (cell x) requires x::cell<0> * y::cell<0>ensures x::cell<1> * y::cell<2> ; • { x.val = x.val + 1; • y.val = y.val + 2;} • void thread2 (thrd t1, cell y) requires t1::thrd<y::cell<2>>ensures y::cell<4> ;{ join(t1); • y.val = y.val + 2;} void main() requires true ensure true; { cell x = new cell(0); • cell y = new cell(0); • thrd t1 = fork(thread1,x,y); • //{t1::thrd<x::cell<1> * y::cell<2>>} • //{t1::thrd<x::cell<1>> * t1::thread<y::cell<2>>} • thrd t2 = fork(thread2,t1,y); • //{t1::thrd<x::cell<1>> • join(t1); • x.val = x.val + 1; • join(t2); • assert( x::cell<2> * y::cell<4> ); }
Example main x,y thread1 x,y thrd t1 = fork(thread1,x,y); t1 thread2 thrd t2 = fork(thread2,t1,y); t1 t1,t2 x y join(t1); join(t1); multi-join t2,x y join(t2); x,y
Further Reading • David, Cristina, and Wei-Ngan Chin. "Immutable specifications for more concise and precise verification." In ACM SIGPLAN Notices, vol. 46, no. 10, pp. 359-374. ACM, 2011.