740 research outputs found
Formal Reasoning Using an Iterative Approach with an Integrated Web IDE
This paper summarizes our experience in communicating the elements of
reasoning about correctness, and the central role of formal specifications in
reasoning about modular, component-based software using a language and an
integrated Web IDE designed for the purpose. Our experience in using such an
IDE, supported by a 'push-button' verifying compiler in a classroom setting,
reveals the highly iterative process learners use to arrive at suitably
specified, automatically provable code. We explain how the IDE facilitates
reasoning at each step of this process by providing human readable verification
conditions (VCs) and feedback from an integrated prover that clearly indicates
unprovable VCs to help identify obstacles to completing proofs. The paper
discusses the IDE's usage in verified software development using several
examples drawn from actual classroom lectures and student assignments to
illustrate principles of design-by-contract and the iterative process of
creating and subsequently refining assertions, such as loop invariants in
object-based code.Comment: In Proceedings F-IDE 2015, arXiv:1508.0338
Development of a Translator from LLVM to ACL2
In our current work a library of formally verified software components is to
be created, and assembled, using the Low-Level Virtual Machine (LLVM)
intermediate form, into subsystems whose top-level assurance relies on the
assurance of the individual components. We have thus undertaken a project to
build a translator from LLVM to the applicative subset of Common Lisp accepted
by the ACL2 theorem prover. Our translator produces executable ACL2 formal
models, allowing us to both prove theorems about the translated models as well
as validate those models by testing. The resulting models can be translated and
certified without user intervention, even for code with loops, thanks to the
use of the def::ung macro which allows us to defer the question of termination.
Initial measurements of concrete execution for translated LLVM functions
indicate that performance is nearly 2.4 million LLVM instructions per second on
a typical laptop computer. In this paper we overview the translation process
and illustrate the translator's capabilities by way of a concrete example,
including both a functional correctness theorem as well as a validation test
for that example.Comment: In Proceedings ACL2 2014, arXiv:1406.123
A formally verified compiler back-end
This article describes the development and formal verification (proof of
semantic preservation) of a compiler back-end from Cminor (a simple imperative
intermediate language) to PowerPC assembly code, using the Coq proof assistant
both for programming the compiler and for proving its correctness. Such a
verified compiler is useful in the context of formal methods applied to the
certification of critical software: the verification of the compiler guarantees
that the safety properties proved on the source code hold for the executable
compiled code as well
Proving soundness of combinatorial Vickrey auctions and generating verified executable code
Using mechanised reasoning we prove that combinatorial Vickrey auctions are
soundly specified in that they associate a unique outcome (allocation and
transfers) to any valid input (bids). Having done so, we auto-generate verified
executable code from the formally defined auction. This removes a source of
error in implementing the auction design. We intend to use formal methods to
verify new auction designs. Here, our contribution is to introduce and
demonstrate the use of formal methods for auction verification in the familiar
setting of a well-known auction
The End of History? Using a Proof Assistant to Replace Language Design with Library Design
Functionality of software systems has exploded in part because of advances in programming-language support for packaging reusable functionality as libraries. Developers benefit from the uniformity that comes of exposing many interfaces in the same language, as opposed to stringing together hodgepodges of command-line tools. Domain-specific languages may be viewed as an evolution of the power of reusable interfaces, when those interfaces become so flexible as to deserve to be called programming languages. However, common approaches to domain-specific languages give up many of the hard-won advantages of library-building in a rich common language, and even the traditional approach poses significant challenges in learning new APIs. We suggest that instead of continuing to develop new domain-specific languages, our community should embrace library-based ecosystems within very expressive languages that mix programming and theorem proving. Our prototype framework Fiat, a library for the Coq proof assistant, turns languages into easily comprehensible libraries via the key idea of modularizing functionality and performance away from each other, the former via macros that desugar into higher-order logic and the latter via optimization scripts that derive efficient code from logical programs
Verus: Verifying Rust Programs using Linear Ghost Types (extended version)
The Rust programming language provides a powerful type system that checks
linearity and borrowing, allowing code to safely manipulate memory without
garbage collection and making Rust ideal for developing low-level,
high-assurance systems. For such systems, formal verification can be useful to
prove functional correctness properties beyond type safety. This paper presents
Verus, an SMT-based tool for formally verifying Rust programs. With Verus,
programmers express proofs and specifications using the Rust language, allowing
proofs to take advantage of Rust's linear types and borrow checking. We show
how this allows proofs to manipulate linearly typed permissions that let Rust
code safely manipulate memory, pointers, and concurrent resources. Verus
organizes proofs and specifications using a novel mode system that
distinguishes specifications, which are not checked for linearity and
borrowing, from executable code and proofs, which are checked for linearity and
borrowing. We formalize Verus' linearity, borrowing, and modes in a small
lambda calculus, for which we prove type safety and termination of
specifications and proofs. We demonstrate Verus on a series of examples,
including pointer-manipulating code (an xor-based doubly linked list), code
with interior mutability, and concurrent code
- …