@@ -6,6 +6,7 @@ Prusti specifications are a superset of Rust boolean expressions. They must be d
66| --- | --- |
77| [ ` old(...) ` ] ( #old-expressions ) | Value of expression in a previous state |
88| [ ` ... ==> ... ` ] ( #implications ) | Implication |
9+ | [ ` ... === ... ` ] ( #snapshot-equality ) | Snapshot equality |
910| [ ` forall(...) ` ] ( #quantifiers ) | Universal quantifier |
1011| [ ` exists(...) ` ] ( #quantifiers ) | Existential quantifier |
1112| [ <code >... | ; = ...</code >] ( #specification-entailments ) | Specification entailment |
@@ -14,7 +15,7 @@ Prusti specifications are a superset of Rust boolean expressions. They must be d
1415
1516Old expressions are used to refer to the value that a memory location pointed at by a mutable reference had at the beginning of the function:
1617
17- ``` rust
18+ ``` rust,noplaypen
1819use prusti_contracts::*;
1920
2021#[ensures(*x == old(*x) + 1)]
@@ -27,7 +28,7 @@ pub fn inc(x: &mut u32) {
2728
2829Implications express a [ relationship] ( https://en.wikipedia.org/wiki/Material_conditional ) between two boolean expressions:
2930
30- ``` rust
31+ ``` rust,noplaypen
3132#[pure]
3233#[ensures(result ==> self.len() == 0)]
3334#[ensures(!result ==> self.len() > 0)]
@@ -36,17 +37,41 @@ pub fn is_empty(&self) -> bool;
3637
3738There is no syntax for logical equivalences ("if and only if"), because this coincides with ` == ` :
3839
39- ``` rust
40+ ``` rust,noplaypen
4041#[pure]
4142#[ensures(result == (self.len() == 0))]
4243pub fn is_empty(&self) -> bool;
4344```
4445
46+ ## Snapshot Equality
47+
48+ Snapshot equality (` === ` ) compares the
49+ [ snapshots] ( https://viperproject.github.io/prusti-dev/dev-guide/encoding/types-snap.html )
50+ of two values; essentially checking if the two values are structurally equal. In
51+ contrast, the standard equality (` == ` ) between values is determined by the
52+ implementation of
53+ [ ` PartialEq ` ] ( https://doc.rust-lang.org/std/cmp/trait.PartialEq.html ) . These two
54+ equalities do not necessarily coincide. For example, some types do not implement
55+ ` PartialEq ` , or their implementation cannot be encoded as a pure function.
56+ Nonetheless, snapshot equality could be used to compare values of such types, as
57+ in the following code:
58+
59+ ``` rust,noplaypen
60+ #[requires(a === b)]
61+ fn foo<T>(a: T, b: T) {}
62+
63+ struct X { a: i32 }
64+
65+ fn main() {
66+ foo(X { a: 1 }, X { a: 1 });
67+ }
68+ ```
69+
4570## Quantifiers
4671
4772Quantifiers are typically used for describing how a method call changes a container such as a vector:
4873
49- ``` rust
74+ ``` rust,noplaypen
5075#[requires(0 <= index && index < self.len())]
5176#[ensures(self.len() == old(self.len()))]
5277#[ensures(self.lookup(index) == value)]
0 commit comments