344 research outputs found
Specifying Reusable Components
Reusable software components need expressive specifications. This paper
outlines a rigorous foundation to model-based contracts, a method to equip
classes with strong contracts that support accurate design, implementation, and
formal verification of reusable components. Model-based contracts
conservatively extend the classic Design by Contract with a notion of model,
which underpins the precise definitions of such concepts as abstract
equivalence and specification completeness. Experiments applying model-based
contracts to libraries of data structures suggest that the method enables
accurate specification of practical software
Observation and abstract behaviour in specification and implementation of state-based systems
Classical algebraic specification is an accepted framework for specification. A criticism which applies is the
fact that it is functional, not based on a notion of state as most software development and implementation languages
are. We formalise the idea of a state-based object or abstract machine using algebraic means. In contrast to similar approaches we consider dynamic logic instead of equational logic as the framework for specification and implementation. The advantage is a more expressive language allowing us to specify safety and liveness conditions. It also allows a clearer distinction of functional and state-based parts which require different treatment in order to achieve behavioural abstraction when necessary. We shall in particular focus on abstract behaviour and observation. A behavioural notion of satisfaction for state-elements is needed in order to abstract from irrelevant details of the state realisation
Structured specifications for better verification of heap-manipulating programs
Abstract. Conventional specifications typically have a flat structure that is based primarily on the underlying logic. Such specifications lack structures that could have provided better guidance to the verification process. In this work, we propose to add three new structures to a specification framework for separation logic to achieve a more precise and better guided verification for pointer-based programs. The newly introduced structures empower users with more control over the verification process in the following ways: (i) case analysis can be invoked to take advantage of disjointness conditions in the logic. (ii) early, as opposed to late, instantiation can minimise on the use of existential quantification. (iii) formulae that are staged provide better reuse of the verification process. Initial experiments have shown that structured specifications can lead to more precise verification without incurring any performance overhead.
Compositional Verification of Heap-Manipulating Programs through Property-Guided Learning
Analyzing and verifying heap-manipulating programs automatically is
challenging. A key for fighting the complexity is to develop compositional
methods. For instance, many existing verifiers for heap-manipulating programs
require user-provided specification for each function in the program in order
to decompose the verification problem. The requirement, however, often hinders
the users from applying such tools. To overcome the issue, we propose to
automatically learn heap-related program invariants in a property-guided way
for each function call. The invariants are learned based on the memory graphs
observed during test execution and improved through memory graph mutation. We
implemented a prototype of our approach and integrated it with two existing
program verifiers. The experimental results show that our approach enhances
existing verifiers effectively in automatically verifying complex
heap-manipulating programs with multiple function calls
Permission-Based Separation Logic for Multithreaded Java Programs
This paper presents a program logic for reasoning about multithreaded
Java-like programs with dynamic thread creation, thread joining and reentrant
object monitors. The logic is based on concurrent separation logic. It is the
first detailed adaptation of concurrent separation logic to a multithreaded
Java-like language. The program logic associates a unique static access
permission with each heap location, ensuring exclusive write accesses and
ruling out data races. Concurrent reads are supported through fractional
permissions. Permissions can be transferred between threads upon thread
starting, thread joining, initial monitor entrancies and final monitor exits.
In order to distinguish between initial monitor entrancies and monitor
reentrancies, auxiliary variables keep track of multisets of currently held
monitors. Data abstraction and behavioral subtyping are facilitated through
abstract predicates, which are also used to represent monitor invariants,
preconditions for thread starting and postconditions for thread joining.
Value-parametrized types allow to conveniently capture common strong global
invariants, like static object ownership relations. The program logic is
presented for a model language with Java-like classes and interfaces, the
soundness of the program logic is proven, and a number of illustrative examples
are presented
Staged Specifications for Automated Verification of Higher-Order Imperative Programs
Higher-order functions and imperative references are language features
supported by many mainstream languages. Their combination enables the ability
to package references to code blocks with the captured state from their
environment. Higher-order imperative programs are expressive and useful, but
complicate formal specification and reasoning due to the use of
yet-to-be-instantiated function parameters, especially when their invocations
may mutate memory captured by or reachable from their arguments.
Existing state-of-the-art works for verifying higher-order imperative
behaviors are restricted in two ways: achieving strong theoretical results
without automated implementations, or achieving automation with the help of
strong assumptions from dedicated type systems (e.g. Rust). To enable an
automated verification solution for imperative languages without the above
restrictions, we introduce Higher-order Staged Separation Logic (HSSL), an
extension of Hoare logic for call-by-value higher-order functions with ML-like
local references.
In this paper, we design a novel staged specification logic, prove its
soundness, develop a new automated higher-order verifier, Heifer, for a core
OCaml-like language, report on experimental results, and present various case
studies investigating its capabilities
A unified approach for static and runtime verification : framework and applications
Static verification of software is becoming ever more effective
and efficient. Still, static techniques either have high precision, in which
case powerful judgements are hard to achieve automatically, or they use
abstractions supporting increased automation, but possibly losing important aspects of the concrete system in the process. Runtime verification has complementary strengths and weaknesses. It combines full
precision of the model (including the real deployment environment) with
full automation, but cannot judge future and alternative runs. Another
drawback of runtime verification can be the computational overhead of
monitoring the running system which, although typically not very high,
can still be prohibitive in certain settings. In this paper we propose a
framework to combine static analysis techniques and runtime verification with the aim of getting the best of both techniques. In particular,
we discuss an instantiation of our framework for the deductive theorem
prover KeY, and the runtime verification tool Larva. Apart from combining static and dynamic verification, this approach also combines the
data centric analysis of KeY with the control centric analysis of Larva.
An advantage of the approach is that, through the use of a single specification which can be used by both analysis techniques, expensive parts
of the analysis could be moved to the static phase, allowing the runtime
monitor to make significant assumptions, dropping parts of expensive
checks at runtime. We also discuss specific applications of our approach.peer-reviewe
Verification of Pointer-Based Programs with Partial Information
The proliferation of software across all aspects of people's life means that software failure can bring catastrophic result. It is therefore highly desirable to be able to develop software that is verified to meet its expected specification. This has also been identified as a key objective in one of the UK Grand Challenges (GC6) (Jones et al., 2006; Woodcock, 2006). However, many difficult problems still remain in achieving this objective, partially due to the wide use of (recursive) shared mutable data structures which are hard to keep track of statically in a precise and concise way.
This thesis aims at building a verification system for both memory safety and functional correctness of programs manipulating pointer-based data structures, which can deal with two scenarios where only partial information about the program is available. For instance the verifier may be supplied with only partial program specification, or with full specification but only part of the program code. For the first scenario, previous state-of-the-art works (Nguyen et al., 2007; Chin et al., 2007; Nguyen and Chin, 2008; Chin et al, 2010) generally require users to provide full specifications for each method of the program to be verified. Their approach seeks much intellectual effort from users, and meanwhile users are liable to make mistakes in writing such specifications. This thesis proposes a new approach to program verification that allows users to provide only partial specification to methods. Our approach will then refine the given annotation into a more complete specification by discovering missing constraints. The discovered constraints may involve both numerical and multiset properties that could be later confirmed or revised by users. Meanwhile, we further augment our approach by requiring only partial specification to be given for primary methods of a program. Specifications for loops and auxiliary methods can then be systematically discovered by our augmented mechanism, with the help of information propagated from the primary methods. This work is aimed at verifying beyond shape properties, with the eventual goal of analysing both memory safety and functional properties for pointer-based data structures. Initial experiments have confirmed that we can automatically refine partial specifications with non-trivial constraints, thus making it easier for users to handle specifications with richer properties.
For the second scenario, many programs contain invocations to unknown components and hence only part of the program code is available to the verifier. As previous works generally require the whole of program code be present, we target at the verification of memory safety and functional correctness of programs manipulating pointer-based data structures, where the program code is only partially available due to invocations to unknown components. Provided with a Hoare-style specification ({Pre} prog {Post}) where program (prog) contains calls to some unknown procedure (unknown), we infer a specification (mspecu) for the unknown part (unknown) from the calling contexts, such that the problem of verifying program (prog) can be safely reduced to the problem of proving that the unknown procedure (unknown) (once its code is available) meets the derived specification (mspecu). The expected specification (mspecu) is automatically calculated using an abduction-based shape analysis specifically designed for a combined abstract domain. We have implemented a system to validate the viability of our approach, with encouraging experimental results
Resource Usage Protocols for Iterators
We discuss usage protocols for iterator objects that prevent concurrent modifications of the underlying collection while iterators are in progress. We formalize these protocols in Java-like object interfaces, enriched with separation logic contracts. We present examples of iterator clients and proofs that they adhere to the iterator protocol, as well as examples of iterator implementations and proofs that they implement the iterator interface
- …