Many interesting program properties involve the execution of multiple programs, including observational equivalence, noninterference, co-termination, monotonicity, and idempotency. One strategy for verifying such relational properties is to construct and reason about an intermediate program whose correctness implies that the individual programs exhibit those properties. A key challenge in building an intermediate program is finding a good alignment of the original programs. An alignment puts subparts of the original programs into correspondence so that their similarities can be exploited in order to simplify verification. We propose an approach to intermediate program construction that uses e-graphs, equality saturation, and algebraic realignment rules to efficiently represent and build programs amenable to automated verification. A key ingredient of our solution is a novel data-driven extraction technique that uses execution traces of candidate intermediate programs to identify solutions that are semantically well-aligned. We have implemented a relational verification engine based on our proposed approach, called KestRel, and use it to evaluate our approach over a suite of benchmarks taken from the relational verification literature.
Hoare-style program logics are a popular and effective technique for software verification. Relational program logics are an instance of this approach that enables reasoning about relationships between the execution of two or more programs. Existing relational program logics have focused on verifying that all runs of a collection of programs do not violate a specified relational behavior. Several important relational properties, including refinement and noninterference, do not fit into this category, as they also mandate the existence of specific desirable executions. This paper presents RHLE, a logic for verifying these sorts of relational $$\forall \exists $$ properties. Key to our approach is a novel form of function specification that employs a variant of ghost variables to ensure that valid implementations exhibit certain behaviors. We have used a program verifier based on RHLE to verify a diverse set of relational $$\forall \exists $$ properties drawn from the literature.
Programmers often leverage data structure libraries that provide useful and reusable abstractions. Modular verification of programs that make use of these libraries naturally rely on specifications that capture important properties about how the library expects these data structures to be accessed and manipulated. However, these specifications are often missing or incomplete, making it hard for clients to be confident they are using the library safely. When library source code is also unavailable, as is often the case, the challenge to infer meaningful specifications is further exacerbated. In this paper, we present a novel data-driven abductive inference mechanism that infers specifications for library methods sufficient to enable verification of the library's clients. Our technique combines a data-driven learning-based framework to postulate candidate specifications, along with SMT-provided counterexamples to refine these candidates, taking special care to prevent generating specifications that overfit to sampled tests. The resulting specifications form a minimal set of requirements on the behavior of library implementations that ensures safety of a particular client program. Our solution thus provides a new multi-abduction procedure for precise specification inference of data structure libraries guided by client-side verification tasks. Experimental results on a wide range of realistic OCaml data structure programs demonstrate the effectiveness of the approach.
Specifications of program behavior typically consider single executions of a program, usually requiring that every execution never reaches a bad state (a safety property) or that every execution can eventually produce some good state (a liveness property). Many desirable behaviors, however, including refinement and non-interference, range over multiple executions of a program. These sorts of behaviors are instead expressible as a combination of k-safety and k-liveness hyperproperties. Relational program logics allow for reasoning about the validity of hyperproperties, but, just as Floyd-Hoare logics focus on axiomatic reasoning about safety, existing relational logics have focused on proving k-safety properties. Such relational logics are unfortunately not suitable for verifying more general combinations of k-safety and k-liveness hyperproperties. This paper presents RHLE, a relational program logic for reasoning about a class of such hyperproperties that we term $\forall\exists$-hyperproperties. RHLE forms the basis for an algorithm capable of automatically verifying this class of hyperproperties. We present an implementation of this algorithm which we have used to automatically verify a number of $\forall\exists$-hyperproperties, including refinement and non-interference properties, on a corpus of representative programs.
Reasoning about nondeterministic programs requires a specification of how their nondeterministic choices are allowed to be resolved. When reasoning about safety properties, it is sound to overapproximate the permitted behaviors. Once its safety is established, a program remains safe for every valid implementation of its nondeterministic choices. Overapproximate specifications are less useful when establishing that a nondeterministic program exhibits some desirable behavior, however, as resolving nondeterminism to specific choices is not guaranteed to preserve the execution that resulted in the desirable final state. This paper proposes a flexible way to underapproximate the behaviors of nondeterministic choices so that clients can soundly reason about the existence of desirable behaviors, while at the same time permitting some freedom in how those choices are implemented. We present a pair of program logics, called HLE and RHLE, that use these specifications to reason about existential program behaviors in the single program and relational settings, respectively. We have implemented a verifier based on these program logics that is capable of automatically verifying a wide range of relational properties, including refinement and noninterference. We have evaluated our approach by using this tool to verify a diverse set of programs and properties drawn from the literature.