Invariant

Trait Invariant 

Source
pub trait Invariant {
    // Required method
    fn invariant(self) -> bool;
}
Expand description

A user-defined type invariant.

Type invariants are additional pre- and postconditions added to each program functions.

§Example

struct SumTo10 {
    a: i32,
    b: i32,
}
// The type invariant constrains the set of valid `SumTo10`s to
// only allow values where the sum of both fields is equal to 10.
impl Invariant for SumTo10 {
    #[logic(open)]
    fn invariant(self) -> bool {
        pearlite! {
            self.a@ + self.b@ == 10
        }
    }
}

// #[requires(inv(x))]     // generated by Creusot
// #[ensures(inv(result))] // generated by Creusot
fn invariant_holds(mut x: SumTo10) -> SumTo10 {
    assert!(x.a + x.b == 10); // We are given the invariant when entering the function
    x.a = 5; // we can break it locally!
    x.b = 5; // but it must be restored eventually
    x
}

§Structural invariants

A type automatically inherits the invariants of its fields.

Examples:

  • x: (T, U) -> inv(x.0) && inv(x.1)
  • x: &T -> inv(*x)
  • x: Vec<T> -> forall<i> 0 <= i && i < x@.len() ==> inv(x@[i])

This does not prevent the type to additionnaly implement the Invariant trait.

§Mutable borrows

For mutable borrows, the invariant is the conjunction of the invariants of the current and final values: x: &mut T -> inv(*x) && inv(^x).

§Logical functions

Invariant pre- and postconditions are not added to logical functions:

#[logic]
#[ensures(x.a@ + x.b@ == 10)]
fn not_provable(x: SumTo10) {}

Required Methods§

Source

fn invariant(self) -> bool

(prophetic)

Implementations on Foreign Types§

Source§

impl<A: Iterator, B: Iterator> Invariant for Zip<A, B>

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(self.itera()) && inv(self.iterb())

Source§

impl<B, I: Iterator, F: FnMut(I::Item) -> Option<B>> Invariant for FilterMap<I, F>

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(self.iter()) && inv(self.func()) && private_invariant(self)
Source§

impl<I> Invariant for Cloned<I>

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(self.iter())

Source§

impl<I> Invariant for Copied<I>

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(self.iter())

Source§

impl<I> Invariant for Rev<I>

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(self.iter())

Source§

impl<I: IteratorSpec> Invariant for Enumerate<I>

Source§

fn invariant(self) -> bool

(prophetic)

ensures

result ==> inv(self.iter())

Source§

impl<I: IteratorSpec, B, F: FnMut(I::Item) -> B> Invariant for Map<I, F>

Source§

fn invariant(self) -> bool

(prophetic)

ensures

result ==> inv(self.iter()) && inv(self.func())

Source§

impl<I: Iterator> Invariant for Fuse<I>

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(self.view())

Source§

impl<I: Iterator> Invariant for Skip<I>

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(self.iter())

Source§

impl<I: Iterator> Invariant for Take<I>

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(self.iter())

Source§

impl<I: Iterator, F: FnMut(&I::Item) -> bool> Invariant for Filter<I, F>

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(self.iter()) && inv(self.func()) && private_invariant(self)

ensures

result ==> inv(self.iter()) && inv(self.func())

Source§

impl<T> Invariant for [T]

Source§

fn invariant(self) -> bool

(open, prophetic)

pearlite! { inv(self@) }

Source§

impl<T, A: Allocator> Invariant for VecDeque<T, A>

Available on crate feature nightly only.
Source§

fn invariant(self) -> bool

(open, prophetic)

pearlite! { inv(self@) }

Source§

impl<T, A: Allocator> Invariant for Vec<T, A>

Available on crate feature nightly only.
Source§

fn invariant(self) -> bool

(open, prophetic)

pearlite! { inv(self@) }

Source§

impl<T, const N: usize> Invariant for [T; N]

Source§

fn invariant(self) -> bool

(open, prophetic)

pearlite! { inv(self@) && self@.len() == N@ }

Source§

impl<T: ?Sized> Invariant for &T

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

inv(*self)

Source§

impl<T: ?Sized> Invariant for &mut T

Source§

fn invariant(self) -> bool

(open, prophetic, inline)

pearlite! { inv(*self) && inv(^self) }

Source§

impl<T: ?Sized, A: Allocator> Invariant for Box<T, A>

Available on crate feature nightly only.
Source§

fn invariant(self) -> bool

(open, prophetic)

inv(*self)

Implementors§

Source§

impl<I: IteratorSpec, B, F: FnMut(I::Item, Snapshot<Seq<I::Item>>) -> B> Invariant for MapInv<I, F>

Source§

impl<K, V> Invariant for Authority<K, V>

Source§

impl<K, V> Invariant for Fragment<K, V>

Source§

impl<K, V> Invariant for FMap<K, V>

Source§

impl<T> Invariant for FSet<T>

Source§

impl<T> Invariant for Seq<T>

Source§

impl<T> Invariant for SeqIterRef<'_, T>

Source§

impl<T: Sized> Invariant for PermCellOwn<T>

Source§

impl<T: ?Sized> Invariant for Ghost<T>

Source§

impl<T: ?Sized> Invariant for PtrOwn<T>