@article{19936,
  abstract     = {There has been a recent upsurge of interest in formal, machine-checked verification of timing guarantees for C implementations of real-time system schedulers. However, prior work has only considered tick-based schedulers, which enjoy a clearly defined notion of time: the time "quantum". In this work, we present a new approach to real-time systems verification for interrupt-free schedulers, which are commonly used in deeply embedded and resource-constrained systems but which do not enjoy a natural notion of periodic time. Our approach builds on and connects two recently developed Rocq-based systems—RefinedC (for foundational C verification) and Prosa (for verified response-time analysis)—adapting the former to reason about timed traces and the latter to reason about overheads. We apply the resulting system, which we call RefinedProsa, to verify Rössl, a simple yet representative, fixed-priority, non-preemptive, interrupt-free scheduler implemented in C.},
  author       = {Bedarkar, Kimaya and Elbeheiry, Laila and Sammler, Michael Joachim and Gäher, Lennard and Brandenburg, Björn and Dreyer, Derek and Garg, Deepak},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {PLDI},
  pages        = {73--97},
  publisher    = {Association for Computing Machinery},
  title        = {{RefinedProsa: Connecting response-time analysis with C verification for interrupt-free schedulers}},
  doi          = {10.1145/3729249},
  volume       = {9},
  year         = {2025},
}

@article{21052,
  abstract     = {Program logics have proven a successful strategy for verification of complex programs. By providing local reasoning and means of abstraction and composition, they allow reasoning principles for individual components of a program to be combined to prove guarantees about a whole program. Crucially, these components and their proofs can be reused. However, this reuse is only available once the program logic has been defined. It is a frustrating fact of the status quo that whoever defines a new program logic must establish every part, both semantics and proof rules, from scratch. In spite of programming languages and program logics typically sharing many core features, reuse is generally not available across languages. Even inside one language, if the same underlying operation appears in multiple language primitives, reuse is typically not possible when establishing proof rules for the program logic.
To enable reuse across and inside languages when defining complex program logics (and proving them sound), we serve program logics à la carte by combining program logic fragments for the various effects of the language. Among other language features, the menu includes shared state, concurrency, and non-determinism as reusable, composable blocks that can be combined to define a program logic modularly. Our theory builds on ITrees as a framework to express language semantics and Iris as the underlying separation logic; the work has been mechanized in the Coq proof assistant.},
  author       = {Vistrup, Max and Sammler, Michael Joachim and Jung, Ralf},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {POPL},
  pages        = {300--331},
  publisher    = {Association for Computing Machinery},
  title        = {{Program logics à la Carte}},
  doi          = {10.1145/3704847},
  volume       = {9},
  year         = {2025},
}

@article{21053,
  abstract     = {Program verification tools are often implemented as front-end translations of an input program into an intermediate verification language (IVL) such as Boogie, GIL, Viper, or Why3. The resulting IVL program is then verified using an existing back-end verifier. A soundness proof for such a translational verifier needs to relate the input program and verification logic to the semantics of the IVL, which in turn needs to be connected with the verification logic implemented in the back-end verifiers. Performing such proofs is challenging due to the large semantic gap between the input and output programs and logics, especially for complex verification logics such as separation logic.
This paper presents a formal framework for reasoning about translational separation logic verifiers. At its center is a generic core IVL that captures the essence of different separation logics. We define its operational semantics and formally connect it to two different back-end verifiers, which use symbolic execution and verification condition generation, resp. Crucially, this semantics uses angelic non-determinism to enable the application of different proof search algorithms and heuristics in the back-end verifiers. An axiomatic semantics for the core IVL simplifies reasoning about the front-end translation by performing essential proof steps once and for all in the equivalence proof with the operational semantics rather than for each concrete front-end translation.
We illustrate the usefulness of our formal framework by instantiating our core IVL with elements of Viper and connecting it to two Viper back-ends as well as a front-end for concurrent separation logic. All our technical results have been formalized in Isabelle/HOL, including the core IVL and its semantics, the semantics of two back-ends for a subset of Viper, and all proofs.},
  author       = {Dardinier, Thibault and Sammler, Michael Joachim and Parthasarathy, Gaurav and Summers, Alexander J. and Müller, Peter},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {POPL},
  pages        = {569--599},
  publisher    = {Association for Computing Machinery},
  title        = {{Formal foundations for translational separation logic verifiers}},
  doi          = {10.1145/3704856},
  volume       = {9},
  year         = {2025},
}

