logic

Attribute Macro logic 

#[logic]
Expand description

Declare a function as being a logical function

This declaration must be pure and total. It cannot be called from Rust programs, but in exchange it can use logical operations and syntax with the help of the pearlite! macro.

§open

Allows the body of a logical definition to be made visible to provers

By default, bodies are opaque: they are only visible to definitions in the same module (like pub(self) for visibility). An optional visibility modifier can be provided to restrict the context in which the body is opened.

A body can only be visible in contexts where all the symbols used in the body are also visible. This means you cannot open a body which refers to a pub(crate) symbol.

§Example

mod inner {
    use creusot_contracts::prelude::*;
    #[logic]
    #[ensures(result == x + 1)]
    pub(super) fn foo(x: Int) -> Int {
        // ...
    }

    #[logic(open)]
    pub(super) fn bar(x: Int) -> Int {
        x + 1
    }
}

// The body of `foo` is not visible here, only the `ensures`.
// But the whole body of `bar` is visible

§prophetic

If you wish to use the ^ operator on mutable borrows to get the final value, you need to specify that the function is prophetic, like so:

#[logic(prophetic)]
fn uses_prophecies(x: &mut Int) -> Int {
    pearlite! { if ^x == 0 { 0 } else { 1 } }
}

Such a logic function cannot be used in snapshot! anymore, and cannot be called from a regular logic function.

§law

Declares a trait item as being a law which is autoloaded as soon another trait item is used in a function.

trait CommutativeOp {
    fn op(self, other: Self) -> Int;

    #[logic(law)]
    #[ensures(forall<x: Self, y: Self> x.op(y) == y.op(x))]
    fn commutative();
}