pub mod proof;
pub mod spec;
use crate::core::spec::Consistency;
use vstd::prelude::*;
verus! {
pub trait DepCombinator {
type Key;
type Val;
type Body: Consistency<Val = Self::Val>;
spec fn apply(&self, key: Self::Key) -> Self::Body;
spec fn recover(&self, value: Self::Val) -> Self::Key;
open spec fn recover_inv(&self) -> bool {
true
}
proof fn lemma_recover_consistent(&self, key: Self::Key, value: Self::Val)
requires
self.recover_inv(),
ensures
self.apply(key).consistent(value) ==> self.recover(value) == key,
;
}
pub type KVFormat<Key, Value, Fmt> = (spec_fn(Key) -> Fmt, spec_fn(Value) -> Key);
#[derive(Copy)]
pub struct Implicit<Head, Tail>(pub Head, pub Tail);
impl<Head: Clone, Tail: Clone> Clone for Implicit<Head, Tail> {
fn clone(&self) -> (cloned: Self)
ensures
call_ensures(Head::clone, (&self.0,), cloned.0),
call_ensures(Tail::clone, (&self.1,), cloned.1),
{
Implicit(self.0.clone(), self.1.clone())
}
}
pub struct VariedLen<Len = u8>(pub core::marker::PhantomData<Len>);
#[allow(non_snake_case)]
pub open spec fn VLData<Len>() -> VariedLen<Len> {
VariedLen(core::marker::PhantomData)
}
pub struct NBytesOf<Len, Then>(pub core::marker::PhantomData<Len>, pub Then);
#[allow(non_snake_case)]
pub open spec fn VLDataOf<Len, C>(c: C) -> NBytesOf<Len, C> {
NBytesOf(core::marker::PhantomData, c)
}
pub struct TVOr<Tag, C, Rest>(pub Tag, pub C, pub Rest);
pub struct VoidTag<Tag>(pub core::marker::PhantomData<Tag>);
#[allow(non_snake_case)]
pub open spec fn Uninhabited<Tag>() -> VoidTag<Tag> {
VoidTag(core::marker::PhantomData)
}
pub struct TLVal<Tag, Len, Body>(pub Body, pub core::marker::PhantomData<(Tag, Len)>);
#[allow(non_snake_case)]
pub open spec fn TLVOf<Tag, Len, Body>(body: Body) -> TLVal<Tag, Len, Body> {
TLVal(body, core::marker::PhantomData)
}
pub struct TagValNode<Tag, Left, Right>(pub Left, pub Right, pub core::marker::PhantomData<Tag>);
#[derive(Copy)]
pub struct TVLeaf<Tag, C>(pub Tag, pub C);
impl<Tag: Clone, C: Clone> Clone for TVLeaf<Tag, C> {
fn clone(&self) -> (cloned: Self)
ensures
call_ensures(Tag::clone, (&self.0,), cloned.0),
call_ensures(C::clone, (&self.1,), cloned.1),
{
TVLeaf(self.0.clone(), self.1.clone())
}
}
#[allow(non_snake_case)]
pub open spec fn TVNode<Tag, Left, Right>(left: Left, right: Right) -> TagValNode<
Tag,
Left,
Right,
> {
TagValNode(left, right, core::marker::PhantomData)
}
}