@article{17495,
  abstract     = {Rust is a modern systems programming language whose ownership-based type system statically guarantees memory safety, making it particularly well-suited to the domain of safety-critical systems. In recent years, a wellspring of automated deductive verification tools have emerged for establishing functional correctness of Rust code. However, none of the previous tools produce foundational proofs (machine-checkable in a general-purpose proof assistant), and all of them are restricted to the safe fragment of Rust. This is a problem because the vast majority of Rust programs make use of unsafe code at critical points, such as in the implementation of widely-used APIs. We propose RefinedRust, a refinement type system—proven sound in the Coq proof assistant—with the goal of establishing foundational semi-automated functional correctness verification of both safe and unsafe Rust code. We have developed a prototype verification tool implementing RefinedRust. Our tool translates Rust code (with user annotations) into a model of Rust embedded in Coq, and then checks its adherence to the RefinedRust type system using separation logic automation in Coq. All proofs generated by RefinedRust are checked by the Coq proof assistant, so the automation and type system do not have to be trusted. We evaluate the effectiveness of RefinedRust by verifying a variant of Rust’s Vec implementation that involves intricate reasoning about unsafe pointer-manipulating code.},
  author       = {Gäher, Lennard and Sammler, Michael Joachim and Jung, Ralf and Krebbers, Robbert and Dreyer, Derek},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {PLDI},
  pages        = {1115--1139},
  publisher    = {Association for Computing Machinery},
  title        = {{RefinedRust: A type system for high-assurance verification of rust programs}},
  doi          = {10.1145/3656422},
  volume       = {8},
  year         = {2024},
}

@article{17497,
  abstract     = {Over the past two decades, there has been a great deal of progress on verification of full functional correctness of programs using separation logic, sometimes even producing “foundational” proofs in proof assistants like Coq. Unfortunately, even though existing approaches to this problem provide significant support for automated verification, they still incur a significant specification overhead: the user must supply the specification against which the program is verified, and the specification may be long, complex, or tedious to formulate. In this paper, we introduce Quiver, the first technique for inferring functional correctness specifications in separation logic while simultaneously verifying foundationally that they are correct. To guide Quiver towards the final specification, we take hints from the user in the form of a specification sketch, and then complete the sketch using inference. To do so, Quiver introduces a new abductive deductive verification technique, which integrates ideas from abductive inference (for specification inference) together with deductive separation logic automation (for foundational verification). The result is that users have to provide some guidance, but significantly less than with traditional deductive verification techniques based on separation logic. We have evaluated Quiver on a range of case studies, including code from popular open-source libraries.},
  author       = {Spies, Simon and Gäher, Lennard and Sammler, Michael Joachim and Dreyer, Derek},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {PLDI},
  pages        = {889--913},
  publisher    = {Association for Computing Machinery},
  title        = {{Quiver: Guided abductive inference of separation logic specifications in coq}},
  doi          = {10.1145/3656413},
  volume       = {8},
  year         = {2024},
}

@article{17498,
  abstract     = {In recent years, there has been tremendous progress on developing program logics for verifying the correctness of programs in a rich and diverse array of languages. Thus far, however, such logics have assumed that programs are written entirely in a single programming language. In practice, this assumption rarely holds since programs are often composed of components written in different programming languages, which interact with one another via some kind of foreign function interface (FFI). In this paper, we take the first steps towards the goal of developing program logics for multi-language verification. Specifically, we present Melocoton, a multi-language program verification system for reasoning about OCaml, C, and their interactions through the OCaml FFI. Melocoton consists of the first formal semantics of (a large subset of) the OCaml FFI—previously only described in prose in the OCaml manual—as well as the first program logic to reason about the interactions of program components written in OCaml and C. Melocoton is fully mechanized in Coq on top of the Iris separation logic framework.},
  author       = {Guéneau, Armaël and Hostert, Johannes and Spies, Simon and Sammler, Michael Joachim and Birkedal, Lars and Dreyer, Derek},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {OOPSLA2},
  pages        = {716--744},
  publisher    = {Association for Computing Machinery},
  title        = {{Melocoton: A program logic for verified interoperability between OCaml and C}},
  doi          = {10.1145/3622823},
  volume       = {7},
  year         = {2023},
}

