260 likes | 343 Views
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.
E N D
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 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
Property Specification Problem • Difficult to formalize a requirement in temporal logic “Between the key being inserted and the key being removed, the ignition can be activated at most twice.” …is rendered in LTL as... []((keyIn /\ <>keyRem) -> ((!activate /\ !keyRem) U (keyRem \/ ((activate /\ !keyRem) U (keyRem \/ ((!activate /\ !keyRem) U (keyRem \/ ((activate /\ !keyRem) U (keyRem \/ (!activate U keyRem))))))))))
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
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))
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.
Quantification BSL: Bandera Specification Language • Propositions stated in terms of source code features • Temporal relationships are expressed using field-tested specification patterns • Heap objects are named via object quantification Temporal Property Specification (via pattern language) Assertion Property Specification (selective enabling) Predicate Definition Assertion Definition
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
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]; }
Bounded Buffer Properties • Buffers are constructed with positive bounds • Full buffers eventually become non-full • Empty buffers must be added to before being taken from • Indices always stay in range • Elements are always added in correct position
Quantification Reminder --- Language Structure Temporal Property Specification (via pattern language) Assertion Property Specification (selective enabling) Predicate Definition Assertion Definition
Pre-conditions @assert PRE <name> <exp>; • Post-conditions @assert POST <name> <exp>; • Arbitrary Locations @assert LOCATION[<label>] <name> <exp>; Assertion Forms class MyClass { int count = 0; … … /** * @assert * PRE foo: (I > 5); * POST bar: (count > 10); * LOCATION[here] checka: * (m.q.a == 4); */ public mymethod(int I) { … … here: … … } }
Bandera Specification: PositiveBound: enable assertions {PositiveBound}; Assertion Checking Requirement: /** * @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; }
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
Classification • Occurrence Patterns: • require states/events to occur or not to occur • Order Patterns • constrain the order of states/events Pattern Hierarchy (Dwyer, Avrunin, Corbett, ICSE’99) Property Patterns Occurrence Order Absence Bounded Existence Chain Response Precedence Universality Existence Chain Precedence Response
Requirement: 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].
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: 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].
Quantification forall[b:BoundedBuffer].P(b) • Quantified set (set of Bounded Buffers) 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
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
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) { ... } }
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)
Next Steps: Avionics Domain • Case studies of avionics code leading to domain-specific patterns • Working with Rockwell-Collins ATC as they developing FAA coding guidelines for using OO in avionics platforms (supplement to DO-178B) • Contains various restrictions on patterns of use • Ultimately, use model-checking results as evidence to help justify FAA certification
Next Steps: Richer Specifications • Integration of BSL with the Java Modeling Language (JML) developed by Gary Leavens at Iowa State. • JML is also used as the specification language for… • ESC/Java (Compac) • LOOP (Bart Jacobs) • Compiles Java to PVS theories for complete verification of source code. • In the long term, we’re interested in other forms of verification.
Next Steps: Real-time Specifications • Including notions of time in patterns <ReadSensor> responds to <SensorInput> within at most <K> globally …where <K> is some number of time units
Next Steps: Other Specification Forms • Compiling UML statecharts into Bandera’s intermediate representation • Support specification of source code properties via hierarchical state machines • Incorporate refinement checking at various levels. …inspiration from Rajeev Alur et. al.
For more details… • Public release of the tool set • Tutorial with repository of simple examples • Tutorial lecture slides • Pattern web pages http://www.cis.ksu.edu/santos/bandera