Skip to content

v0.3.0

Latest
Compare
Choose a tag to compare
@xldenis xldenis released this 27 Oct 11:20
· 271 commits to master since this release

Following is the changelog of Creusot, a verification tool for safe Rust programs. Using Creusot you can prove -- formally -- that your Rust program behaves in a specific manner.

Creusot allows you to annotate your code using contracts which describe correctness conditions for your program. Creusot then uses SMT solvers to check that these contracts hold for all possible runs of the program. All of this is done statically without running your program, and contracts are erased at compilation time.

Creusot is currently best suited for the verification of code like data-structures or algorithm implementations, and less so for systems which interact heavily with the outside world or exploit concurrency. Notable projects using Creusot include the CreuSAT verified SAT solver and the Sprout SMT solver.

Creusot is still very experimental software, you should expect some obscure crashes and missing features.

Cargo Creusot

Documentation using cargo creusot doc now includes functions specifications and logic function bodies (Arnaud Golfouse @arnaudgolfouse).

Proof obligations are now generated in a separate verif directory, and by default cargo creusot will generate one coma file per module in your program, this can enable faster iteration by only loading relevant submodules during verification.
The old behavior can be restored by passing the --monolithic flag.

Note: We are planning on removing the --focus-on option with the arrival of modular code generation.

The cargo creusot why3 ide has been made aware of this behavior.

Creusot IDE

Not strictly speaking part of this release, we have recently published a new Creusot IDE extension on the VSCode Marketplace.
The extension currently provides syntax highlighting for Creusot, and dynamically updates the proof status within VSCode.

It also has support for running why3find on proofs that have pending obligations by interacting with an icon in the sidebar.

Pearlite

Several minor but still important changes were made to Pearlite in this release, their descriptions follow.

Nested Trusted

The semantics of #[trusted] were slightly altered, the attribute is now inherited, which means that placing it on a module marks all contained functions as trusted. (Xavier Denis @xldenis, request by Molly MacLaren @mojeanmac)

Type invariants & Resolution

Type invariants were completely overhauled, several unsoundnesses were resolved in the process.
Invariants are now added as pre and post conditions to program functions, but are not enforced for logical constructs.

Logical functions and quantifiers no longer provide the invariant, meaning that you must explicitly guard them if you require the invariant to be upheld for a type. This enables future support for empty types.

The resolution trait no longer uses specialization (meaning you no longer have to add min_specialization to your projects). Users should also now use the new, bare resolve functions if needed.
Resolution also comes with a proof obligation to demonstrate the soundness of user-provided implementations of the Resolve trait.

Syntax changes & bug fixes

New syntax to specify triggers in quantifiers (David Ewert @dewert99). Triggers can be added to quantifiers in the following way: forall<x : T, .. > #![trigger exp1,..,expN] exp.
Multi-triggers are supported by providing multiple comma separated values.

Fixes to #[derive(DeepModel)] for structs (Arnaud Golfouse @arnaudgolfouse).

Creusot standard library

The API support for VecDeque was extended, adding indexing, and a custom Resolve implementation. (David Ewert @dewert99)

New specifications for map and filter were added. While proven, the specification for filter is currently hard to successfully apply in projects, we expect revisions in future releases.

Several changes were made to the GhostPtrMap module. (@dewert99)

The ShallowModel trait was renamed to View which is hoped to be less confusing. (Armaël Guéneau @Armael)

Creusot Backend

Place-oriented reasoning

This release marks the complete transition of Creusot to a fully "place oriented" mode of reasoning.
For users, what this means, is generally an easier time working with type invariants, specifically with partially initialized structures and the closing of several lingering unsoundnesses.

Closures

Several crashes with regards to closures (especially nested) were fixed.
Support was added for proof_assert! inside of closures.

Structural Resolution

A new intrinsic structural_resolve generates a resolution statement from the conjunction of fields of a type. All user-defined implementations must be weaker than this.

Ownership in Ghost code

An initial, experimental version of ownership in ghost code was added, reintroducing the ghost! macro. Future releases will flesh out support in this area. (@arnaudgolfhouse)

Coma

A major unsoundness in our encoding of pattern matching in Coma was solved. We found that this was exploited by solvers in a single test of our suite (though without affecting the end reuslt of the proof).
The issue was resolved.

Identifiers generated in Coma are now stable, meaning that re-organizing Rust code should not lead to any changes in generated proofs. This should improve the obsolecence of proofs in Why3. (Li-yao Xia @Lysxia)

SMT Solvers

The Alt-Ergo solver was upgraded to version 2.6.0. As a bonus, it is now installed by cargo creusot setup itself instead of opam. (Armaël Guéneau @Armael)