Verification Condition Generation Via Theorem Proving (original) (raw)
Related papers
Accurate Theorem Proving for Program Verification
Lecture Notes in Computer Science, 2006
Symbolic software verification engines such as Slam and ESC/Java often use automatic theorem provers to implement forms of symbolic simulation. The theorem provers that are used, such as Simplify, usually combine decision procedures for the theories of uninterpreted functions, linear arithmetic, and sometimes bit vectors using techniques proposed by Nelson-Oppen or Shostak. Programming language constructs such as pointers, structures and unions are not directly supported by the provers, and are often encoded imprecisely using axioms and uninterpreted functions.
Cogent: Accurate Theorem Proving for Program Verification
Lecture Notes in Computer Science, 2005
Symbolic software verification engines such as Slam and ESC/Java often use automatic theorem provers to implement forms of symbolic simulation. The theorem provers that are used, such as Simplify, usually combine decision procedures for the theories of uninterpreted functions, linear arithmetic, and sometimes bit vectors using techniques proposed by Nelson-Oppen or Shostak. Programming language constructs such as pointers, structures and unions are not directly supported by the provers, and are often encoded imprecisely using axioms and uninterpreted functions.
Semantics-based generation of verification conditions by program specialization
2016
We present a method for automatically generating verification con-ditions for a class of imperative programs and safety properties. Our method is parametric with respect to the semantics of the impera-tive programming language, as it specializes, by using unfold/fold transformation rules, a Horn clause interpreter that encodes that se-mantics. We define a multi-step operational semantics for a fragment of the C language and compare the verification conditions obtained by using this semantics with those obtained by using a more tradi-tional small-step semantics. The flexibility of the approach is fur-ther demonstrated by showing that it is possible to easily take into account alternative operational semantics definitions for modeling new language features. Finally, we provide an experimental evalu-ation of the method by generating verification conditions using the multi-step and the small-step semantics for a few hundreds of pro-grams taken from various publicly available benchmarks,...
Semantics-based generation of verification conditions via program specialization
Science of Computer Programming, 2017
We present a method for automatically generating verification conditions for a class of imperative programs and safety properties. Our method is parametric with respect to the semantics of the imperative programming language, as it generates the verification conditions by specializing, using unfold/fold transformation rules, a Horn clause interpreter that encodes that semantics. We define a multi-step operational semantics for a fragment of the C language and compare the verification conditions obtained by using this semantics with those obtained by using a more traditional small-step semantics. The flexibility of the approach is further demonstrated by showing that it is possible to easily take into account alternative operational semantics definitions for modeling additional language features. We have proved that the verification condition generation takes a number of transformation steps that is linear with respect to the size of the imperative program to be verified. Also the size of the verification conditions is linear with respect to the size of the imperative program. Besides the theoretical computational complexity analysis, we also provide an experimental evaluation of the method by generating verification conditions using the multi-step and the small-step semantics for a few hundreds of programs taken from various publicly available benchmarks, and by checking the satisfiability of these verification conditions by using state-of-the-art Horn clause solvers. These experiments show that automated verification of programs from a formal definition of the operational semantics is indeed feasible in practice.
Directed Proof Generation for Machine Code
2010
We present the algorithms used in MCVETO (Machine-Code VErification TOol), a tool to check whether a stripped machinecode program satisfies a safety property. The verification problem that MCVETO addresses is challenging because it cannot assume that it has access to (i) certain structures commonly relied on by source-code verification tools, such as control-flow graphs and call-graphs, and (ii) metadata, such as information about variables, types, and aliasing. It cannot even rely on out-of-scope local variables and return addresses being protected from the program's actions. What distinguishes MCVETO from other work on software model checking is that it shows how verification of machine-code can be performed, while avoiding conventional techniques that would be unsound if applied at the machine-code level.
Formal verification of a realistic compiler
This paper reports on the development and formal verification (proof of semantic preservation) of CompCert, a compiler from Clight (a large subset of the C programming 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 critical software and its formal verification: the verification of the compiler guarantees that the safety properties proved on the source code hold for the executable compiled code as well.
Artificial Intelligence, 1999
We discuss a framework for the application of abstract interpretation as an aid during program development, rather than in the more traditional application of program optimization. Program validation and detection of errors is first performed statically by comparing (partial) specifications written in terms of assertions against information obtained from (global) static analysis of the program. The results of this process are expressed in the user assertion language. Assertions (or parts of assertions) which cannot be checked statically are translated into run-time tests. The framework allows the use of assertions to be optional. It also allows using very general properties in assertions, beyond the predefined set understandable by the static analyzer and including properties defined by user programs. We also report briefly on an implementation of the framework. The resulting tool generates and checks assertions for Prolog, CLP(R), and CHIP/CLP(fd) programs, and integrates compile-time and run-time checking in a uniform way. The tool allows using properties such as types, modes, non-failure, determinacy, and computational cost, and can treat modules separately, performing incremental analysis. Contents 1 Introduction 1 2 Overall Framework Architecture and Operation 2.1 Check Assertions 2.2 Run-time checking of assertions 2.3 Compile-time checking of assertions 3 The Assertion Language 3.1 Assertions on Success States 3.2 Assertions Restricted to a Subset of the Calis 3.3 Assertions on Cali States 3.4 Assertions on the Computation of Predicates 4 Defining Properties 4.1 Writing Properties of Execution States: Compatibility Vs. Instantiation Properties 4.2 Writing Properties of Computations 11 5 A Simple Run-time Checking Scheme 11 5.1 Properties 11 5.2 Success Assertions 5.3 Calis Assertions 5.4 Comp Assertions 6 Compile-Time Checking 7 A Sample Debugging Session with the CIAO System 8 A Preliminary Experimental Evaluation 9 Discussion 21 References 23
Refocusing the Verifying Compiler Grand Challenge
2008
The ideal goal of this grand challenge should be a future in which no production software is considered properly engineered unless it has been fully specified and fully verified as satisfying its specifications. The verifying compiler then becomes the essential central artifact necessary to achieve this outcome, and its characteristics are determined by the overall goal. From this perspective, the nature of programming languages that a verifying compiler could process becomes an immediate issue, and we present several critical features that such a programming language must possess. Specifically, it must include specifications as an integral constituent, and it must have clean semantics, which preclude unexpected side-effecting, aliasing, etc. It must include mechanisms for writing reusable components that are amenable to verification, and consequently, it must include an open-ended mechanism for adding arbitrarily sophisticated mathematical theories in order to specify large software components concisely. Because the current programming languages lack these essential characteristics, the verifying compiler grand challenge will not be met unless it redirects its focus to include the development of a suitable programming language within which full verification is possible.
A formally verified compiler back-end
Journal of Automated Reasoning, 2009
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 soundness. 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.
Verification tools in the development of provably correct compilers
1993
The paper presents a practical verification tool that helps in the development of provably correct compilers. The tool is based on the approach of proving termination of PROLOG-like programs using term-rewriting techniques and a technique of testing whether a given PROLOG program can be soundly executed on PROLOG interpreters without the Occur-check test. The tool has been built on top of the theorem prover, RRL (Rewrite Rule Laboratory).