Title: Bogor
1Bogor
An Extensible and Highly Modular Software
Model-Checking Framework
SAnToS Laboratory, Kansas State University, USA
http//bogor.projects.cis.ksu.edu
Matthew Dwyer
Radu Iosif
John Hatcliff
William Deng
Robby
Edwin Rodriguez
Support
US Army Research Office (ARO) US National Science
Foundation (NSF) US Department of Defense
Advanced Research Projects Agency (DARPA)
Rockwell-Collins ATC Boeing Lockheed Martin IBM
2Research Context
SAnToS Laboratory, Kansas State
University http//www.cis.ksu.edu/santos
- Working on a variety of techniques
- static analysis, model-checking, run-time
monitoring - code level, architectural design level
- Aiming for robust tools
- built on solid semantic foundations
- open source, close to commercial quality
- Interacting intensively with domain experts
- research teams at Boeing (St. Louis),
Rockwell-Collins, and Lockheed-Martin - real-time middleware developers (Vanderbilt, Wash
U (ACE-TAO), UC Irvine (Zen) - Integration into development process
- ease of use and scalability sometimes take
precedence over theoretical elegance - most of the time, focus is on bug-finding rather
than true verification
3Broad Overview
- being rebuilt from the ground up
- testing on significant code bases
4Bogor
5Bogor Software Model Checking Framework
6Bogor Direct support for OO software
Extensive support for checking concurrent OO
software
Software targeted algorithms
Direct support for
- unbounded dynamic creation of threads and objects
- automatic memory management (garbage collection)
- virtual methods,
- , exceptions, etc.
- supports virtually all of Java
- thread heap symmetry
- compact state representation
- partial order reduction techniques driven by
- object escape analysis
- locking information
7Bogor Eclipse-based Tool Components
8Bogor Domain Specific Model-Checking
Modeling language and Algorithms easily
customized to different domains
9Variety of Application Domains
10Leveraging Domain Knowledge
- Holzmann developed a customized model extraction
from C to Spin - Translation using pattern matching of particular
domain idioms - In essence, an abstract machine for a particular
domain - Very effective at finding subtle defects
Lucent Path Star Telephone Switch
11Variety of System Descriptions
Different levels of abstraction!
12The Goal
13The Goal
Device Drivers
Source code
Model-checking Engine
14The Goal
Automotive
Design Notations
Model-checking Engine
15Domain-Specific Model-Checking
Real-time Scheduling
Quasi-cyclic Search
Partial State Representation
16Outline of Talk
III. A complex Bogor extension
II. Checking strong specs for OO programs
- avionics mission-control domain
- model-checking engine for Cadena environment for
CORBA Component Model development - extension abstracts real-time CORBA event-channel
layer
- moving beyond assertions temporal logic
- SpEx checking JML specifications
- Adding support for concurrency to JML
17Modeling Language Extensions
- Bogor allows definitions of new abstract types
and abstract operations as first-class constructs
extension Set for SetModule typedef
typeltagt expdef Set.typeltagt createltagt(a
...) expdef a chooseltagt(Set.typeltagt)
actiondef addltagt(Set.typeltagt, a) expdef
boolean forAll(a -gt boolean, Set.typeltagt)
18Modeling Language Extensions
- Bogor allows definitions of new abstract types
and abstract operations as first-class constructs
extension Set for SetModule typedef
typeltagt expdef Set.typeltagt createltagt(a
...) expdef a chooseltagt(Set.typeltagt)
actiondef addltagt(Set.typeltagt, a) expdef
boolean forAll(a -gt boolean, Set.typeltagt)
Variable arity function for creating symmetric
sets
19Modeling Language Extensions
- Bogor allows definitions of new abstract types
and abstract operations as first-class constructs
extension Set for SetModule typedef
typeltagt expdef Set.typeltagt createltagt(a
...) expdef a chooseltagt(Set.typeltagt)
actiondef addltagt(Set.typeltagt, a) expdef
boolean forAll(a -gt boolean, Set.typeltagt)
Non-deterministically pick an element of the set
to return
20Modeling Language Extensions
- Bogor allows definitions of new abstract types
and abstract operations as first-class constructs
extension Set for SetModule typedef
typeltagt expdef Set.typeltagt createltagt(a
...) expdef a chooseltagt(Set.typeltagt)
actiondef addltagt(Set.typeltagt, a) expdef
boolean forAll(a -gt boolean, Set.typeltagt)
Higher-order function implements quantification
over set elements
21Extension Implementation
- Extensions are implemented by associating each
item in extension interface with Java methods
that provide the semantics for the item (or
state-vector storage representation in case of
state).
Extension Implementation
extension Set for SetModule typedef
typeltagt expdef Set.typeltagt createltagt(a
...) expdef a chooseltagt(Set.typeltagt)
actiondef addltagt(Set.typeltagt, a) expdef
boolean forAll(a -gt boolean, Set.typeltagt)
22Extension Implementation
Implementing the set value for the set type
- public class MySet implements INonPrimitiveExtValu
e - protected HashSet set new HashSet()
- protected boolean isNonPrimitiveElement
- public void add(IValue v) set.add(v)
- public byte linearize(..., int bitsPerNPV,
- ObjectIntTable npvIdMap)
- Object elements set.toArray()
- BitBuffer bb new BitBuffer()
- if (isNonPrimitiveElement)
- int elementIds new intelements.length
- for (int i 0 i lt elements.length i)
- elementIdsi npvIdMap.get(elementsi)
- Arrays.sort(elementIds)
- for (int i 0 i lt elements.length i)
- bb.append(elementIdsi, bitsPerNPV)
- else ...
- return new byte bb.toByteArray()
23Extension Implementation
Implementing the set value for the set type
- public class MySet implements INonPrimitiveExtValu
e - protected HashSet set new HashSet()
- protected boolean isNonPrimitiveElement
- public void add(IValue v) set.add(v)
- public byte linearize(..., int bitsPerNPV,
- ObjectIntTable npvIdMap)
- Object elements set.toArray()
- BitBuffer bb new BitBuffer()
- if (isNonPrimitiveElement)
- int elementIds new intelements.length
- for (int i 0 i lt elements.length i)
- elementIdsi npvIdMap.get(elementsi)
- Arrays.sort(elementIds)
- for (int i 0 i lt elements.length i)
- bb.append(elementIdsi, bitsPerNPV)
- else ...
- return new byte bb.toByteArray()
Implement Bogor interface for non-primitive value
24Extension Implementation
Implementing the set value for the set type
- public class MySet implements INonPrimitiveExtValu
e - protected HashSet set new HashSet()
- protected boolean isNonPrimitiveElement
- public void add(IValue v) set.add(v)
- public byte linearize(..., int bitsPerNPV,
- ObjectIntTable npvIdMap)
- Object elements set.toArray()
- BitBuffer bb new BitBuffer()
- if (isNonPrimitiveElement)
- int elementIds new intelements.length
- for (int i 0 i lt elements.length i)
- elementIdsi npvIdMap.get(elementsi)
- Arrays.sort(elementIds)
- for (int i 0 i lt elements.length i)
- bb.append(elementIdsi, bitsPerNPV)
- else ...
- return new byte bb.toByteArray()
25Extension Implementation
Implementing the set value for the set type
- public class MySet implements INonPrimitiveExtValu
e - protected HashSet set new HashSet()
- protected boolean isNonPrimitiveElement
- public void add(IValue v) set.add(v)
- public byte linearize(..., int bitsPerNPV,
- ObjectIntTable npvIdMap)
- Object elements set.toArray()
- BitBuffer bb new BitBuffer()
- if (isNonPrimitiveElement)
- int elementIds new intelements.length
- for (int i 0 i lt elements.length i)
- elementIdsi npvIdMap.get(elementsi)
- Arrays.sort(elementIds)
- for (int i 0 i lt elements.length i)
- bb.append(elementIdsi, bitsPerNPV)
- else ...
- return new byte bb.toByteArray()
26Extension Implementation
Implementing the set value for the set type
- public class MySet implements INonPrimitiveExtValu
e - protected HashSet set new HashSet()
- protected boolean isNonPrimitiveElement
- public void add(IValue v) set.add(v)
- public byte linearize(..., int bitsPerNPV,
- ObjectIntTable npvIdMap)
- Object elements set.toArray()
- BitBuffer bb new BitBuffer()
- if (isNonPrimitiveElement)
- int elementIds new intelements.length
- for (int i 0 i lt elements.length i)
- elementIdsi npvIdMap.get(elementsi)
- Arrays.sort(elementIds)
- for (int i 0 i lt elements.length i)
- bb.append(elementIdsi, bitsPerNPV)
- else ...
- return new byte bb.toByteArray()
See Bogor web site for extensive tutorial
(PowerPoint slides) and the paper Bogor An
extensible and highly modular software
model-checking framework
27Outline of Talk
III. A complex Bogor extension
II. Checking strong specs for OO programs
- avionics mission-control domain
- model-checking engine for Cadena environment for
CORBA Component Model development - extension abstracts real-time CORBA event-channel
layer
- moving beyond assertions temporal logic
- SpEx checking JML specifications
- Adding support for concurrency to JML
28Assertions for Software Verification
- Use of assertions has become common practice
among developers - 10 years ago assertions were not considered
useful by developers - evidence of the effectiveness of assertions
- David Rosenblum (1995)
- now some programming languages have included
assertions in their standard specifications - c.f. Java 1.4 assertions
29Concurrent Queue based on Linked List (Doug Leas
util.concurrent package)
public class LinkedNode public Object value
public LinkedNode next public
LinkedNode(Object x) value x
public class LinkedQueue protected final
Object putLock protected LinkedNode head
protected LinkedNode last head protected int
waitingForTake 0 public LinkedQueue()
putLock new Object() head new
LinkedNode(null) public boolean isEmpty()
synchronized (head) return
head.next null public void
put(Object x) if (x null) throw
new IllegalArgumentException() insert(x)
protected synchronized Object extract()
synchronized (head) Object x null
LinkedNode first head.next if (first !
null) x first.value first.value
null head first return x
protected void insert(Object x)
synchronized (putLock) LinkedNode p new
LinkedNode(x) synchronized (last)
last.next p last p if
(waitingForTake gt 0) putLock.notify()
return public Object take() Object x
extract() if (x ! null) return x else
protected void insert(Object x)
synchronized (putLock) LinkedNode p new
LinkedNode(x) synchronized (last)
last.next p last p if
(waitingForTake gt 0) putLock.notify()
return
assert(x ! null)
allows concurrent access to put() and take()
30An example
public class LinkedNode public Object value
public LinkedNode next public
LinkedNode(Object x) value x
public class LinkedQueue protected final
Object putLock protected LinkedNode head
protected LinkedNode last head protected int
waitingForTake 0 public LinkedQueue()
putLock new Object() head new
LinkedNode(null) public boolean isEmpty()
synchronized (head) return
head.next null public void
put(Object x) if (x null) throw
new IllegalArgumentException() insert(x)
protected synchronized Object extract()
synchronized (head) Object x null
LinkedNode first head.next if (first !
null) x first.value first.value
null head first return x
protected void insert(Object x)
synchronized (putLock) LinkedNode p new
LinkedNode(x) synchronized (last)
last.next p last p if
(waitingForTake gt 0) putLock.notify()
return public Object take() Object x
extract() if (x ! null) return x else
public class LinkedQueue protected final
Object putLock protected LinkedNode head
protected LinkedNode last head protected int
waitingForTake 0 . . .
Specify that putLock is never null
31An example
protected synchronized Object extract()
assert(putLock ! null) synchronized (head)
Object x null LinkedNode first
head.next if (first ! null) x
first.value first.value null head
first return x assert(putLock
! null) protected void insert(Object x)
assert(putLock ! null) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) last.next p
last p if (waitingForTake gt 0)
putLock.notify() return
assert(putLock ! null) public Object take()
assert(putLock ! null) Object x
extract() if (x ! null) return x else
assert(putLock ! null)
public class LinkedNode public Object value
public LinkedNode next public
LinkedNode(Object x) value x
public class LinkedQueue protected final
Object putLock protected LinkedNode head
protected LinkedNode last head protected int
waitingForTake 0 public LinkedQueue()
assert(putLock ! null) putLock new
Object() head new LinkedNode(null)
assert(putLock ! null) public boolean
isEmpty() assert(putLock ! null)
synchronized (head) return head.next
null assert(putLock ! null)
public void put(Object x) assert(putLock !
null) if (x null) throw new
IllegalArgumentException() insert(x)
assert(putLock ! null)
Need more declarative formalisms
Specify that putLock is never null
32Specification Languages
- We want specification languages that
- have a rich set of primitives for observing
program state - heap-allocated objects, concurrency, etc.
- make it easy to write useful specifications
- support lightweight and deep-semantic
specifications - be checkable using a variety of analysis
techniques - static analysis, theorem proving, etc.
33Java Modeling Language (JML)
- Developed by G. Leavens and other colleagues at
Iowa State University - very rich set of operators, especially for
describing complex heap properties - \reach(r), \forall(), \old(), etc.
- support for specifications with varying degrees
of complexity - lightweight vs. heavyweight specifications
- has been checked with a variety of different
techniques - so far, static analysis, theorem proving and
runtime checking - Emerging as a standard specification language for
Java within the research community
34Java Modeling Language (JML)
public class LinkedNode public Object value
public LinkedNode next public
LinkedNode(Object x) value x
public class LinkedQueue protected final
Object putLock protected LinkedNode head
protected LinkedNode last head protected int
waitingForTake 0 public LinkedQueue()
putLock new Object() head new
LinkedNode(null) public boolean isEmpty()
synchronized (head) return
head.next null public void
put(Object x) if (x null) throw
new IllegalArgumentException() insert(x)
protected synchronized Object extract()
synchronized (head) Object x null
LinkedNode first head.next if (first !
null) x first.value first.value
null head first return x
protected void insert(Object x)
synchronized (putLock) LinkedNode p new
LinkedNode(x) synchronized (last)
last.next p last p if
(waitingForTake gt 0) putLock.notify()
return public Object take() Object x
extract() if (x ! null) return x else
35An example
protected synchronized Object extract()
assert(putLock ! null) synchronized (head)
Object x null LinkedNode first
head.next if (first ! null) x
first.value first.value null head
first return x assert(putLock
! null) protected void insert(Object x)
assert(putLock ! null) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) last.next p
last p if (waitingForTake gt 0)
putLock.notify() return
assert(putLock ! null) public Object take()
assert(putLock ! null) Object x
extract() if (x ! null) return x else
assert(putLock ! null)
public class LinkedNode public Object value
public LinkedNode next public
LinkedNode(Object x) value x
public class LinkedQueue protected final
Object putLock protected LinkedNode head
protected LinkedNode last head protected int
waitingForTake 0 public LinkedQueue()
assert(putLock ! null) putLock new
Object() head new LinkedNode(null)
assert(putLock ! null) public boolean
isEmpty() assert(putLock ! null)
synchronized (head) return head.next
null assert(putLock ! null)
public void put(Object x) assert(putLock !
null) if (x null) throw new
IllegalArgumentException() insert(x)
assert(putLock ! null)
36Java Modeling Language (JML)
/_at_ behavior _at_ requires x ! null _at_
ensures true _at_ also behavior _at_ requires
x null _at_ signals (Exception e) e
instanceof IllegalArgumentException _at_/
public void put(Object x) if (x null)
throw new IllegalArgumentException()
insert(x) protected synchronized Object
extract() synchronized (head)
return refactoredExtract() /_at_
behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
Object refactoredExtract() Object x
null LinkedNode first head.next if
(first ! null) x first.value
first.value null head first
return x /_at_ behavior _at_ requires x
! null _at_ ensures last.value x
\fresh(last) _at_/ protected void
insert(Object x) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) refactoredInsert(p) if
(waitingForTake gt 0) putLock.notify()
return
public class LinkedNode public Object value
public LinkedNode next /_at_ behavior _at_
ensures value x _at_/ public
LinkedNode(Object x) value x
public class LinkedQueue protected final
/_at_ non_null _at_/ Object putLock protected /_at_
non_null _at_/ LinkedNode head protected /_at_
non_null _at_/ LinkedNode last head protected
int waitingForTake 0 //_at_ instance invariant
waitingForTake gt 0 //_at_ instance invariant
\reach(head).has(last) /_at_ behavior _at_
assignable head, last, putLock, waitingForTake
_at_ ensures \fresh(head, putLock) head.next
null _at_/ public LinkedQueue()
putLock new Object() head new
LinkedNode(null) /_at_ behavior _at_
ensures \result ltgt head.next null _at_/
public boolean isEmpty() synchronized
(head) return head.next null
/_at_ behavior _at_ requires n ! null
_at_ assignable last, last.next _at_/
protected void refactoredInsert(LinkedNode n)
last.next n last n
/_at_ behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
synchronized Object extract()
synchronized(head) Object x null
LinkedNode first head.next if (first !
null) x first.value
first.value null head first
return x
ability to make deep-semantic specifications
37Java Modeling Language (JML)
/_at_ behavior _at_ requires x ! null _at_
ensures true _at_ also behavior _at_ requires
x null _at_ signals (Exception e) e
instanceof IllegalArgumentException _at_/
public void put(Object x) if (x null)
throw new IllegalArgumentException()
insert(x) protected synchronized Object
extract() synchronized (head)
return refactoredExtract() /_at_
behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
Object refactoredExtract() Object x
null LinkedNode first head.next if
(first ! null) x first.value
first.value null head first
return x /_at_ behavior _at_ requires x
! null _at_ ensures last.value x
\fresh(last) _at_/ protected void
insert(Object x) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) refactoredInsert(p) if
(waitingForTake gt 0) putLock.notify()
return
public class LinkedNode public Object value
public LinkedNode next /_at_ behavior _at_
ensures value x _at_/ public
LinkedNode(Object x) value x
public class LinkedQueue protected final
/_at_ non_null _at_/ Object putLock protected /_at_
non_null _at_/ LinkedNode head protected /_at_
non_null _at_/ LinkedNode last head protected
int waitingForTake 0 //_at_ instance invariant
waitingForTake gt 0 //_at_ instance invariant
\reach(head).has(last) /_at_ behavior _at_
assignable head, last, putLock, waitingForTake
_at_ ensures \fresh(head, putLock) head.next
null _at_/ public LinkedQueue()
putLock new Object() head new
LinkedNode(null) /_at_ behavior _at_
ensures \result ltgt head.next null _at_/
public boolean isEmpty() synchronized
(head) return head.next null
/_at_ behavior _at_ requires n ! null
_at_ assignable last, last.next _at_/
protected void refactoredInsert(LinkedNode n)
last.next n last n
Frame conditions can only assign to these
variables.
/_at_ behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
synchronized Object extract()
synchronized(head) Object x null
LinkedNode first head.next if (first !
null) x first.value
first.value null head first
return x
ability to make deep-semantic specifications
38Java Modeling Language (JML)
/_at_ behavior _at_ requires x ! null _at_
ensures true _at_ also behavior _at_ requires
x null _at_ signals (Exception e) e
instanceof IllegalArgumentException _at_/
public void put(Object x) if (x null)
throw new IllegalArgumentException()
insert(x) protected synchronized Object
extract() synchronized (head)
return refactoredExtract() /_at_
behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
Object refactoredExtract() Object x
null LinkedNode first head.next if
(first ! null) x first.value
first.value null head first
return x /_at_ behavior _at_ requires x
! null _at_ ensures last.value x
\fresh(last) _at_/ protected void
insert(Object x) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) refactoredInsert(p) if
(waitingForTake gt 0) putLock.notify()
return
public class LinkedNode public Object value
public LinkedNode next /_at_ behavior _at_
ensures value x _at_/ public
LinkedNode(Object x) value x
public class LinkedQueue protected final
/_at_ non_null _at_/ Object putLock protected /_at_
non_null _at_/ LinkedNode head protected /_at_
non_null _at_/ LinkedNode last head protected
int waitingForTake 0 //_at_ instance invariant
waitingForTake gt 0 //_at_ instance invariant
\reach(head).has(last) /_at_ behavior _at_
assignable head, last, putLock, waitingForTake
_at_ ensures \fresh(head, putLock) head.next
null _at_/ public LinkedQueue()
putLock new Object() head new
LinkedNode(null) /_at_ behavior _at_
ensures \result ltgt head.next null _at_/
public boolean isEmpty() synchronized
(head) return head.next null
/_at_ behavior _at_ requires n ! null
_at_ assignable last, last.next _at_/
protected void refactoredInsert(LinkedNode n)
last.next n last n
Post condition the result of the method is
null, or
/_at_ behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
synchronized Object extract()
synchronized(head) Object x null
LinkedNode first head.next if (first !
null) x first.value
first.value null head first
return x
ability to make deep-semantic specifications
39Java Modeling Language (JML)
/_at_ behavior _at_ requires x ! null _at_
ensures true _at_ also behavior _at_ requires
x null _at_ signals (Exception e) e
instanceof IllegalArgumentException _at_/
public void put(Object x) if (x null)
throw new IllegalArgumentException()
insert(x) protected synchronized Object
extract() synchronized (head)
return refactoredExtract() /_at_
behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
Object refactoredExtract() Object x
null LinkedNode first head.next if
(first ! null) x first.value
first.value null head first
return x /_at_ behavior _at_ requires x
! null _at_ ensures last.value x
\fresh(last) _at_/ protected void
insert(Object x) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) refactoredInsert(p) if
(waitingForTake gt 0) putLock.notify()
return
public class LinkedNode public Object value
public LinkedNode next /_at_ behavior _at_
ensures value x _at_/ public
LinkedNode(Object x) value x
public class LinkedQueue protected final
/_at_ non_null _at_/ Object putLock protected /_at_
non_null _at_/ LinkedNode head protected /_at_
non_null _at_/ LinkedNode last head protected
int waitingForTake 0 //_at_ instance invariant
waitingForTake gt 0 //_at_ instance invariant
\reach(head).has(last) /_at_ behavior _at_
assignable head, last, putLock, waitingForTake
_at_ ensures \fresh(head, putLock) head.next
null _at_/ public LinkedQueue()
putLock new Object() head new
LinkedNode(null) /_at_ behavior _at_
ensures \result ltgt head.next null _at_/
public boolean isEmpty() synchronized
(head) return head.next null
/_at_ behavior _at_ requires n ! null
_at_ assignable last, last.next _at_/
protected void refactoredInsert(LinkedNode n)
last.next n last n
there exists an instance n of the class
LinkedNode (existential quantification of heap
data)
/_at_ behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
synchronized Object extract()
synchronized(head) Object x null
LinkedNode first head.next if (first !
null) x first.value
first.value null head first
return x
ability to make deep-semantic specifications
40Java Modeling Language (JML)
/_at_ behavior _at_ requires x ! null _at_
ensures true _at_ also behavior _at_ requires
x null _at_ signals (Exception e) e
instanceof IllegalArgumentException _at_/
public void put(Object x) if (x null)
throw new IllegalArgumentException()
insert(x) protected synchronized Object
extract() synchronized (head)
return refactoredExtract() /_at_
behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
Object refactoredExtract() Object x
null LinkedNode first head.next if
(first ! null) x first.value
first.value null head first
return x /_at_ behavior _at_ requires x
! null _at_ ensures last.value x
\fresh(last) _at_/ protected void
insert(Object x) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) refactoredInsert(p) if
(waitingForTake gt 0) putLock.notify()
return
public class LinkedNode public Object value
public LinkedNode next /_at_ behavior _at_
ensures value x _at_/ public
LinkedNode(Object x) value x
public class LinkedQueue protected final
/_at_ non_null _at_/ Object putLock protected /_at_
non_null _at_/ LinkedNode head protected /_at_
non_null _at_/ LinkedNode last head protected
int waitingForTake 0 //_at_ instance invariant
waitingForTake gt 0 //_at_ instance invariant
\reach(head).has(last) /_at_ behavior _at_
assignable head, last, putLock, waitingForTake
_at_ ensures \fresh(head, putLock) head.next
null _at_/ public LinkedQueue()
putLock new Object() head new
LinkedNode(null) /_at_ behavior _at_
ensures \result ltgt head.next null _at_/
public boolean isEmpty() synchronized
(head) return head.next null
/_at_ behavior _at_ requires n ! null
_at_ assignable last, last.next _at_/
protected void refactoredInsert(LinkedNode n)
last.next n last n
look at the pre-state the state of the
execution when the method was entered
/_at_ behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
synchronized Object extract()
synchronized(head) Object x null
LinkedNode first head.next if (first !
null) x first.value
first.value null head first
return x
ability to make deep-semantic specifications
41Java Modeling Language (JML)
/_at_ behavior _at_ requires x ! null _at_
ensures true _at_ also behavior _at_ requires
x null _at_ signals (Exception e) e
instanceof IllegalArgumentException _at_/
public void put(Object x) if (x null)
throw new IllegalArgumentException()
insert(x) protected synchronized Object
extract() synchronized (head)
return refactoredExtract() /_at_
behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
Object refactoredExtract() Object x
null LinkedNode first head.next if
(first ! null) x first.value
first.value null head first
return x /_at_ behavior _at_ requires x
! null _at_ ensures last.value x
\fresh(last) _at_/ protected void
insert(Object x) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) refactoredInsert(p) if
(waitingForTake gt 0) putLock.notify()
return
public class LinkedNode public Object value
public LinkedNode next /_at_ behavior _at_
ensures value x _at_/ public
LinkedNode(Object x) value x
public class LinkedQueue protected final
/_at_ non_null _at_/ Object putLock protected /_at_
non_null _at_/ LinkedNode head protected /_at_
non_null _at_/ LinkedNode last head protected
int waitingForTake 0 //_at_ instance invariant
waitingForTake gt 0 //_at_ instance invariant
\reach(head).has(last) /_at_ behavior _at_
assignable head, last, putLock, waitingForTake
_at_ ensures \fresh(head, putLock) head.next
null _at_/ public LinkedQueue()
putLock new Object() head new
LinkedNode(null) /_at_ behavior _at_
ensures \result ltgt head.next null _at_/
public boolean isEmpty() synchronized
(head) return head.next null
/_at_ behavior _at_ requires n ! null
_at_ assignable last, last.next _at_/
protected void refactoredInsert(LinkedNode n)
last.next n last n
in the pre-state, form the set of objects that
are reachable via object references from head
field
/_at_ behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
synchronized Object extract()
synchronized(head) Object x null
LinkedNode first head.next if (first !
null) x first.value
first.value null head first
return x
ability to make deep-semantic specifications
42Java Modeling Language (JML)
/_at_ behavior _at_ requires x ! null _at_
ensures true _at_ also behavior _at_ requires
x null _at_ signals (Exception e) e
instanceof IllegalArgumentException _at_/
public void put(Object x) if (x null)
throw new IllegalArgumentException()
insert(x) protected synchronized Object
extract() synchronized (head)
return refactoredExtract() /_at_
behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
Object refactoredExtract() Object x
null LinkedNode first head.next if
(first ! null) x first.value
first.value null head first
return x /_at_ behavior _at_ requires x
! null _at_ ensures last.value x
\fresh(last) _at_/ protected void
insert(Object x) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) refactoredInsert(p) if
(waitingForTake gt 0) putLock.notify()
return
public class LinkedNode public Object value
public LinkedNode next /_at_ behavior _at_
ensures value x _at_/ public
LinkedNode(Object x) value x
public class LinkedQueue protected final
/_at_ non_null _at_/ Object putLock protected /_at_
non_null _at_/ LinkedNode head protected /_at_
non_null _at_/ LinkedNode last head protected
int waitingForTake 0 //_at_ instance invariant
waitingForTake gt 0 //_at_ instance invariant
\reach(head).has(last) /_at_ behavior _at_
assignable head, last, putLock, waitingForTake
_at_ ensures \fresh(head, putLock) head.next
null _at_/ public LinkedQueue()
putLock new Object() head new
LinkedNode(null) /_at_ behavior _at_
ensures \result ltgt head.next null _at_/
public boolean isEmpty() synchronized
(head) return head.next null
/_at_ behavior _at_ requires n ! null
_at_ assignable last, last.next _at_/
protected void refactoredInsert(LinkedNode n)
last.next n last n
the set of objects reachable from head in the
pre-state has n in it (i.e., n is a member of the
set)
/_at_ behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
synchronized Object extract()
synchronized(head) Object x null
LinkedNode first head.next if (first !
null) x first.value
first.value null head first
return x
ability to make deep-semantic specifications
43Java Modeling Language (JML)
/_at_ behavior _at_ requires x ! null _at_
ensures true _at_ also behavior _at_ requires
x null _at_ signals (Exception e) e
instanceof IllegalArgumentException _at_/
public void put(Object x) if (x null)
throw new IllegalArgumentException()
insert(x) protected synchronized Object
extract() synchronized (head)
return refactoredExtract() /_at_
behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
Object refactoredExtract() Object x
null LinkedNode first head.next if
(first ! null) x first.value
first.value null head first
return x /_at_ behavior _at_ requires x
! null _at_ ensures last.value x
\fresh(last) _at_/ protected void
insert(Object x) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) refactoredInsert(p) if
(waitingForTake gt 0) putLock.notify()
return
public class LinkedNode public Object value
public LinkedNode next /_at_ behavior _at_
ensures value x _at_/ public
LinkedNode(Object x) value x
public class LinkedQueue protected final
/_at_ non_null _at_/ Object putLock protected /_at_
non_null _at_/ LinkedNode head protected /_at_
non_null _at_/ LinkedNode last head protected
int waitingForTake 0 //_at_ instance invariant
waitingForTake gt 0 //_at_ instance invariant
\reach(head).has(last) /_at_ behavior _at_
assignable head, last, putLock, waitingForTake
_at_ ensures \fresh(head, putLock) head.next
null _at_/ public LinkedQueue()
putLock new Object() head new
LinkedNode(null) /_at_ behavior _at_
ensures \result ltgt head.next null _at_/
public boolean isEmpty() synchronized
(head) return head.next null
/_at_ behavior _at_ requires n ! null
_at_ assignable last, last.next _at_/
protected void refactoredInsert(LinkedNode n)
last.next n last n
the value in the n node matches the method result
/_at_ behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
synchronized Object extract()
synchronized(head) Object x null
LinkedNode first head.next if (first !
null) x first.value
first.value null head first
return x
ability to make deep-semantic specifications
44Java Modeling Language (JML)
/_at_ behavior _at_ requires x ! null _at_
ensures true _at_ also behavior _at_ requires
x null _at_ signals (Exception e) e
instanceof IllegalArgumentException _at_/
public void put(Object x) if (x null)
throw new IllegalArgumentException()
insert(x) protected synchronized Object
extract() synchronized (head)
return refactoredExtract() /_at_
behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
Object refactoredExtract() Object x
null LinkedNode first head.next if
(first ! null) x first.value
first.value null head first
return x /_at_ behavior _at_ requires x
! null _at_ ensures last.value x
\fresh(last) _at_/ protected void
insert(Object x) synchronized (putLock)
LinkedNode p new LinkedNode(x)
synchronized (last) refactoredInsert(p) if
(waitingForTake gt 0) putLock.notify()
return
public class LinkedNode public Object value
public LinkedNode next /_at_ behavior _at_
ensures value x _at_/ public
LinkedNode(Object x) value x
public class LinkedQueue protected final
/_at_ non_null _at_/ Object putLock protected /_at_
non_null _at_/ LinkedNode head protected /_at_
non_null _at_/ LinkedNode last head protected
int waitingForTake 0 //_at_ instance invariant
waitingForTake gt 0 //_at_ instance invariant
\reach(head).has(last) /_at_ behavior _at_
assignable head, last, putLock, waitingForTake
_at_ ensures \fresh(head, putLock) head.next
null _at_/ public LinkedQueue()
putLock new Object() head new
LinkedNode(null) /_at_ behavior _at_
ensures \result ltgt head.next null _at_/
public boolean isEmpty() synchronized
(head) return head.next null
/_at_ behavior _at_ requires n ! null
_at_ assignable last, last.next _at_/
protected void refactoredInsert(LinkedNode n)
last.next n last n
the set of objects reachable from head in the
final state does not have n in it.
/_at_ behavior _at_ assignable head,
head.next.value _at_ ensures \result null
(\exists LinkedNode n _at_
\old(\reach(head)).has(n) _at_
n.value \result
_at_
!(\reach(head).has(n))) _at_/ protected
synchronized Object extract()
synchronized(head) Object x null
LinkedNode first head.next if (first !
null) x first.value
first.value null head first
return x
ability to make deep-semantic specifications
45Bogor
Questions
- Specs like this havent been checked with
model-checking before - What makes Bogor well-suited for checking JML?
- Can we check JML efficiently?
46Bogors Heap Representation
Key Points
State
explicit heap representation
after each transition, a topological sort gives
heap objects a canonical order
transition may create new objects, garbage, etc.
garbage is eliminated
precise heap model
precise alias information
have access to all visited states (but,
efficiently stored using collapse compression)
47Bogors Heap Representation Enables JML Specs
Check
Key Points
State
many JML features are easy to support in Bogor
precise heap model (c.f., \reach)
transition may create new objects, garbage, etc.
precise alias information (c.f., assignable)
can easily compare objects in methods
pre/post-states (c.f., \old)
48Assessment
- The ability to state strong properties of
heap-allocated data (as JML enables) is very
useful - complementary to techniques developed by UPenn
team (JIST) which focus on synthesizing ordering
constraints on calls to Java interfaces - Bogors native support for OO features,
explicit-state representation and extension
facility enable JML property checking to be
implemented fairly easily - Bogors sophisticated partial-order reduction
strategies (rely on dynamic escape and
lock-pattern analysis) enable checking to be
carried out efficiently for software units.
49JML Reasoning Tools and Technologies
SPeX/Bogor (!)
JMLc/Testing
Theorem Proving
m()
m() assume pre-conditions
prove post-conditions
checking that specifications are satisfied for
particular traces generated by the environment
(test harness)
manipulate formulas
50Experiments without reductions
w/ JML
w/o JML
Checking JML specs adds 20-40 overhead
Test Platform JDK 1.4.1 (32-bit mode) on a 2 GHz
Opteron with maximum heap of 1 GB running Linux
(64-bit mode)
51Bogors Reduction Algorithms Enables Checking
JML Specs
w/ POR
w/o POR
w/ JML
w/o JML
w/ JML
w/o JML
52Bogor Eclipse-based Tool Components
53JMLEclipse
JML well-formedness checking
JML syntax highlighting
Working with a number of groups in JML community
to integrate static analysis and theorem-proving
based tools into a single framework.
54Outline of Talk
III. A complex Bogor extension
II. Checking strong specs for OO programs
- avionics mission-control domain
- model-checking engine for Cadena environment for
CORBA Component Model development - extension abstracts real-time CORBA event-channel
layer
- moving beyond assertions temporal logic
- SpEx checking JML specifications
- Adding support for concurrency to JML