Abstract

Abstract This paper presents a framework aimed at significantly reducing the cost of proving functional correctness for low-level operating systems components. The framework is designed around a new functional programming language, Cogent. A central aspect of the language is its uniqueness type system, which eliminates the need for a trusted runtime or garbage collector while still guaranteeing memory safety, a crucial property for safety and security. Moreover, it allows us to assign two semantics to the language: The first semantics is imperative, suitable for efficient C code generation, and the second is purely functional, providing a user-friendly interface for equational reasoning and verification of higher-level correctness properties. The refinement theorem connecting the two semantics allows the compiler to produce a proof via translation validation certifying the correctness of the generated C code with respect to the semantics of the Cogent source program. We have demonstrated the effectiveness of our framework for implementation and for verification through two file system implementations.

Highlights

  • The correctness of any application critically depends on the correctness of the systems on which it relies

  • Our main contribution is the framework for significantly reducing the cost of formal verification for important classes of systems code, using this language-based approach for automatically co-generating code and proofs

  • The blowout in size of the generated C code is mostly a result of normalisation steps applied by the Cogent compiler, most of which is optimised away by the C compiler. The performance of these file systems is generally competitive with their C counterparts (Amani et al, 2016); we found that gcc’s optimiser does an unsatisfactory job of optimising operations on large structs, resulting in some unnecessary copy operations left in the code

Read more

Summary

Introduction

The correctness of any application critically depends on the correctness of the systems on which it relies. It enables the programmer to write low-level systems code in Cogent, a purely functional language with a strong static type system. It facilitates simpler verification of code via equational reasoning in the interactive theorem prover Isabelle/HOL (Nipkow et al, 2002), through a certifying compiler from Cogent to efficient C code. The main restrictions of Cogent are the (purposeful) lack of built-in iteration or recursion, and its uniqueness type system The former ensures totality, which is important for both systems code correctness as well as for a simple shallow representation in higherorder logic (HOL). These case studies demonstrate Cogent’s suitability for systems programming, as well as its potential to reduce the cost of functional correctness verification for real-world systems

Cogent
Variant types
Subtyping and variant types
Abstract types and functions
Suspending uniqueness
Higher-order functions
Polymorphism
Records
Cogent for systems programming
Experience with Cogent
Static semantics
Abstract and observer types
Record types
Subtyping
Dynamic semantics
A tale of two semantics
Value semantics
Update semantics
Refinement and type preservation
A typed refinement relation
Framing
Proving refinement
Foreign functions
Refinement framework
Refinement and forward simulation
Refinement phases
SIMPL and AutoCorres
AutoCorres and Cogent
Monomorphisation
A-normal and deep embeddings
Desugared and neat embeddings
Combined predicate for full refinement
Connecting to abstract specifications
Functional correctness specification
Functional correctness proof
Proving invariants
Subtyping and refinement framework
The Cogent toolchain
Verification effort
Safety and security
Optimisations
Language features
Safe languages
Safe file systems
Findings
Conclusion
Full Text
Paper version not known

Talk to us

Join us for a 30 min session where you can share your feedback and ask us any queries you have

Schedule a call