@article{17499,
  abstract     = {Much work in formal verification of low-level systems is based on one of two approaches: refinement or separation logic. These two approaches have complementary benefits: refinement supports the use of programs as specifications, as well as transitive composition of proofs, whereas separation logic supports conditional specifications, as well as modular ownership reasoning about shared state. A number of verification frameworks employ these techniques in tandem, but in all such cases the benefits of the two techniques remain separate. For example, in frameworks that use relational separation logic to prove contextual refinement, the relational separation logic judgment does not support transitive composition of proofs, while the contextual refinement judgment does not support conditional specifications.  
In this paper, we propose Conditional Contextual Refinement (or CCR, for short), the first verification system to not only combine refinement and separation logic in a single framework but also to truly marry them together into a unified mechanism enjoying all the benefits of refinement and separation logic simultaneously. Specifically, unlike in prior work, CCR’s refinement specifications are both conditional (with separation logic pre- and post-conditions) and transitively composable. We implement CCR in Coq and evaluate its effectiveness on a range of interesting examples.},
  author       = {Song, Youngju and Cho, Minki and Lee, Dongjae and Hur, Chung-Kil and Sammler, Michael Joachim and Dreyer, Derek},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {POPL},
  pages        = {1121--1151},
  publisher    = {Association for Computing Machinery},
  title        = {{Conditional contextual refinement}},
  doi          = {10.1145/3571232},
  volume       = {7},
  year         = {2023},
}

