use vstd::prelude::*;
use crate::connectives::accumulator::Accumulator as AccumulatorCarrier;
use crate::connectives::buffer::Buffer as BufferCarrier;
use crate::connectives::counter::Counter as CounterCarrier;
use crate::connectives::marker::Marker as MarkerCarrier;
use crate::value_eq::ValueEq;
verus! {
pub struct Accumulator<T: Copy> {
inner: AccumulatorCarrier<T>,
}
impl<T: Copy> Accumulator<T> {
pub closed spec fn well_formed(&self) -> bool {
self.inner.well_formed()
}
pub closed spec fn complete(&self) -> bool {
self.inner.pending@.len() == 0
}
pub closed spec fn total_len(&self) -> nat {
self.inner.accumulated@.len() + self.inner.pending@.len()
}
pub fn new(values: Vec<T>) -> (accumulator: Self)
ensures accumulator.well_formed(),
{
Self { inner: AccumulatorCarrier::new(values) }
}
pub fn from_accumulated(values: Vec<T>) -> (accumulator: Self)
ensures
accumulator.well_formed(),
accumulator.complete(),
{
Self { inner: AccumulatorCarrier::from_accumulated(values) }
}
pub fn checked_len(&self) -> Option<usize> {
self.inner
.accumulated_len()
.checked_add(self.inner.pending_len())
}
pub fn is_empty(&self) -> bool {
self.inner.accumulated_len() == 0 && self.inner.pending_len() == 0
}
pub fn accumulated_len(&self) -> usize { self.inner.accumulated_len() }
pub fn pending_len(&self) -> usize { self.inner.pending_len() }
pub fn is_complete(&self) -> (complete: bool)
ensures complete == self.complete(),
{
self.inner.is_complete()
}
pub fn accumulated(&self, index: usize) -> Option<T> { self.inner.accumulated(index) }
pub fn pending(&self, index: usize) -> Option<T> { self.inner.pending(index) }
pub fn advance(&mut self) -> (value: Option<T>)
requires old(self).well_formed(),
ensures final(self).well_formed(),
{
self.inner.advance()
}
pub fn try_append(&mut self, value: T) -> (result: Result<(), T>)
requires old(self).well_formed(),
ensures final(self).well_formed(),
{
if !self.inner.is_complete() { return Err(value); }
self.inner.append(value);
Ok(())
}
}
pub struct Buffer<T> {
inner: BufferCarrier<T>,
}
impl<T> Buffer<T> {
pub closed spec fn retained(&self) -> Seq<T> {
self.inner.values@
}
pub closed spec fn admitted_capacity(&self) -> nat {
self.inner.capacity as nat
}
pub closed spec fn contains_retained(&self, value: T) -> bool {
crate::connectives::buffer::contains_value(self.inner.values@, value)
}
pub closed spec fn well_formed(&self) -> bool {
self.inner.well_formed()
}
pub closed spec fn distinct(&self) -> bool {
crate::connectives::buffer::all_distinct(self.inner.values@)
}
pub fn new(capacity: usize) -> (buffer: Self)
ensures
buffer.well_formed(),
buffer.distinct(),
buffer.admitted_capacity() == capacity as nat,
buffer.retained() == Seq::<T>::empty(),
forall|value: T| !buffer.contains_retained(value),
{
Self { inner: BufferCarrier::new(capacity) }
}
pub fn capacity(&self) -> (capacity: usize)
ensures capacity as nat == self.admitted_capacity(),
{
self.inner.capacity()
}
pub fn len(&self) -> (length: usize)
ensures length as nat == self.retained().len(),
{
self.inner.len()
}
pub fn is_empty(&self) -> (empty: bool)
ensures empty == (self.retained().len() == 0),
{
self.inner.is_empty()
}
pub fn is_full(&self) -> (full: bool)
ensures full == (self.retained().len() == self.admitted_capacity()),
{
self.inner.is_full()
}
pub fn push(&mut self, value: T) -> (result: Result<(), T>)
requires old(self).well_formed(),
ensures
final(self).well_formed(),
final(self).admitted_capacity() == old(self).admitted_capacity(),
old(self).retained().len() < old(self).admitted_capacity() ==>
final(self).retained() == old(self).retained().push(value),
old(self).retained().len() >= old(self).admitted_capacity() ==>
final(self).retained() == old(self).retained(),
{
self.inner.push(value)
}
pub fn pop(&mut self) -> (value: Option<T>)
requires old(self).well_formed(),
ensures
final(self).well_formed(),
final(self).admitted_capacity() == old(self).admitted_capacity(),
old(self).retained().len() == 0 ==>
final(self).retained() == old(self).retained(),
old(self).retained().len() > 0 ==>
final(self).retained() == old(self).retained().skip(1),
old(self).distinct() ==> final(self).distinct(),
{
self.inner.pop()
}
}
impl<T: ValueEq + Copy> Buffer<T> {
pub fn contains(&self, value: T) -> (present: bool)
ensures present == self.contains_retained(value),
{
self.inner.contains(value)
}
#[must_use]
pub fn push_unique(&mut self, value: T) -> (accepted: bool)
requires old(self).well_formed(), old(self).distinct(),
ensures
final(self).well_formed(),
final(self).distinct(),
final(self).admitted_capacity() == old(self).admitted_capacity(),
accepted == (old(self).retained().len() < old(self).admitted_capacity()
&& !old(self).contains_retained(value)),
accepted ==> final(self).retained() == old(self).retained().push(value),
!accepted ==> final(self).retained() == old(self).retained(),
{
self.inner.push_unique(value)
}
#[must_use]
pub fn remove(&mut self, value: T) -> (removed: bool)
requires old(self).well_formed(), old(self).distinct(),
ensures
final(self).well_formed(),
final(self).distinct(),
final(self).admitted_capacity() == old(self).admitted_capacity(),
removed == old(self).contains_retained(value),
forall|candidate: T| #[trigger] final(self).contains_retained(candidate)
== (old(self).contains_retained(candidate) && candidate != value),
{
self.inner.remove_value(value)
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct Counter {
inner: CounterCarrier,
}
impl Counter {
pub fn new(value: u64) -> Self { Self { inner: CounterCarrier::new(value) } }
pub fn value(&self) -> u64 { self.inner.value() }
#[must_use]
pub fn try_increment(&mut self) -> bool { self.inner.try_increment() }
#[must_use]
pub fn try_decrement(&mut self) -> bool { self.inner.try_decrement() }
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct Marker {
inner: MarkerCarrier,
}
impl Marker {
pub fn new(marked: bool) -> Self { Self { inner: MarkerCarrier::new(marked) } }
pub fn is_marked(&self) -> bool { self.inner.is_marked() }
#[must_use]
pub fn set(&mut self) -> bool { self.inner.set() }
#[must_use]
pub fn clear(&mut self) -> bool { self.inner.clear() }
}
pub fn projection_consistent(projected: bool, source: bool) -> (consistent: bool)
ensures consistent == crate::connectives::projection::membership_consistent(projected, source),
{
projected == source
}
pub fn strictly_before(left: usize, right: usize) -> (ordered: bool) {
crate::connectives::ordering_pass::is_strictly_before(left, right)
}
}
impl<T: Copy> Accumulator<T> {
pub fn accumulated_iter(&self) -> impl ExactSizeIterator<Item = &T> {
self.inner.accumulated.iter()
}
pub fn pending_iter(&self) -> impl ExactSizeIterator<Item = &T> {
self.inner.pending.iter()
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.inner
.accumulated
.iter()
.chain(self.inner.pending.iter())
}
}
impl<T: Copy> Default for Accumulator<T> {
fn default() -> Self {
Self::new(Vec::new())
}
}
impl<T: Copy + core::fmt::Debug> core::fmt::Debug for Accumulator<T> {
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter
.debug_struct("Accumulator")
.field("accumulated", &self.inner.accumulated)
.field("pending", &self.inner.pending)
.finish()
}
}
impl<T> Buffer<T> {
pub fn get(&self, index: usize) -> Option<&T> {
self.inner.values.get(index)
}
pub fn as_slice(&self) -> &[T] {
self.inner.values.as_slice()
}
pub fn iter(&self) -> core::slice::Iter<'_, T> {
self.inner.values.iter()
}
}
impl<T> Default for Buffer<T> {
fn default() -> Self {
Self::new(0)
}
}
impl<T: Clone> Clone for Buffer<T> {
fn clone(&self) -> Self {
Self {
inner: BufferCarrier {
capacity: self.inner.capacity,
values: self.inner.values.clone(),
},
}
}
}
impl<T: PartialEq> PartialEq for Buffer<T> {
fn eq(&self, other: &Self) -> bool {
self.inner.capacity == other.inner.capacity && self.inner.values == other.inner.values
}
}
impl<T: Eq> Eq for Buffer<T> {}
impl<T: core::fmt::Debug> core::fmt::Debug for Buffer<T> {
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter
.debug_struct("Buffer")
.field("capacity", &self.inner.capacity)
.field("values", &self.inner.values)
.finish()
}
}
impl<T> AsRef<[T]> for Buffer<T> {
fn as_ref(&self) -> &[T] {
self.as_slice()
}
}
impl<'a, T> IntoIterator for &'a Buffer<T> {
type Item = &'a T;
type IntoIter = core::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T> IntoIterator for Buffer<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.inner.values.into_iter()
}
}
impl From<u64> for Counter {
fn from(value: u64) -> Self {
Self::new(value)
}
}
impl From<Counter> for u64 {
fn from(counter: Counter) -> Self {
counter.value()
}
}
impl From<bool> for Marker {
fn from(marked: bool) -> Self {
Self::new(marked)
}
}
impl From<Marker> for bool {
fn from(marker: Marker) -> Self {
marker.is_marked()
}
}