Gradually Verifying Unfolding Expressions & Pure Functions
Programming Languages
Summary
The authors explain how certain features called unfolding expressions and pure functions help program verifiers check code that involves ownership of resources. They define the exact meaning of these features for tools that verify programs by simulating their behavior (symbolic execution) and extend this to work with a gradual verifier that allows partial checking. They also prove that using these features is sound, meaning they don’t introduce errors. Their work mainly supports the Gradual C0 verifier but also applies to other static verifiers like Gobra and Nagini.
Authors
Hazel Torek, Long Tien Nguyen, Priyam Gupta, Jenna DiVincenzo, Jonathan Aldrich
Abstract
Unfolding expressions, which temporarily unfold a predicate to leverage its owned fields when evaluating a heap-dependent expression, and pure functions, which are heap-dependent functions that can be used in specifications, are used in deductive program verifiers based on implicit dynamic frames, such as Gradual C0, Gobra, Nagini, and SnaKt, to increase the modularity of specifications involving ownership. In this paper, we present the formal semantics for unfolding expressions and pure functions for a static verifier using symbolic execution, extend it for a gradual verifier, and provide a proof of soundness. To support Gradual C0, our proof is in the setting of gradual verification, a deductive program verification system that combines static and dynamic verification to allow partial specifications. However, because the gradual verifier is a conservative extension of a static verifier, our results also apply to static verifiers that use symbolic execution, such as the Silicon symbolic execution backend for the Viper verification infrastructure used by Gobra, Nagini, and SnaKt.