@article{17500,
  abstract     = {Prior work on multi-language program verification has achieved impressive results, including the compositional verification of complex compilers. But the existing approaches to this problem impose a variety of restrictions on the overall structure of multi-language programs (e.g. fixing the source language, fixing the set of involved languages, fixing the memory model, or fixing the semantics of interoperation). In this paper, we explore the problem of how to avoid such global restrictions.
Concretely, we present DimSum: a new, decentralized approach to multi-language semantics and verification, which we have implemented in the Coq proof assistant. Decentralization means that we can define and reason about languages independently from each other (as independent modules communicating via events), but also combine and translate between them when necessary (via a library of combinators).
We apply DimSum to a high-level imperative language Rec (with an abstract memory model and function calls), a low-level assembly language Asm (with a concrete memory model, arbitrary jumps, and syscalls), and a mathematical specification language Spec. We evaluate DimSum on two case studies: an Asm library extending Rec with support for pointer comparison, and a coroutine library for Rec written in Asm. In both cases, we show how DimSum allows the Asm libraries to be abstracted to Rec-level specifications, despite the behavior of the Asm libraries not being syntactically expressible in Rec itself. We also verify an optimizing multi-pass compiler from Rec to Asm, showing that it is compatible with these Asm libraries.},
  author       = {Sammler, Michael Joachim and Spies, Simon and Song, Youngju and D'Osualdo, Emanuele and Krebbers, Robbert and Garg, Deepak and Dreyer, Derek},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {POPL},
  pages        = {775--805},
  publisher    = {Association for Computing Machinery},
  title        = {{DimSum: A decentralized approach to multi-language semantics and verification}},
  doi          = {10.1145/3571220},
  volume       = {7},
  year         = {2023},
}

@article{17501,
  abstract     = {Low-level systems code often needs to interact with data, such as page table entries or network packet headers, in which multiple pieces of information are packaged together as bitfield components of a single machine integer and accessed via bitfield manipulations (e.g., shifts and masking). Most existing approaches to verifying such code employ SMT solvers, instantiated with theories for bit vector reasoning: these provide a powerful hammer, but also significantly increase the trusted computing base of the verification toolchain.
In this work, we propose an alternative approach to the verification of bitfield-manipulating systems code, which we call BFF. Building on the RefinedC framework, BFF is not only highly automated (as SMT-based approaches are) but also foundational---i.e., it produces a machine-checked proof of program correctness against a formal semantics for C programs, fully mechanized in Coq. Unlike SMT-based approaches, we do not try to solve the general problem of arbitrary bit vector reasoning, but rather observe that real systems code typically accesses bitfields using simple, well-understood programming patterns: the layout of a bit vector is known up front, and its bitfields are accessed in predictable ways through a handful of bitwise operations involving bit masks. Correspondingly, we center our approach around the concept of a structured bit vector---i.e., a bit vector with a known bitfield layout---which we use to drive simple and predictable automation. We validate the BFF approach by verifying a range of bitfield-manipulating C functions drawn from real systems code, including page table manipulation code from the Linux kernel and the pKVM hypervisor.},
  author       = {Zhu, Fengmin and Sammler, Michael Joachim and Lepigre, Rodolphe and Dreyer, Derek and Garg, Deepak},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {OOPSLA2},
  pages        = {1613--1638},
  publisher    = {Association for Computing Machinery},
  title        = {{BFF: Foundational and automated verification of bitfield-manipulating programs}},
  doi          = {10.1145/3563345},
  volume       = {6},
  year         = {2022},
}

@article{17503,
  abstract     = {Systems code often requires fine-grained control over memory layout and pointers, expressed using low-level (e.g., bitwise) operations on pointer values. Since these operations go beyond what basic pointer arithmetic in C allows, they are performed with the help of integer-pointer casts. Prior work has explored increasingly realistic memory object models for C that account for the desired semantics of integer-pointer casts while also being sound w.r.t. compiler optimisations, culminating in PNVI, the preferred memory object model in ongoing discussions within the ISO WG14 C standards committee. However, its complexity makes it an unappealing target for verification, and no tools currently exist to verify C programs under PNVI.
In this paper, we introduce VIP, a new memory object model aimed at supporting C verification. VIP sidesteps the complexities of PNVI with a simple but effective idea: a new construct that lets programmers express the intended provenances of integer-pointer casts explicitly. At the same time, we prove VIP compatible with PNVI, thus enabling verification on top of VIP to benefit from PNVI’s validation with respect to practice. In particular, we build a verification tool, RefinedC-VIP, for verifying programs under VIP semantics. As the name suggests, RefinedC-VIP extends the recently developed RefinedC tool, which is automated yet also produces foundational proofs in Coq. We evaluate RefinedC-VIP on a range of systems-code idioms, and validate VIP’s expressiveness via an implementation in the Cerberus C semantics.},
  author       = {Lepigre, Rodolphe and Sammler, Michael Joachim and Memarian, Kayvan and Krebbers, Robbert and Dreyer, Derek and Sewell, Peter},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {POPL},
  pages        = {1--32},
  publisher    = {Association for Computing Machinery},
  title        = {{VIP: Verifying real-world C idioms with integer-pointer casts}},
  doi          = {10.1145/3498681},
  volume       = {6},
  year         = {2022},
}

@article{17504,
  abstract     = {Today’s compilers employ a variety of non-trivial optimizations to achieve good performance. One key trick compilers use to justify transformations of concurrent programs is to assume that the source program has no data races: if it does, they cause the program to have undefined behavior (UB) and give the compiler free rein. However, verifying correctness of optimizations that exploit this assumption is a non-trivial problem. In particular, prior work either has not proven that such optimizations preserve program termination (particularly non-obvious when considering optimizations that move instructions out of loop bodies), or has treated all synchronization operations as external functions (losing the ability to reorder instructions around them).
In this work we present Simuliris, the first simulation technique to establish termination preservation (under a fair scheduler) for a range of concurrent program transformations that exploit UB in the source language. Simuliris is based on the idea of using ownership to reason modularly about the assumptions the compiler makes about programs with well-defined behavior. This brings the benefits of concurrent separation logics to the space of verifying program transformations: we can combine powerful reasoning techniques such as framing and coinduction to perform thread-local proofs of non-trivial concurrent program optimizations. Simuliris is built on a (non-step-indexed) variant of the Coq-based Iris framework, and is thus not tied to a particular language. In addition to demonstrating the effectiveness of Simuliris on standard compiler optimizations involving data race UB, we also instantiate it with Jung et al.’s Stacked Borrows semantics for Rust and generalize their proofs of interesting type-based aliasing optimizations to account for concurrency.},
  author       = {Gäher, Lennard and Sammler, Michael Joachim and Spies, Simon and Jung, Ralf and Dang, Hoang-Hai and Krebbers, Robbert and Kang, Jeehoon and Dreyer, Derek},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {POPL},
  pages        = {1--31},
  publisher    = {Association for Computing Machinery},
  title        = {{Simuliris: A separation logic framework for verifying concurrent program optimizations}},
  doi          = {10.1145/3498689},
  volume       = {6},
  year         = {2022},
}

@article{17506,
  abstract     = {Sandboxing is a common technique that allows low-level, untrusted components to safely interact with trusted code. However, previous work has only investigated the low-level memory isolation guarantees of sandboxing, leaving open the question of the end-to-end guarantees that sandboxing affords programmers. In this paper, we fill this gap by showing that sandboxing enables reasoning about the known concept of robust safety, i.e., safety of the trusted code even in the presence of arbitrary untrusted code. To do this, we first present an idealized operational semantics for a language that combines trusted code with untrusted code. Sandboxing is built into our semantics. Then, we prove that safety properties of the trusted code (as enforced through a rich type system) are upheld in the presence of arbitrary untrusted code, so long as all interactions with untrusted code occur at the “any” type (a type inhabited by all values). Finally, to alleviate the burden of having to interact with untrusted code at only the “any” type, we formalize and prove safe several wrappers, which automatically convert values between the “any” type and much richer types. All our results are mechanized in the Coq proof assistant.},
  author       = {Sammler, Michael Joachim and Garg, Deepak and Dreyer, Derek and Litak, Tadeusz},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {POPL},
  pages        = {1--32},
  publisher    = {Association for Computing Machinery},
  title        = {{The high-level benefits of low-level sandboxing}},
  doi          = {10.1145/3371100},
  volume       = {4},
  year         = {2019},
}

@article{6380,
  abstract     = {There is a huge gap between the speeds of modern caches and main memories, and therefore cache misses account for a considerable loss of efficiency in programs. The predominant technique to address this issue has been Data Packing: data elements that are frequently accessed within time proximity are packed into the same cache block, thereby minimizing accesses to the main memory. We consider the algorithmic problem of Data Packing on a two-level memory system. Given a reference sequence R of accesses to data elements, the task is to partition the elements into cache blocks such that the number of cache misses on R is minimized. The problem is notoriously difficult: it is NP-hard even when the cache has size 1, and is hard to approximate for any cache size larger than 4. Therefore, all existing techniques for Data Packing are based on heuristics and lack theoretical guarantees. In this work, we present the first positive theoretical results for Data Packing, along with new and stronger negative results. We consider the problem under the lens of the underlying access hypergraphs, which are hypergraphs of affinities between the data elements, where the order of an access hypergraph corresponds to the size of the affinity group. We study the problem parameterized by the treewidth of access hypergraphs, which is a standard notion in graph theory to measure the closeness of a graph to a tree. Our main results are as follows: We show there is a number q* depending on the cache parameters such that (a) if the access hypergraph of order q* has constant treewidth, then there is a linear-time algorithm for Data Packing; (b)the Data Packing problem remains NP-hard even if the access hypergraph of order q*-1 has constant treewidth. Thus, we establish a fine-grained dichotomy depending on a single parameter, namely, the highest order among access hypegraphs that have constant treewidth; and establish the optimal value q* of this parameter. Finally, we present an experimental evaluation of a prototype implementation of our algorithm. Our results demonstrate that, in practice, access hypergraphs of many commonly-used algorithms have small treewidth. We compare our approach with several state-of-the-art heuristic-based algorithms and show that our algorithm leads to significantly fewer cache-misses. },
  author       = {Chatterjee, Krishnendu and Goharshady, Amir Kafshdar and Okati, Nastaran and Pavlogiannis, Andreas},
  issn         = {2475-1421},
  journal      = {Proceedings of the ACM on Programming Languages},
  number       = {POPL},
  publisher    = {ACM},
  title        = {{Efficient parameterized algorithms for data packing}},
  doi          = {10.1145/3290366},
  volume       = {3},
  year         = {2019},
}

