1 / 27

Specifying Temporal Properties of Software Using the Bandera Specification Language

Specifying Temporal Properties of Software Using the Bandera Specification Language. [U. Hawaii] [Kansas State] [Kansas State] [Kansas State]. James Corbett Matthew Dwyer John Hatcliff Robby. http://www.cis.ksu.edu/santos/bandera. Graphical User Interface. Optimization Control.

Télécharger la présentation

Specifying Temporal Properties of Software Using the Bandera Specification Language

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Specifying Temporal Properties of Software Using the Bandera Specification Language [U. Hawaii] [Kansas State] [Kansas State] [Kansas State] James Corbett Matthew Dwyer John Hatcliff Robby http://www.cis.ksu.edu/santos/bandera

  2. Graphical User Interface Optimization Control Checker Inputs ? void add(Object o) { buffer[head] = o; head = (head+1)%size; } Object take() { … tail=(tail+1)%size; return buffer[tail]; } Model Checkers Transformation & Abstraction Tools Checker Outputs Java Source Error Trace Mapping Bandera Bandera:An open tool set for model-checking Java source code Slicing Temporal Specification Abstract Interpretation Static Analysis

  3. Issue: Rendering Requirement • Often difficult to formalize a requirement in temporal logic “Between the window open and the window close, button X can be pushed at most twice.” …is rendered in LTL as... []((open && <>close) -> ((!pushX && !close) U (close || ((pushX && !close) U (close || ((!pushX && !close) U (close || ((pushX && !close) U (close || (!pushX U close))))))))))

  4. Graphical User Interface mismatch! CTL CSP void add(Object o) { buffer[head] = o; head = (head+1)%size; } Object take() { … tail=(tail+1)%size; return buffer[tail]; } SMV FDR Transformation & Abstraction Tools Java Source Bandera Issue: Checker Dependence Checker Inputs LTL LTL Temporal Specification Model Checkers Spin

  5. Issue: Representation Dependence • Source’s representation Heap.b.head == Heap.b.tail • Model’s representation (((_collect(heap_b) == 1)\ && (BoundedBuffer_col.instance[_index(heap _b)].head == BoundedBuffer_col.instance[_index(heap _b)].tail) )\ || ((_collect(heap _b) == 3)\ && (BoundedBuffer_col_0.instance[_index(heap _b)].head == BoundedBuffer_col_0.instance[_index(heap _b)].tail) )\ || ((_collect(heap _b) == 0) && TRAP))

  6. Variables b1 b2 b3 Heap object Issue: Naming Heap-allocated Objects Consider multiple instances of a bounded buffer class... Requirement: If a buffer instance becomes full, it will eventually become non-full. In general, a heap object has no program-level name that persists throughout the lifetime of the object.

  7. Quantification BSL: Bandera Specification Language • Propositions stated in terms of source code features • Based on an extensible system of temporal specification patterns • Heap objects are named via object quantification Temporal Property Specification (via pattern language) Assertion Property Specification (selective enabling) Predicate Definition Assertion Definition

  8. Pre-conditions @assert PRE <name> <exp>; • Post-conditions @assert POST <name> <exp>; • Arbitrary Locations @assert LOCATION[<label>] <name> <exp>; Assertion Forms /** * @assert * PRE foo: (I > 5); * POST bar: (I < 10); * LOCATION[here] checka: * (m.q.a == 4); */ public mymethod(int I) { … … here: … … }

  9. Static/Instance Data Constraints • Invocation @observable [static] EXP <name> <exp>; @observable INVOKE <name> <exp>; • Return @observable RETURN <name> <exp>; • Arbitrary Locations @observable LOCATION[<label>] <name> <exp>; Predicate Forms

  10. Relationship between assertion PRE and predication INVOKE Semantic Issues @assert PRE <name> <exp>; IMPLICATION: holds if <exp> is true WHEN control is at entry of method (true otherwise) @observable INVOKE <name> <exp>; CONJUNCTION: holds if <exp> is true AND control is at entry of method

  11. Semantic Issues (o1 != null) && (o1.next != null) && ( ) o1.next.value == 0

  12. Given a software requirement... Methodology: Property Specification • Identify observables (propositions) in requirement • Define propositions in source Java-doc comments • Use GUI to select appropriate temporal pattern parameterized by declared observables • Add quantification if property contains instance propositions.

  13. Initialization head tail head head tail tail Bounded Buffer class BoundedBuffer { Object [] buffer; int head; /* next available slot */ int tail; /* last available slot */ int bound; /* max # of elements */ public BoundedBuffer(int b) {…} public synchronized boolean isEmpty() {…} public synchronized void add(Object o) {…} public synchronized Object take () {…} } Add,Add Add,Take,Take

  14. Initialization head tail Add,Add head head tail Add,Take,Take tail Bounded Buffer public BoundedBuffer(int b) { bound = b; buffer = new Object[bound]; head = 0; tail = bound-1; } public synchronized boolean isEmpty() { return head == ((tail+1) % bound); }

  15. Initialization head tail Add,Add head head tail Add,Take,Take tail Bounded Buffer public synchronized void add(Object o) { while ( tail == head ) try { wait(); } catch (InterruptedException ex) {} buffer_[head] = o; head = (head+1) % bound; notifyAll(); } public synchronized Object take() { while (head == ((tail+1) % bound)) try { wait(); } catch (InterruptedException ex) {} tail = (tail+1) % bound; notifyAll(); return buffer_[tail]; }

  16. Bounded Buffer Properties • Full buffers eventually become non-full • Indices always stay in range • Empty buffers must be added to before being taken from • Buffers are constructed with positive bounds • Elements are always added in correct position

  17. Requirement 1: If a buffer becomes full, it will eventually become non-full. Bandera Specification: FullToNonFull: {!Full(b)} responds to {Full(b)} globally; Property Specification /** * @observable * EXP Full: (head == tail); */ class BoundedBuffer { Object [] buffer; int head, tail, bound; public synchronized void add(Object o) {…} public synchronized Object take () {…} } forall[b:BoundedBuffer].

  18. Bandera Specification: IndexRangeInvariant: {HeadRange(b) && TailRange(b)} is universal globally; Property Specification /** * @observable * EXP HeadRange: * head >= 0 && head < bound; * Exp TailRange: * tail >= 0 && tail < bound; */ Requirement 2: Indices always stay in range. class BoundedBuffer { Object [] buffer; int head, tail, bound; public synchronized void add(Object o) {…} public synchronized Object take () {…} } forall[b:BoundedBuffer].

  19. Bandera Specification: NoTakeWhileEmpty: {take.Return(b)} is absent after {Empty(b)} until {add.Call(b)}; Property Specification /** * @observable * EXP Empty: * head == ((tail+1) % bound); */ Requirement 3: Empty buffers must added to before being taken from class BoundedBuffer { int head, tail, bound; public synchronized void add(Object o) {…} public synchronized Object take () {…} } /** * @observable INVOKE Call; */ /** * @observable RETURN Return; */ forall[b:BoundedBuffer].

  20. Bandera Specification: PositiveBound: enable assertions {PositiveBound}; Property Specification Requirement 4: /** * @assert * PRE PositiveBound: * (b > 0); */ Buffers are constructed with positive bounds public BoundedBuffer(int b) { bound = b; buffer = new Object[bound]; head = 0; tail = bound-1; }

  21. Quantification forall[b:BoundedBuffer].P(b) • Quantified set is not fixed • varies within executions • varies across executions • Solution • by adding a state variable (for b) that will eventually be bound non-deterministically to each instance • by enabling checking of the formula only when variable is bound to an instance

  22. Quantification (Cont’d) (!selected U (selected && P(b))) || []!selected (!selected (selected && P(b))) []!selected !selected [1] new BoundedBuffer(n) new BoundedBuffer(n) [1] selected !selected [2] new BoundedBuffer(m) new BoundedBuffer(m) new BoundedBuffer(m) !selected [1] selected [2] selected new BoundedBuffer(k) [3] new BoundedBuffer(k) new BoundedBuffer(k) new BoundedBuffer(k) [1] selected [2] selected [3] selected !selected

  23. Quantification (Cont’d) class heap { public static BoundedBuffer b; } class BoundedBuffer { Object [] buffer; int head, tail, bound; public BoundedBuffer(int n) { ... if (heap.b == null && Bandera.choose()) { heap.b = this; } } } class BoundedBuffer { Object [] buffer; int head, tail, bound; public BoundedBuffer(int n) { ... } }

  24. Quantification (Cont’d) forall[b:BoundedBuffer]. {Full(b)} leads to {!Full(b)} globally; (heap.b == null U (heap.b != null && ([](heap.b.head == heap.b.tail) -> <>(heap.b.head != heap.b.tail)))) || [](heap.b == null)

  25. Specification: PositiveBound: enable assertions {PosBound}; Embedding Assertion class BoundedBuffer { Object [] buffer; int head, tail, bound; public BoundedBuffer(int n) {…} public synchronized void add(Object o) {…} } /** * @assertion * PRE PosBound1: (n > 0); */ public BoundedBuffer(int n) { Bandera.assert(n > 0); ... }

  26. Test Result & Assessments Property Sliced Never-claim Stored States States BufferAssertions Yes - 17797 IndexRangeInv Yes 14 45215 IndexRangeInv, BufferAssertions Yes 14 115387 FullToNonFull Yes 25 64687 FullToNonFull, BufferAssertions Yes 25 154842

  27. Summary • Motivation: Makes it easier for non-expert to write temporal specifications for Java programs • How? • Source level • Pattern based approach • Tool supports: • automatic translation • guides for writing specification (GUI) • HTML documentation generation

More Related