Expand description
Define local invariants.
Local invariants are not the same as type invariants: they
allow the use of a shared piece of data to be used in the invariant (see
Protocol), but in return they impose a much more restricted access to
the underlying data, as well as the use of Tokens.
§Example
Building a simplified Cell, that only asserts its content’s type invariant.
declare_namespace! { PERMCELL }
/// A cell that simply asserts its content's type invariant.
pub struct CellInv<T: Invariant> {
data: PermCell<T>,
permission: Ghost<LocalInvariant<PermCellLocalInv<T>>>,
}
impl<T: Invariant> Invariant for CellInv<T> {
#[logic]
fn invariant(self) -> bool {
self.permission.namespace() == PERMCELL() && self.permission.public() == self.data.id()
}
}
struct PermCellLocalInv<T>(PermCellOwn<T>);
impl<T: Invariant> Protocol for PermCellLocalInv<T> {
type Public = Id;
#[logic]
fn protocol(self, id: Id) -> bool {
self.0.id() == id
}
}
impl<T: Invariant> CellInv<T> {
#[requires(tokens.contains(PERMCELL()))]
pub fn write(&self, x: T, tokens: Ghost<Tokens>) {
LocalInvariant::open(self.permission.borrow(), tokens, move |perm| unsafe {
*self.data.borrow_mut(ghost!(&mut perm.into_inner().0)) = x
})
}
}§Explicit tokens
For now, Tokens must be explicitely passed to open.
We plan to relax this limitation at some point.
Macros§
- declare_
namespace - Declare a new namespace.
Structs§
- Local
Invariant - A ghost structure, that holds a piece of data (
T) together with an protocol. - Namespace
- The type of namespaces of associated with local invariants.
- Tokens
- Invariant tokens.
Traits§
- Local
Invariant Ext - Define method call syntax for
LocalInvariant::open. - Protocol
- A variant of
Invariantfor use inLocalInvariants.