3,121 research outputs found
Functional Big-step Semantics
When doing an interactive proof about a piece of software, it is important that the underlying programming languageâs semantics does not make the proof unnecessarily difficult or unwieldy. Both smallstep and big-step semantics are commonly used, and the latter is typically given by an inductively defined relation. In this paper, we consider an alternative: using a recursive function akin to an interpreter for the language. The advantages include a better induction theorem, less duplication, accessibility to ordinary functional programmers, and the ease of doing symbolic simulation in proofs via rewriting. We believe that this style of semantics is well suited for compiler verification, including proofs of divergence preservation. We do not claim the invention of this style of semantics: our contribution here is to clarify its value, and to explain how it supports several language features that might appear to require a relational or small-step approach. We illustrate the technique on a simple imperative language with C-like for-loops and a break statement, and compare it to a variety of other approaches. We also provide ML and lambda-calculus based examples to illustrate its generality
A Verified Certificate Checker for Finite-Precision Error Bounds in Coq and HOL4
Being able to soundly estimate roundoff errors of finite-precision
computations is important for many applications in embedded systems and
scientific computing. Due to the discrepancy between continuous reals and
discrete finite-precision values, automated static analysis tools are highly
valuable to estimate roundoff errors. The results, however, are only as correct
as the implementations of the static analysis tools. This paper presents a
formally verified and modular tool which fully automatically checks the
correctness of finite-precision roundoff error bounds encoded in a certificate.
We present implementations of certificate generation and checking for both Coq
and HOL4 and evaluate it on a number of examples from the literature. The
experiments use both in-logic evaluation of Coq and HOL4, and execution of
extracted code outside of the logics: we benchmark Coq extracted unverified
OCaml code and a CakeML-generated verified binary
A formally verified compiler back-end
This article describes the development and formal verification (proof of
semantic preservation) of a compiler back-end from Cminor (a simple imperative
intermediate language) to PowerPC assembly code, using the Coq proof assistant
both for programming the compiler and for proving its correctness. Such a
verified compiler is useful in the context of formal methods applied to the
certification of critical software: the verification of the compiler guarantees
that the safety properties proved on the source code hold for the executable
compiled code as well
Interaction Trees: Representing Recursive and Impure Programs in Coq
"Interaction trees" (ITrees) are a general-purpose data structure for
representing the behaviors of recursive programs that interact with their
environments. A coinductive variant of "free monads," ITrees are built out of
uninterpreted events and their continuations. They support compositional
construction of interpreters from "event handlers", which give meaning to
events by defining their semantics as monadic actions. ITrees are expressive
enough to represent impure and potentially nonterminating, mutually recursive
computations, while admitting a rich equational theory of equivalence up to
weak bisimulation. In contrast to other approaches such as relationally
specified operational semantics, ITrees are executable via code extraction,
making them suitable for debugging, testing, and implementing software
artifacts that are amenable to formal verification.
We have implemented ITrees and their associated theory as a Coq library,
mechanizing classic domain- and category-theoretic results about program
semantics, iteration, monadic structures, and equational reasoning. Although
the internals of the library rely heavily on coinductive proofs, the interface
hides these details so that clients can use and reason about ITrees without
explicit use of Coq's coinduction tactics.
To showcase the utility of our theory, we prove the termination-sensitive
correctness of a compiler from a simple imperative source language to an
assembly-like target whose meanings are given in an ITree-based denotational
semantics. Unlike previous results using operational techniques, our
bisimulation proof follows straightforwardly by structural induction and
elementary rewriting via an equational theory of combinators for control-flow
graphs.Comment: 28 pages, 4 pages references, published at POPL 202
An Abstract Separation Logic for Interlinked Extensible Records
International audienceThe memory manipulated by JavaScript programs can be seen as a heap of extensible records storing values and pointers. We define a separation logic for describing such structures. In order to scale up to full-fledged languages such as JavaScript, this logic must be integrated with existing abstract domains from abstract interpretation. However, the frame ruleâwhich is a central notion in separation logicâdoes not easily mix with abstract interpretation. We present a domain of heaps of interlinked extensible records based on both separation logic and abstract interpretation. The domain features spatial conjunction and uses summary nodes from shape analyses. We show how this domain can accommodate an abstract interpretation including a frame rule
Frex: dependently-typed algebraic simplification
We present an extensible, mathematically-structured algebraic simplification
library design. We structure the library using universal algebraic concepts: a
free algebra -- fral -- and a free extension -- frex -- of an algebra by a set
of variables. The library's dependently-typed API guarantees simplification
modules, even user-defined ones, are terminating, sound, and complete with
respect to a well-specified class of equations. Completeness offers intangible
benefits in practice -- our main contribution is the novel design. Cleanly
separating between the interface and implementation of simplification modules
provides two new modularity axes. First, simplification modules share thousands
of lines of infrastructure code dealing with term-representation,
pretty-printing, certification, and macros/reflection. Second, new
simplification modules can reuse existing ones. We demonstrate this design by
developing simplification modules for monoid varieties: ordinary, commutative,
and involutive. We implemented this design in the new Idris2 dependently-typed
programming language, and in Agda
- âŠ