pub struct Resource<R>(/* private fields */);Expand description
A ghost wrapper around a resource algebra.
This structure is meant to be manipulated in ghost code.
The usual usage is this:
- Create some ghost resource
- Split it into multiple parts.
This may be used to duplicate the resource if we have
self.op(self) == self. - Join these parts later. By exploiting validity of the combination, this allows one to learn information about one part from the other.
§Example
use creusot_contracts::{ghost::resource::Resource, logic::ra::agree::Ag, prelude::*};
let mut res: Ghost<Resource<Ag<Int>>> = Resource::alloc(snapshot!(Ag(1)));
ghost! {
let part = res.split_off(snapshot!(Ag(1)), snapshot!(Ag(1)));
// Pass `part` around, forget what it contained...
let _ = res.join_shared(&part);
// And now we remember: the only way the above worked is if `part` contained `1`!
proof_assert!(part@ == Ag(1));
};Implementations§
Source§impl<R: RA> Resource<R>
impl<R: RA> Resource<R>
Sourcepub fn id(self) -> Id
pub fn id(self) -> Id
Get the id for this resource.
This prevents mixing resources of different origins.
(opaque) ⚠
Sourcepub fn id_ghost(&self) -> Id
pub fn id_ghost(&self) -> Id
Get the id for this resource.
This is the same as Self::id, but for ghost code.
terminates
ghost
ensures
result == self.id()Sourcepub fn alloc(r: Snapshot<R>) -> Ghost<Self>
pub fn alloc(r: Snapshot<R>) -> Ghost<Self>
Create a new resource
§Corresponding reasoning
⊢ |=> ∃γ, Own(value, γ)
terminates
ghost
ensures
result@ == *rSourcepub fn core(&self) -> Self
pub fn core(&self) -> Self
Duplicate the duplicable core of a resource
requires
self@.core() != Noneensures
result.id() == self.id()ensures
Some(result@) == self@.core()terminates
ghost
Sourcepub fn split(self, a: Snapshot<R>, b: Snapshot<R>) -> (Self, Self)
pub fn split(self, a: Snapshot<R>, b: Snapshot<R>) -> (Self, Self)
Split a resource into two parts, described by a and b.
See also Self::split_mut and Self::split_off.
§Corresponding reasoning
⌜a = b ⋅ c⌝ ∧ Own(a, γ) ⊢ Own(b, γ) ∗ Own(c, γ)
terminates
ghost
requires
R::incl_eq_op(*a, *b, self@)ensures
result.0.id() == self.id() && result.1.id() == self.id()ensures
result.0@ == *aensures
result.1@ == *bSourcepub fn split_mut(
&mut self,
a: Snapshot<R>,
b: Snapshot<R>,
) -> (&mut Self, &mut Self)
pub fn split_mut( &mut self, a: Snapshot<R>, b: Snapshot<R>, ) -> (&mut Self, &mut Self)
Split a resource into two, and join it again once the mutable borrows are dropped.
terminates
ghost
requires
R::incl_eq_op(*a, *b, self@)ensures
result.0.id() == self.id() && result.1.id() == self.id()ensures
result.0@ == *a && result.1@ == *bensures
(^result.0).id() == self.id() && (^result.1).id() == self.id() ==> (^self).id() == self.id() && Some((^self)@) == (^result.0)@.op((^result.1)@)
Sourcepub fn split_off(&mut self, r: Snapshot<R>, s: Snapshot<R>) -> Self
pub fn split_off(&mut self, r: Snapshot<R>, s: Snapshot<R>) -> Self
Remove r from self and return it, leaving s in self.
terminates
ghost
requires
R::incl_eq_op(*r, *s, self@)ensures
(^self).id() == self.id() && result.id() == self.id()ensures
(^self)@ == *sensures
result@ == *rSourcepub fn join(self, other: Self) -> Self
pub fn join(self, other: Self) -> Self
Join two owned resources together.
See also [Self::join_mut] and Self::join_shared.
§Corresponding reasoning
⌜c = a ⋅ b⌝ ∗ Own(a, γ) ∗ Own(b, γ) ⊢ Own(c, γ)
terminates
ghost
requires
self.id() == other.id()ensures
result.id() == self.id()ensures
Some(result@) == self@.op(other@)Sourcepub fn join_in(&mut self, other: Self)
pub fn join_in(&mut self, other: Self)
Same as Self::join, but put the result into self.
terminates
ghost
requires
self.id() == other.id()ensures
(^self).id() == self.id()ensures
Some((^self)@) == self@.op(other@)Join two shared resources together.
§Corresponding reasoning
⌜a ≼ c⌝ ∧ ⌜b ≼ c⌝ ∧ Own(a, γ) ∧ Own(b, γ) ⊢ Own(c, γ)
terminates
ghost
requires
self.id() == other.id()ensures
result.id() == self.id()ensures
self@.incl_eq(result@) && other@.incl_eq(result@)Sourcepub fn weaken(&mut self, target: Snapshot<R>)
pub fn weaken(&mut self, target: Snapshot<R>)
Transforms self into target, given that target is included in self.
terminates
ghost
requires
target.incl(self@)ensures
(^self).id() == self.id()ensures
(^self)@ == *targetValidate the composition of self and other.
terminates
ghost
requires
self.id() == other.id()ensures
^self == *selfensures
self@.op(other@) != None