15 research outputs found

    Abstract conflict driven learning

    Full text link

    Lower Bounds for Possibly Divergent Probabilistic Programs

    Get PDF
    We present a new proof rule for verifying lower bounds on quantities of probabilistic programs. Our proof rule is not confined to almost-surely terminating programs -- as is the case for existing rules -- and can be used to establish non-trivial lower bounds on, e.g., termination probabilities and expected values, for possibly divergent probabilistic loops, e.g., the well-known three-dimensional random walk on a lattice

    Quantitative Strongest Post: A Calculus for Reasoning about the Flow of Quantitative Information

    Get PDF
    We present a novel strongest-postcondition-style calculus for quantitative reasoning about non-deterministic programs with loops. Whereas existing quantitative weakest pre allows reasoning about the value of a quantity after a program terminates on a given initial state, quantitative strongest post allows reasoning about the value that a quantity had before the program was executed and reached a given final state. We show how strongest post enables reasoning about the flow of quantitative information through programs. Similarly to weakest liberal preconditions, we also develop a quantitative strongest liberal post. As a byproduct, we obtain the entirely unexplored notion of strongest liberal postconditions and show how these foreshadow a potential new program logic - partial incorrectness logic - which would be a more liberal version of O'Hearn's recent incorrectness logic

    Field-sensitive unreachability and non-cyclicity analysis

    Get PDF
    Field-sensitive static analyses of object-oriented code use approximations of the computational states where fields are taken into account, for better precision. This article presents a novel and sound definite analysis of Java bytecode that approximates two strictly related properties: field-sensitive unreachability between program variables and field-sensitive non-cyclicity of program variables. The latter exploits the former for better precision. We build a data-flow analysis based on constraint graphs, whose nodes are program points and whose arcs propagate information according to the semantics of each bytecode instruction. We follow abstract interpretation both to approximate the concrete semantics and to prove our results formally correct. Our analysis has been designed with the goal of improving client analyses such as termination analysis, asserting the non-cyclicity of variables with respect to specific fields

    Causality-based verification

    Get PDF
    Program verification is one of the central research topics in computer science since its inception – we can consider the field to be initiated as early as in 1949, with Alan Turing’s pioneering paper “Checking a Large Routine.” Yet, we are still far from the dream of automatically proving every computer program correct. Two aspects make this problem particularly challenging: concurrent program execution on parallel processors, and large, or even infinite, state spaces of data-manipulating programs. Nowadays, with concurrency entering everywhere, from smartphones to aircrafts, proving the correctness of infinite-state concurrent programs becomes increasingly more important: we do want to be sure that the program that controls the airplane we are flying in is correct. In this thesis we propose a new approach to the verification of infinitestate concurrent programs. We call it causality-based, because it captures in an automatic proof system the “cause-effect” reasoning principles, which are often used informally in manual correctness proofs. While traditionally automatic methods are based on the state space exploration, our method is based on a new concurrency model, called concurrent traces, which are the abstractions of the history of a concurrent program to some key events and the relationships between them. Causality-based proof rules relate concurrent traces with each other, by formally tracking what are the necessary consequences (the “effects”) from a particular analysis situation (the “cause”). The full correctness proof is then a composition of such primitive proof steps. We study the syntactic and language-based properties of concurrent traces, and characterize the complexity of such operations as emptiness checking and language inclusion. Regarding the program correctness, we develop proof systems for the broad classes of safety and liveness properties, and provide algorithms for the automatic construction of correctness proofs. We demonstrate that for practically relevant classes of programs, such as multi-threaded programs with binary semaphores, the constructed proofs are of polynomial size, and can be also checked in polynomial time. The methods of the thesis have been implemented in Arctor, the first scalable termination prover for concurrent programs, which is able to handle programs with hundreds of non-trivial threads.Die Programmverifikation ist seit den Anfängen der Informatik eines ihrer zentralen Forschungsfelder. Als Beginn dieser Forschungsrichtung kann bereits das Jahr 1949 betrachtet werden, in dem Alan Turings bahnbrechende Arbeit “Checking a Large Routine” erschien. Der Traum, die Korrektheit von Programmen stets automatisch beweisen zu können, ist aber auch heute noch weit davon entfernt, Realität zu sein. Es gibt zwei Aspekte, die dieses Problem zu einer solch großen Herausforderung machen: die nebenläufige Ausführung von Programmen auf Parallelrechnern, und die großen, oder sogar unendlichen, Zustandsräume von datenverarbeitenden Programmen. Nebenläufige Programme werden in immer mehr Anwendungsbereichen, von Handys bis zur Luftfahrt, eingesetzt. Automatische Korrektheitsbeweise werden daher immer wichtiger: wenn wir mit dem Flugzeug reisen, möchten wir sicher sein, dass das Programm, das das Flugzeug steuert, auch tatsachlich korrekt ist. In dieser Arbeit schlagen wir einen neuen Ansatz für die Verifikation von nebenläufigen Programmen mit unendlichem Zustandsraum vor. Wir nennen den Ansatz “kausalitätsbasiert”, weil er im Rahmen eines automatischen Beweissystems die “Ursache-Wirkung”-Beziehungen erfasst, die sonst eher informell in manuellen Korrektheitsbeweisen benutzt werden. Anders als traditionelle automatische Methoden, die den Zustandsraums explorieren, baut unser Ansatz auf einem neuen nebenläufigen Berechnungsmodell, dem der “nebenläufigen Spuren”, auf. Eine nebenläufige Spur ist eine Abstraktion der Vergangenheit eines nebenläufigen Programms im Hinblick auf bestimmte Schlüsselereignisse und die Beziehungen zwischen diesen Ereignissen. Kausalitätsbasierte Beweis-regeln setzen nebenläufige Spuren zueinander in Bezug, indem die Konsequenzen (die “Wirkungen”) einer bestimmten analytischen Situation (der “Ursache”) auf eine formale Art und Weise verfolgt werden. Der vollständige Korrektheitsbeweis setzt sich dann aus solchen einfachen Beweisschritten zusammen. Wir untersuchen die syntaktischen und sprachtheoretischen Eigenschaften von nebenläufigen Spuren, und charakterisieren die Komplexität von Operationen wie den Tests auf leere Sprache und Sprachinklusion. Wir entwickeln Beweissysteme zum Nachweis der Programmkorrektheit für die allgemeinen Klassen der Sicherheits- und Lebendigkeitseigenschaften, und stellen Algorithmen vor, die solche Beweise automatisch konstruieren. Für aus praktischer Sicht relevante Klassen von Programmen, wie Multi-Thread Programme mit binären Semaphoren, zeigen wir, dass die konstruierten Beweise polynomiell groß sind und auch in polynomieller Zeit geprüft werden können. Die in der Arbeit vorgestellten Methoden wurden im Verifikationswerkzeug Arctor implementiert. Arctor is der erste skalierbare Terminierungsbeweiser für nebenläufige Programme. Arctor kann Programme mit Hunderten nicht-trivialer Threads verarbeiten

    Abstraction, Up-To Techniques and Games for Systems of Fixpoint Equations

    Get PDF
    Systems of fixpoint equations over complete lattices, consisting of (mixed) least and greatest fixpoint equations, allow one to express many verification tasks such as model-checking of various kinds of specification logics or the check of coinductive behavioural equivalences. In this paper we develop a theory of approximation for systems of fixpoint equations in the style of abstract interpretation: a system over some concrete domain is abstracted to a system in a suitable abstract domain, with conditions ensuring that the abstract solution represents a sound/complete overapproximation of the concrete solution. Interestingly, up-to techniques, a classical approach used in coinductive settings to obtain easier or feasible proofs, can be interpreted as abstractions in a way that they naturally fit into our framework and extend to systems of equations. Additionally, relying on the approximation theory, we can characterise the solution of systems of fixpoint equations over complete lattices in terms of a suitable parity game, generalising some recent work that was restricted to continuous lattices. The game view opens the way for the development of local algorithms for characterising the solution of such equation systems and we explore some special cases

    Abstract Execution: Automatically Proving Infinitely Many Programs

    Get PDF
    Abstract programs contain schematic placeholders representing potentially infinitely many concrete programs. They naturally occur in multiple areas of computer science concerned with correctness: rule-based compilation and optimization, code refactoring and other source-to-source transformations, program synthesis, Correctness-by-Construction, and more. Mechanized correctness arguments about abstract programs are frequently conducted in interactive environments. While this permits expressing arbitrary properties quantifying over programs, substantial effort has to be invested to prove them manually by writing proof scripts. Existing approaches to proving abstract program properties automatically, on the other hand, lack expressiveness. Frequently, they only support placeholders representing all possible instantiations; in some cases, minor refinements are supported. This thesis bridges that gap by presenting Abstract Execution (AE), an automatic reasoning technique for universal behavioral properties of abstract programs. The restriction to universal (no existential quantification) and behavioral (not addressing internal structure) properties excludes certain applications; however, it is the key to automation. Our logic for Abstract Execution uses abstract state changes to represent unknown effects on local variables and the heap, and models abrupt completion by symbolic branching. In this logic, schematic placeholders have names: It is possible to re-use them at several places, representing the same program elements in potentially different contexts. Furthermore, the represented concrete programs can be constrained by an expressive specification language, which is a unique feature of AE. We use the theory of dynamic frames to scale between full abstraction and total precision of frame specifications, and support fine-grained pre- and postconditions for (abrupt) completion. We implemented AE by extending the program verifier KeY. Specifically for relational verification of abstract Java programs, we developed REFINITY, a graphical KeY frontend. We used REFINITY it in our signature application of AE: to model well-known statement-level refactoring techniques and prove their conditional safety. Several yet undocumented behavioral preconditions for safe refactorings originated in this case study, which is one of very few attempts to statically prove behavioral correctness of statement-level refactorings, and the only one to cover them to that extent. AE extends Symbolic Execution (SE) for abstract programs. As a foundational contribution, we propose a general framework for SE based on the semantics of symbolic states. It natively integrates state merging by supporting m-to-n transitions. We define two orthogonal correctness notions, exhaustiveness and precision, and formally prove their relation to program proving and bug detection. Finally, we introduce Modal Trace Logic (MTL), a trace-based logic to represent a variety of different program verification tasks, especially for relational verification. It is a “plug-in” logic which can be integrated on-demand with formal languages that have a trace semantics. The core of MTL is the trace modality, which allows expressing that a specification approximates an implementation after a trace abstraction step. We demonstrate the versatility of this approach by formalizing concrete verification tasks in MTL, ranging from functional verification over program synthesis to program evolution. To reason about MTL problems, we translate them to symbolic traces. We suggest Symbolic Trace Logic (STL), which comes with a sequent calculus to prove symbolic trace inclusions. This requires checking symbolic states for subsumption; to that end, we provide two generally useful notions of symbolic state subsumption. This framework relates as follows to the other parts of this thesis: We use the language of abstract programs to express synthesis and compilation, which connects MTL to AE. Moreover, symbolic states of STL are based on our framework for SE
    corecore