Fig 11 - uploaded by Patrick Cousot
Content may be subject to copyright.
A screenshot of the error reporting with the precondition inference.  

A screenshot of the error reporting with the precondition inference.  

Source publication
Conference Paper
Full-text available
We consider the problem of automatic precondition inference. We argue that the common notion of sufficient precondition inference (i.e., under which precondition is the program correct?) imposes too large a burden on callers, and hence it is unfit for automatic program analysis. Therefore, we define the problem of necessary precondition inference (...

Citations

... This implies that is an overapproximation of the set of states that end up in , and corresponds to the notion of necessary preconditions studied by Cousot et al. [2013]. In particular, if an initial state ̸ |= , then is guaranteed to not terminate in ( could also diverge). ...
... Following the terminology from above, which is inspired from the naming necessary preconditions of Cousot et al. [2013], we can state that • total correctness triples provide sufficient preconditions; ...
... The latter connection is justified by the fundamental Galois connection between slp and wp, and the strong duality between total and partial correctness, but where we replace nontermination with unreachability. Finally, we notice that there are three additional Hoare-style triples that can be naturally defined using our transformers, and we identify a precise connection between partial incorrectness and the so-called necessary preconditions [Cousot et al. 2013]. ...
Preprint
Full-text available
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.
... Given its interest, considerable effort has recently been invested in achieving automatic support for equipping programs with extensive contracts, yet the current contract inference tools are still often unsatisfactory in practice [13]. ...
... Let us briefly discuss those strands of research that have influenced our work the most. A detailed description of the related literature can be found [1,13,20,32,45]. Our axiomatic representation is inspired by [44], which relies on a model checker for (bounded) symbolic execution of .NET programs and generates either Spec# specifications or parameterized unit tests. ...
... ). However, this is achieved at the expense of some additional precision loss [13]. We achieve generality thanks to the K Framework. ...
Article
Full-text available
In this article, we propose a symbolic technique that can be used for automatically inferring software contracts from programs that are written in a non-trivial fragment of C, called KERNELC, that supports pointer-based structures and heap manipulation. Starting from the semantic definition of KERNELC in the 𝕂 semantic framework, we enrich the symbolic execution facilities recently provided by 𝕂 with novel capabilities for contract synthesis that are based on abstract subsumption. Roughly speaking, we define an abstract symbolic technique that axiomatically explains the execution of any (modifier) C function by using other (observer) routines in the same program. We implemented our technique in the automated tool KINDSPEC 2.1, which generates logical axioms that express pre- and post-condition assertions which define the precise input/output behavior of the C routines. Thanks to the integrated support for symbolic execution and deductive verification provided by 𝕂, some synthesized axioms that cannot be guaranteed to be correct by construction due to abstraction can finally be verified in our setting with little effort.
... Our analysis does not aim to address this question. More generally, the result of our analysis can be used for a wide range of applications: from code specifications [14], to grammar-based testing [29], to automatically checking and guiding the cleaning of the data [1,38]. ...
... Finally, the main difference compared to the inference of necessary preconditions proposed by Cousot et al. [14] or the (bi-)abduction [6] used in tools like Infer [5] is that our analysis can also deal with inputs read at any point during the program (thus notably also inside loops whose execution may depend on other inputs -this is where the need for the stack comes from, cf. Section 4). ...
Preprint
Nowadays, as machine-learned software quickly permeates our society, we are becoming increasingly vulnerable to programming errors in the data pre-processing or training software, as well as errors in the data itself. In this paper, we propose a static shape analysis framework for input data of data-processing programs. Our analysis automatically infers necessary conditions on the structure and values of the data read by a data-processing program. Our framework builds on a family of underlying abstract domains, extended to indirectly reason about the input data rather than simply reasoning about the program variables. The choice of these abstract domain is a parameter of the analysis. We describe various instances built from existing abstract domains. The proposed approach is implemented in an open-source static analyzer for Python programs. We demonstrate its potential on a number of representative examples.
... In this section, we assume a pre-image over-approximating backwards analysis of the program, e.g. [5], i.e., we assume a function pre |prg| : ℘(Y ) → ℘(X) such that pre |prg| (A) ⊆ pre |prg| (A). We want to use pre |prg| to provide upper and lower probability bounds for all output events. ...
Preprint
Full-text available
We consider reusing established non-probabilistic output analyses (either forward or backwards) that yield over-approximations of a program's pre-image or image relation, e.g., interval analyses. We assume a probability measure over the program input and present two techniques (one for forward and one for backward analyses) that both derive upper and lower probability bounds for the output events. We demonstrate the most involved technique, namely the forward technique, for two examples and compare their results to a cutting-edge probabilistic output analysis.
... In this section, we assume a pre-image over-approximating backwards analysis of the program, e.g. [5], i.e., we assume a function pre |prg| : ℘(Y ) → ℘(X) such that pre |prg| (A) ⊆ pre |prg| (A). We want to use pre |prg| to provide upper and lower probability bounds for all output events. ...
Article
Full-text available
We consider reusing established non-probabilistic output analyses (either forward or backwards) that yield over-approximations of a program's pre-image or image relation, e.g., interval analyses. We assume a probability measure over the program input and present two techniques (one for forward and one for backward analyses) that both derive upper and lower probability bounds for the output events. We demonstrate the most involved technique, namely the forward technique, for two examples and compare their results to a cutting-edge probabilistic output analysis.
... The concept of necessary preconditon [Cousot et al. 2013] is related. A necessary precondition for a program is a predicate which, whenever falsified, leads to divergence or an error, but never to successful termination. ...
... Curiously, flipping the subset relation gives two inequivalent notions, p ⊇ wlp(C)q and post (C)p ⊇ q. Replacing wlp with the weakest possible preconditon wpp(C)q leads to a relationship p ⊇ wpp(C)q which is as in Thresher and in necessary preconditions, the difference being that in Thresher q describes error states where Cousot et al. [2013] use q to describe success states. I am grateful to Benno Stein for discussions on Thresher, necessary preconditions, and wpp. ...
Article
Full-text available
Program correctness and incorrectness are two sides of the same coin. As a programmer, even if you would like to have correctness, you might find yourself spending most of your time reasoning about incorrectness. This includes informal reasoning that people do while looking at or thinking about their code, as well as that supported by automated testing and static analysis tools. This paper describes a simple logic for program incorrectness which is, in a sense, the other side of the coin to Hoare's logic of correctness.
... We leverage the notion of "abstract testing" [19] to denote the process of abstract execution (i.e., forward analysis) of a program with an given abstract input (which represents a set of concrete inputs) and the checking of whether the abstract output satisfies the target property. The key idea of our approach is to perform abstract testing iteratively in a top-down manner, by refining the abstract input via partitioning, wherein the refinement process also makes use of the computed necessary precondition of violating the target assertion via the "inverse" abstract execution (i.e., backward analysis [21]). When the property has been checked to hold for all abstract sub-inputs in the partition, the iterative process stops and gives a proof. ...
... With the abstract semantics, sound program invariants can be computed automatically in finite steps by forward abstract interpretation [18] (denoted as Forward AI) and backward abstract interpretation [21] (denoted as Backward AI) respectively. The computation with abstract interpretation is parameterized by abstract domains specifying the considered approximated properties. ...
Chapter
Full-text available
When applying abstract interpretation to verification, it may suffer from the problem of getting too conservative over-approximations to verify a given target property, and being hardly able to generate counter-examples when the property does not hold. In this paper, we propose iterative abstract testing, to create a property-oriented verification approach based on abstract interpretation. Abstract testing employs forward abstract executions (i.e., forward analysis) together with property checking to mimic (regular) testing, and utilizes backward abstract executions (i.e., backward analysis) to derive necessary preconditions that may falsify the target property, and be useful for reducing the input space that needs further exploration. To verify a property, we conduct abstract testing in an iterative manner by utilizing dynamic partitioning to split the input space into sub-spaces such that each sub-space involves fewer program behaviors and may be easier to verify. Moreover, we leverage bounded exhaustive testing to verify bounded small sub-spaces, as a means to complement abstract testing based verification. The experimental results show that our approach has comparable strength with several state-of-the-art verification tools.
... A second set of techniques uses static analysis on the code of the API method to infer specifications; e.g. Cousot et al. uses abstract interpretation [10] to infer preconditions, and Buse et al. uses symbolic execution [8] A third set of techniques uses dynamic approaches to mining specifications [3], [11], [12], [18], [22], [33], [35], [43], [49], [53]. Some of these works infer temporal patterns over API method calls [22], [33], [35], [53], object-usage specifications [43], and others strengthen existing specifications [49]. ...
... Input: R, a residual graph of the form V, E Root, the root of the graph Output: A specification begin 10 return B end that this choice works out well. 1 The weights assigned are the number of preconditions that are ∼ between the two cases; for example, if cases l and r have 3 preconditions that are related by ∼, then the weight assigned to the edge from l to r is 3. In Fig. 2, an edge of weight n is shown as n dashed edges. 1 The ∼ relation used need not be lexical identity; we speculate that more interesting results could be achieved by considering other relations, such as logical equivalence, but that is beyond the scope of this paper. ...
... A second set of techniques uses static analysis on the code of the API method to infer specifications; e.g. Cousot et al. uses abstract interpretation [10] to infer preconditions, and Buse et al. uses symbolic execution [8] to infer conditions leading to exceptions. However, Buse et al. do not infer conditions under which the API method terminates normally and Cousot et al. do not infer postconditions. ...
Preprint
Full-text available
Modern software relies on libraries and uses them via application programming interfaces (APIs). Correct API usage as well as many software engineering tasks are enabled when APIs have formal specifications. In this work, we analyze the implementation of each method in an API to infer a formal postcondition. Conventional wisdom is that, if one has preconditions, then one can use the strongest postcondition predicate transformer (SP) to infer postconditions. However, SP yields postconditions that are exponentially large, which makes them difficult to use, either by humans or by tools. Our key idea is an algorithm that converts such exponentially large specifications into a form that is more concise and thus more usable. This is done by leveraging the structure of the specifications that result from the use of SP. We applied our technique to infer postconditions for over 2,300 methods in seven popular Java libraries. Our technique was able to infer specifications for 75.7% of these methods, each of which was verified using an Extended Static Checker. We also found that 84.6% of resulting specifications were less than 1/4 page (20 lines) in length. Our technique was able to reduce the length of SMT proofs needed for verifying implementations by 76.7% and reduced prover execution time by 26.7%.
... API specifications are used to make sure that developers are using the APIs as intended. On that account, prior works have paid attention to two distinct types of specifications: behavioral specifications [1,4,6] and temporal specifications [2,3,5]. Behavioral specifications are typically represented in the form of Boolean expressions effectively defining the constraints to ensure normal behavior. ...
Conference Paper
The programmers utilize APIs provided by frameworks and libraries to avoid reinventing the wheel and API specifications aid them to fully understand and adequately use these APIs. This paper introduces "contract-based typestate specifications", a new kind ofspecification for documenting programs. Prior work has focused on two kinds of specifications, namely behavioral and temporal specifications. These specifications either target the constraints of API method invocations or, the usage order of API methods to ensure normal behavior. Consequentially, these two types of specifications are treated independently. Another challenge for these state-of-art specifications lies in the form of limited expressiveness to the designers’ intention, as these are unable to demonstrate all the valid choices under same or different constraints. Contract-based typestate specifications capture the essence of behavioral and temporal specifications, yet provide better understanding and ensure valid API usage as required by context, thus providing flexibility of usage.