use crate::connectives::cursor::Cursor as CursorCarrier;
use crate::primitives::actuation_pass::ActuationPass as ActuationPassCarrier;
use crate::primitives::audit_sink::AuditSink as AuditSinkCarrier;
use crate::primitives::backtracking_traversal::BacktrackingTraversal as BacktrackingTraversalCarrier;
use crate::primitives::budget::Budget as BudgetCarrier;
use crate::primitives::competitive_selection::{
CompetitiveSelectionHard as CompetitiveSelectionHardCarrier,
CompetitiveSelectionHardExclusive as CompetitiveSelectionHardExclusiveCarrier,
CompetitiveSelectionRanked as CompetitiveSelectionRankedCarrier,
CompetitiveSelectionSoft as CompetitiveSelectionSoftCarrier,
};
use crate::primitives::convergence_governor_phase_aware::ConvergenceGovernorPhaseAware as ConvergenceGovernorCarrier;
use crate::primitives::propagation_pass::PropagationPass as PropagationPassCarrier;
use crate::primitives::quality_hierarchy::QualityHierarchy as QualityHierarchyCarrier;
use crate::primitives::resource_registry::ResourceRegistry as RegistryCarrier;
use vstd::prelude::*;
pub use crate::primitives::convergence_governor_phase_aware::{
GovState as ConvergenceState, Phase as ConvergencePhase,
};
pub use crate::primitives::propagation_pass::Round as PropagationRound;
verus! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum BudgetError {
AmountExceedsReservation,
AmountExceedsAllocation,
AmountExceedsPendingEviction,
}
pub struct Budget {
inner: BudgetCarrier,
}
impl Budget {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.safety_invariant()
}
pub fn new(capacity: u64) -> (budget: Self) {
let inner = BudgetCarrier::new(capacity);
Self { inner }
}
pub fn capacity(&self) -> u64 {
self.inner.capacity
}
pub fn allocated(&self) -> u64 {
self.inner.allocated
}
pub fn reserved(&self) -> u64 {
self.inner.reserved
}
pub fn pending_eviction(&self) -> u64 {
self.inner.pending_eviction
}
pub fn available(&self) -> (available: u64) {
proof { use_type_invariant(&*self); }
self.inner.available()
}
#[must_use]
pub fn try_allocate(&mut self, amount: u64) -> (accepted: bool) {
proof { use_type_invariant(&*self); }
let mut carrier = budget_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
let accepted = carrier.try_allocate(amount);
core::mem::swap(&mut self.inner, &mut carrier);
accepted
}
#[must_use]
pub fn try_reserve(&mut self, amount: u64) -> (accepted: bool) {
proof { use_type_invariant(&*self); }
let mut carrier = budget_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
let accepted = carrier.reserve(amount);
core::mem::swap(&mut self.inner, &mut carrier);
accepted
}
pub fn commit_reservation(&mut self, amount: u64) -> (result: Result<(), BudgetError>) {
proof { use_type_invariant(&*self); }
if amount <= self.inner.reserved {
let mut carrier = budget_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.commit_reservation(amount);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
} else {
Err(BudgetError::AmountExceedsReservation)
}
}
pub fn release(&mut self, amount: u64) -> (result: Result<(), BudgetError>) {
proof { use_type_invariant(&*self); }
if amount <= self.inner.allocated {
let mut carrier = budget_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.release(amount);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
} else {
Err(BudgetError::AmountExceedsAllocation)
}
}
pub fn mark_eviction(&mut self, amount: u64) -> (result: Result<(), BudgetError>) {
proof { use_type_invariant(&*self); }
if amount <= self.inner.allocated {
let mut carrier = budget_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.mark_eviction(amount);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
} else {
Err(BudgetError::AmountExceedsAllocation)
}
}
pub fn complete_eviction(&mut self, amount: u64) -> (result: Result<(), BudgetError>) {
proof { use_type_invariant(&*self); }
if amount <= self.inner.pending_eviction {
let mut carrier = budget_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.complete_eviction(amount);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
} else {
Err(BudgetError::AmountExceedsPendingEviction)
}
}
}
pub struct ResourceRegistry {
inner: RegistryCarrier<u64, u64>,
}
impl ResourceRegistry {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.unique_mapping()
}
pub fn new() -> (registry: Self) {
let inner = RegistryCarrier::new();
Self { inner }
}
pub fn len(&self) -> usize {
self.inner.entries.len()
}
pub fn is_empty(&self) -> bool {
self.inner.entries.is_empty()
}
pub fn get(&self, key: u64) -> (value: Option<u64>) {
proof { use_type_invariant(&*self); }
self.inner.lookup(key)
}
pub fn insert(&mut self, key: u64, value: u64) -> (previous: Option<u64>) {
proof { use_type_invariant(&*self); }
let previous = self.inner.lookup(key);
let mut carrier = registry_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.register(key, value);
core::mem::swap(&mut self.inner, &mut carrier);
previous
}
pub fn remove(&mut self, key: u64) -> (previous: Option<u64>) {
proof { use_type_invariant(&*self); }
let previous = self.inner.lookup(key);
match previous {
Some(value) => {
let mut carrier = registry_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.deregister(key);
core::mem::swap(&mut self.inner, &mut carrier);
Some(value)
},
None => None,
}
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the registry index is in bounds")]
pub fn entry(&self, index: usize) -> Option<(u64, u64)> {
if index < self.inner.entries.len() {
Some(self.inner.entries[index])
} else {
None
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct AuditRecord {
pub operation: u64,
pub previous_hash: u64,
pub hash: u64,
}
pub struct AuditSink {
inner: AuditSinkCarrier,
}
impl AuditSink {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.inv()
}
pub fn new(capacity: usize) -> (sink: Self) {
let inner = AuditSinkCarrier::new(capacity);
Self { inner }
}
pub fn capacity(&self) -> usize {
self.inner.max_log_len
}
pub fn len(&self) -> usize {
self.inner.log.len()
}
pub fn is_empty(&self) -> bool {
self.inner.log.is_empty()
}
pub fn last_hash(&self) -> u64 {
self.inner.last_hash
}
#[must_use]
pub fn try_record(&mut self, operation: u64) -> (accepted: bool) {
proof { use_type_invariant(&*self); }
let mut carrier = audit_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
let accepted = carrier.record(operation);
core::mem::swap(&mut self.inner, &mut carrier);
accepted
}
pub fn validate(&self) -> (valid: bool) {
proof { use_type_invariant(&*self); }
self.inner.validate()
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the audit index is in bounds")]
pub fn record(&self, index: usize) -> Option<AuditRecord> {
if index < self.inner.log.len() {
let entry = &self.inner.log[index];
Some(AuditRecord {
operation: entry.operation,
previous_hash: entry.prev_hash,
hash: entry.hash,
})
} else {
None
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum CursorError {
Regression,
}
pub struct Cursor {
inner: CursorCarrier,
}
impl Cursor {
pub fn new(position: usize) -> (cursor: Self) {
Self { inner: CursorCarrier::new(position) }
}
pub fn position(&self) -> usize {
self.inner.position
}
pub fn advance_to(&mut self, position: usize) -> (result: Result<(), CursorError>) {
if position < self.inner.position {
return Err(CursorError::Regression);
}
self.inner.advance_to(position);
Ok(())
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum PropagationBuildError {
InitialValueOutOfRange,
EdgeEndpointOutOfRange,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum PropagationError {
NodeOutOfRange,
RoundAlreadyRunning,
RoundNotRunning,
NodeAlreadyUpdated,
RoundIncomplete,
PassTerminated,
PassStillRunning,
}
pub struct PropagationPass {
inner: PropagationPassCarrier,
}
impl PropagationPass {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.inv()
}
pub fn new(
max_iterations: u64,
max_value: u64,
edges: Vec<(usize, usize)>,
initial_values: Vec<u64>,
) -> (result: Result<Self, PropagationBuildError>) {
if !values_within_max(&initial_values, max_value) {
return Err(PropagationBuildError::InitialValueOutOfRange);
}
let num_nodes = initial_values.len();
if !edges_within_nodes(&edges, num_nodes) {
return Err(PropagationBuildError::EdgeEndpointOutOfRange);
}
let inner = PropagationPassCarrier::new(
num_nodes,
max_iterations,
max_value,
edges,
initial_values,
);
Ok(Self { inner })
}
pub fn num_nodes(&self) -> usize {
self.inner.num_nodes
}
pub fn max_iterations(&self) -> u64 {
self.inner.max_iterations
}
pub fn max_value(&self) -> u64 {
self.inner.max_value
}
pub fn iteration(&self) -> u64 {
self.inner.iteration
}
pub fn round(&self) -> PropagationRound {
self.inner.round
}
pub fn changed(&self) -> bool {
self.inner.changed
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the node index is in bounds")]
pub fn value(&self, node: usize) -> Option<u64> {
if node < self.inner.values.len() {
Some(self.inner.values[node])
} else {
None
}
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the snapshot index is in bounds")]
pub fn snapshot_value(&self, node: usize) -> Option<u64> {
if node < self.inner.snapshot.len() {
Some(self.inner.snapshot[node])
} else {
None
}
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the update index is in bounds")]
pub fn node_updated(&self, node: usize) -> Option<bool> {
if node < self.inner.updated.len() {
Some(self.inner.updated[node])
} else {
None
}
}
pub fn start_round(&mut self) -> (result: Result<(), PropagationError>) {
proof { use_type_invariant(&*self); }
match self.inner.round {
PropagationRound::Running => {
return Err(PropagationError::RoundAlreadyRunning);
},
PropagationRound::Idle => {},
}
if !self.inner.changed || self.inner.iteration >= self.inner.max_iterations {
return Err(PropagationError::PassTerminated);
}
let mut carrier = propagation_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.start_round();
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the update index is in bounds")]
pub fn update_node(&mut self, node: usize) -> (result: Result<(), PropagationError>) {
proof { use_type_invariant(&*self); }
match self.inner.round {
PropagationRound::Idle => {
return Err(PropagationError::RoundNotRunning);
},
PropagationRound::Running => {},
}
if node >= self.inner.num_nodes {
return Err(PropagationError::NodeOutOfRange);
}
if self.inner.updated[node] {
return Err(PropagationError::NodeAlreadyUpdated);
}
let mut carrier = propagation_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.update_node(node);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
pub fn end_round(&mut self) -> (result: Result<(), PropagationError>) {
proof { use_type_invariant(&*self); }
match self.inner.round {
PropagationRound::Idle => {
return Err(PropagationError::RoundNotRunning);
},
PropagationRound::Running => {},
}
if !self.inner.all_nodes_updated() {
return Err(PropagationError::RoundIncomplete);
}
let mut carrier = propagation_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.end_round();
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
pub fn terminate(&mut self) -> (result: Result<(), PropagationError>) {
proof { use_type_invariant(&*self); }
match self.inner.round {
PropagationRound::Running => {
return Err(PropagationError::RoundAlreadyRunning);
},
PropagationRound::Idle => {},
}
if self.inner.changed && self.inner.iteration != self.inner.max_iterations {
return Err(PropagationError::PassStillRunning);
}
let mut carrier = propagation_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.terminate();
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum ActuationError {
SeatOutOfRange,
PassComplete,
SeatAlreadyAllocated,
SeatUnallocated,
SeatAlreadyActuated,
PassIncomplete,
}
pub struct ActuationPass {
inner: ActuationPassCarrier,
}
impl ActuationPass {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.invariant()
}
pub fn new(allocation: Vec<Option<u64>>) -> (pass: Self) {
let num_seats = allocation.len();
let inner = ActuationPassCarrier::new(allocation, num_seats);
Self { inner }
}
pub fn len(&self) -> usize {
self.inner.num_seats
}
pub fn is_empty(&self) -> bool {
self.inner.num_seats == 0
}
pub fn is_complete(&self) -> bool {
self.inner.complete
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the allocation index is in bounds")]
pub fn allocation(&self, seat: usize) -> Option<Option<u64>> {
if seat < self.inner.allocation.len() {
Some(self.inner.allocation[seat])
} else {
None
}
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the effect index is in bounds")]
pub fn effect(&self, seat: usize) -> Option<Option<u64>> {
if seat < self.inner.effects.len() {
Some(self.inner.effects[seat])
} else {
None
}
}
pub fn allocate(&mut self, seat: usize, resource: u64) -> (result: Result<(), ActuationError>) {
proof { use_type_invariant(&*self); }
if seat >= self.inner.num_seats {
return Err(ActuationError::SeatOutOfRange);
}
if self.inner.complete {
return Err(ActuationError::PassComplete);
}
if !self.inner.can_allocate(seat) {
return Err(ActuationError::SeatAlreadyAllocated);
}
let mut carrier = actuation_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.allocate(seat, resource);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
pub fn deallocate(&mut self, seat: usize) -> (result: Result<(), ActuationError>) {
proof { use_type_invariant(&*self); }
if seat >= self.inner.num_seats {
return Err(ActuationError::SeatOutOfRange);
}
if self.inner.complete {
return Err(ActuationError::PassComplete);
}
if !self.inner.is_allocated(seat) {
return Err(ActuationError::SeatUnallocated);
}
if !self.inner.can_deallocate(seat) {
return Err(ActuationError::SeatAlreadyActuated);
}
let mut carrier = actuation_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.deallocate(seat);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
pub fn actuate(&mut self, seat: usize) -> (result: Result<(), ActuationError>) {
proof { use_type_invariant(&*self); }
if seat >= self.inner.num_seats {
return Err(ActuationError::SeatOutOfRange);
}
if self.inner.complete {
return Err(ActuationError::PassComplete);
}
if !self.inner.is_allocated(seat) {
return Err(ActuationError::SeatUnallocated);
}
if !self.inner.can_actuate(seat) {
return Err(ActuationError::SeatAlreadyActuated);
}
let mut carrier = actuation_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.actuate(seat);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
pub fn ready_to_finish(&self) -> (ready: bool) {
proof { use_type_invariant(&*self); }
self.inner.ready_to_finish_exec()
}
pub fn finish(&mut self) -> (result: Result<(), ActuationError>) {
proof { use_type_invariant(&*self); }
if self.inner.complete {
return Err(ActuationError::PassComplete);
}
if !self.inner.ready_to_finish_exec() {
return Err(ActuationError::PassIncomplete);
}
let mut carrier = actuation_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.finish();
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum QualityHierarchyError {
NodeOutOfRange,
ParentOutOfRange,
ChildOutOfRange,
LevelOutOfRange,
CostOutOfRange,
NodeNotIsolated,
SelfEdge,
EdgeAlreadyExists,
ChildAlreadyParented,
LevelOrderViolation,
CostOrderViolation,
}
pub struct QualityHierarchy {
inner: QualityHierarchyCarrier,
}
impl QualityHierarchy {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.type_invariant()
&& self.inner.strict_level_descent()
&& self.inner.parent_edge_agreement()
&& self.inner.cost_monotonicity()
}
pub fn new(num_nodes: usize, max_level: u64) -> (hierarchy: Self) {
let inner = QualityHierarchyCarrier::new(num_nodes, max_level);
Self { inner }
}
pub fn len(&self) -> usize {
self.inner.num_nodes
}
pub fn is_empty(&self) -> bool {
self.inner.num_nodes == 0
}
pub fn max_level(&self) -> u64 {
self.inner.max_level
}
pub fn level(&self, node: usize) -> Option<u64> {
proof { use_type_invariant(&*self); }
if node < self.inner.num_nodes {
Some(self.inner.level_of(node))
} else {
None
}
}
pub fn cost(&self, node: usize) -> Option<u64> {
proof { use_type_invariant(&*self); }
if node < self.inner.num_nodes {
Some(self.inner.cost_of(node))
} else {
None
}
}
pub fn parent(&self, node: usize) -> Option<usize> {
proof { use_type_invariant(&*self); }
if node >= self.inner.num_nodes {
return None;
}
let parent = self.inner.parent_of(node);
if parent == self.inner.num_nodes {
None
} else {
Some(parent)
}
}
pub fn edge_count(&self) -> usize {
self.inner.edges.len()
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the hierarchy edge index is in bounds")]
pub fn edge(&self, index: usize) -> Option<(usize, usize)> {
if index < self.inner.edges.len() {
Some(self.inner.edges[index])
} else {
None
}
}
pub fn set_node_properties(
&mut self,
node: usize,
level: u64,
cost: u64,
) -> (result: Result<(), QualityHierarchyError>) {
proof { use_type_invariant(&*self); }
if node >= self.inner.num_nodes {
return Err(QualityHierarchyError::NodeOutOfRange);
}
if level > self.inner.max_level {
return Err(QualityHierarchyError::LevelOutOfRange);
}
if cost > self.inner.max_level {
return Err(QualityHierarchyError::CostOutOfRange);
}
if !self.inner.can_set_node_properties(node, level, cost) {
return Err(QualityHierarchyError::NodeNotIsolated);
}
let mut carrier = quality_hierarchy_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.set_node_properties(node, level, cost);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
pub fn add_child(
&mut self,
parent: usize,
child: usize,
) -> (result: Result<(), QualityHierarchyError>) {
proof { use_type_invariant(&*self); }
if parent >= self.inner.num_nodes {
return Err(QualityHierarchyError::ParentOutOfRange);
}
if child >= self.inner.num_nodes {
return Err(QualityHierarchyError::ChildOutOfRange);
}
if self.inner.can_add_child(parent, child) {
let mut carrier = quality_hierarchy_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.add_child(parent, child);
core::mem::swap(&mut self.inner, &mut carrier);
return Ok(());
}
if parent == child {
Err(QualityHierarchyError::SelfEdge)
} else if self.inner.has_edge(parent, child) {
Err(QualityHierarchyError::EdgeAlreadyExists)
} else if self.inner.parent_of(child) != self.inner.num_nodes {
Err(QualityHierarchyError::ChildAlreadyParented)
} else if self.inner.level_of(parent) <= self.inner.level_of(child) {
Err(QualityHierarchyError::LevelOrderViolation)
} else {
Err(QualityHierarchyError::CostOrderViolation)
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum BacktrackingBuildError {
InitialAuxOutOfRange,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum BacktrackingError {
AtLeaf,
ChoiceOutOfRange,
DeltaOutOfRange,
NotLeaf,
AlreadyVisited,
AtRoot,
}
pub struct BacktrackingTraversal {
inner: BacktrackingTraversalCarrier,
}
impl BacktrackingTraversal {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.inv()
}
pub fn new(
branch_factor: u64,
max_depth: usize,
initial_aux: u64,
) -> (result: Result<Self, BacktrackingBuildError>) {
if initial_aux >= 3 {
return Err(BacktrackingBuildError::InitialAuxOutOfRange);
}
let inner = BacktrackingTraversalCarrier::new(branch_factor, max_depth, initial_aux);
Ok(Self { inner })
}
pub fn max_depth(&self) -> usize {
self.inner.max_depth
}
pub fn depth(&self) -> usize {
self.inner.path.len()
}
pub fn auxiliary(&self) -> u64 {
self.inner.aux
}
pub fn visited_count(&self) -> usize {
self.inner.visited.len()
}
pub fn is_leaf(&self) -> bool {
self.inner.is_leaf_exec()
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the path index is in bounds")]
pub fn choice(&self, depth: usize) -> Option<u64> {
if depth < self.inner.path.len() {
Some(self.inner.path[depth])
} else {
None
}
}
pub fn descend(&mut self, choice: u64, delta: u64) -> (result: Result<(), BacktrackingError>) {
proof { use_type_invariant(&*self); }
if self.inner.is_leaf_exec() {
return Err(BacktrackingError::AtLeaf);
}
if choice < 1 || choice > self.inner.branch_factor {
return Err(BacktrackingError::ChoiceOutOfRange);
}
if delta < 1 || delta > 2 {
return Err(BacktrackingError::DeltaOutOfRange);
}
let mut carrier = backtracking_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.descend(choice, delta);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
pub fn visit(&mut self) -> (result: Result<(), BacktrackingError>) {
proof { use_type_invariant(&*self); }
if !self.inner.is_leaf_exec() {
return Err(BacktrackingError::NotLeaf);
}
if !self.inner.can_visit() {
return Err(BacktrackingError::AlreadyVisited);
}
let mut carrier = backtracking_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.visit();
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
pub fn ascend(&mut self) -> (result: Result<(), BacktrackingError>) {
proof { use_type_invariant(&*self); }
if !self.inner.can_ascend() {
return Err(BacktrackingError::AtRoot);
}
let mut carrier = backtracking_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.ascend();
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum CompetitiveSelectionError {
NoCandidates,
CandidateOutOfRange,
SeatOutOfRange,
SeatAlreadyAllocated,
NoCandidateAvailable,
ScoreOutOfRange,
ScoreCountMismatch,
WeightTotalBelowReservedFloor,
WeightTotalOutOfRange,
MaxScoreOutOfRange,
AllocationComplete,
}
pub struct CompetitiveSelectionHard {
inner: CompetitiveSelectionHardCarrier,
}
impl CompetitiveSelectionHard {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.inv() && self.inner.scores.len() >= 1
}
pub fn new(num_candidates: usize) -> (result: Result<Self, CompetitiveSelectionError>) {
if num_candidates == 0 {
return Err(CompetitiveSelectionError::NoCandidates);
}
let inner = CompetitiveSelectionHardCarrier::new(num_candidates);
Ok(Self { inner })
}
pub fn len(&self) -> usize {
self.inner.scores.len()
}
pub fn is_empty(&self) -> bool {
false
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the candidate index is in bounds")]
pub fn score(&self, candidate: usize) -> Option<u64> {
if candidate < self.inner.scores.len() {
Some(self.inner.scores[candidate])
} else {
None
}
}
pub fn winner(&self) -> Option<usize> {
self.inner.allocation
}
pub fn update_score(
&mut self,
candidate: usize,
score: u64,
) -> (result: Result<(), CompetitiveSelectionError>) {
proof { use_type_invariant(&*self); }
if candidate >= self.inner.scores.len() {
return Err(CompetitiveSelectionError::CandidateOutOfRange);
}
let mut carrier = hard_selection_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.update_score(candidate, score);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
#[expect(clippy::manual_unwrap_or_default, reason = "the explicit match is supported by the Verus boundary")]
pub fn evaluate(&mut self) -> (winner: usize) {
proof { use_type_invariant(&*self); }
let mut carrier = hard_selection_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.evaluate();
let winner = match carrier.allocation {
Some(value) => value,
None => 0,
};
core::mem::swap(&mut self.inner, &mut carrier);
winner
}
}
pub struct CompetitiveSelectionHardExclusive {
inner: CompetitiveSelectionHardExclusiveCarrier,
}
impl CompetitiveSelectionHardExclusive {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.inv()
}
pub fn new(
num_seats: usize,
num_candidates: usize,
max_score: u64,
) -> (result: Result<Self, CompetitiveSelectionError>) {
if num_candidates == 0 {
return Err(CompetitiveSelectionError::NoCandidates);
}
let inner = CompetitiveSelectionHardExclusiveCarrier::new(
num_seats,
num_candidates,
max_score,
);
Ok(Self { inner })
}
pub fn seat_count(&self) -> usize {
self.inner.num_seats
}
pub fn candidate_count(&self) -> usize {
self.inner.num_candidates
}
pub fn max_score(&self) -> u64 {
self.inner.max_score
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the seat index is in bounds")]
#[expect(clippy::manual_map, reason = "the explicit match is supported by the Verus boundary")]
pub fn allocation(&self, seat: usize) -> Option<usize> {
proof { use_type_invariant(&*self); }
if seat >= self.inner.num_seats {
return None;
}
match self.inner.allocation[seat] {
Some(candidate) => Some(candidate as usize),
None => None,
}
}
#[expect(clippy::indexing_slicing, reason = "the branches prove both score indices are in bounds")]
pub fn score(&self, seat: usize, candidate: usize) -> Option<u64> {
proof { use_type_invariant(&*self); }
if seat >= self.inner.num_seats || candidate >= self.inner.num_candidates {
None
} else {
Some(self.inner.scores[seat][candidate])
}
}
pub fn candidate_available(&self, seat: usize, candidate: usize) -> Option<bool> {
proof { use_type_invariant(&*self); }
if seat >= self.inner.num_seats || candidate >= self.inner.num_candidates {
return None;
}
Some(self.inner.candidate_available(seat, candidate))
}
pub fn update_score(
&mut self,
seat: usize,
candidate: usize,
score: u64,
) -> (result: Result<(), CompetitiveSelectionError>) {
proof { use_type_invariant(&*self); }
if seat >= self.inner.num_seats {
return Err(CompetitiveSelectionError::SeatOutOfRange);
}
if candidate >= self.inner.num_candidates {
return Err(CompetitiveSelectionError::CandidateOutOfRange);
}
if score > self.inner.max_score {
return Err(CompetitiveSelectionError::ScoreOutOfRange);
}
let mut carrier = hard_exclusive_selection_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.update_score(seat, candidate, score);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
#[expect(clippy::indexing_slicing, reason = "the guards prove the seat index is in bounds")]
pub fn evaluate(
&mut self,
seat: usize,
) -> (result: Result<usize, CompetitiveSelectionError>) {
proof { use_type_invariant(&*self); }
if seat >= self.inner.num_seats {
return Err(CompetitiveSelectionError::SeatOutOfRange);
}
if self.inner.allocation[seat].is_some() {
return Err(CompetitiveSelectionError::SeatAlreadyAllocated);
}
if !self.inner.has_available(seat) {
return Err(CompetitiveSelectionError::NoCandidateAvailable);
}
let mut carrier = hard_exclusive_selection_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.evaluate(seat);
let winner = match carrier.allocation[seat] {
Some(candidate) => candidate as usize,
None => 0,
};
core::mem::swap(&mut self.inner, &mut carrier);
Ok(winner)
}
}
pub struct CompetitiveSelectionSoft {
inner: CompetitiveSelectionSoftCarrier,
}
impl CompetitiveSelectionSoft {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.mutable_score_inv()
}
pub fn new(
scores: Vec<u64>,
weight_total: u64,
max_score: u64,
) -> (result: Result<Self, CompetitiveSelectionError>) {
if scores.is_empty() {
return Err(CompetitiveSelectionError::NoCandidates);
}
if weight_total > 1_000_000_000 {
return Err(CompetitiveSelectionError::WeightTotalOutOfRange);
}
if max_score > 1_000_000_000 {
return Err(CompetitiveSelectionError::MaxScoreOutOfRange);
}
if weight_total < scores.len() as u64 {
return Err(CompetitiveSelectionError::WeightTotalBelowReservedFloor);
}
if !positive_values_within_max(&scores, max_score) {
return Err(CompetitiveSelectionError::ScoreOutOfRange);
}
let inner = CompetitiveSelectionSoftCarrier::new(scores, weight_total, max_score);
Ok(Self { inner })
}
pub fn begin(
scores: Vec<u64>,
weight_total: u64,
max_score: u64,
) -> (result: Result<Self, CompetitiveSelectionError>) {
if scores.is_empty() {
return Err(CompetitiveSelectionError::NoCandidates);
}
if weight_total > 1_000_000_000 {
return Err(CompetitiveSelectionError::WeightTotalOutOfRange);
}
if max_score > 1_000_000_000 {
return Err(CompetitiveSelectionError::MaxScoreOutOfRange);
}
if weight_total < scores.len() as u64 {
return Err(CompetitiveSelectionError::WeightTotalBelowReservedFloor);
}
if !positive_values_within_max(&scores, max_score) {
return Err(CompetitiveSelectionError::ScoreOutOfRange);
}
let inner = CompetitiveSelectionSoftCarrier::init(scores, weight_total, max_score);
Ok(Self { inner })
}
pub fn len(&self) -> usize {
self.inner.scores.len()
}
pub fn is_empty(&self) -> bool {
false
}
pub fn weight_total(&self) -> u64 {
self.inner.weight_total
}
pub fn max_score(&self) -> u64 {
self.inner.max_score
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the candidate index is in bounds")]
pub fn score(&self, candidate: usize) -> Option<u64> {
if candidate < self.inner.scores.len() {
Some(self.inner.scores[candidate])
} else {
None
}
}
pub fn weight(&self, candidate: usize) -> Option<u64> {
proof { use_type_invariant(&*self); }
if candidate < self.inner.extra.len() {
Some(self.inner.weight_at(candidate))
} else {
None
}
}
pub fn assigned_weight(&self) -> u64 {
proof { use_type_invariant(&*self); }
self.inner.assigned_weight()
}
pub fn is_complete(&self) -> bool {
self.assigned_weight() == self.inner.weight_total
}
pub fn assign_next(&mut self) -> (result: Result<usize, CompetitiveSelectionError>) {
proof { use_type_invariant(&*self); }
if self.inner.assigned_weight() >= self.inner.weight_total {
return Err(CompetitiveSelectionError::AllocationComplete);
}
let mut carrier = soft_selection_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
let winner = carrier.assign_next();
core::mem::swap(&mut self.inner, &mut carrier);
Ok(winner)
}
pub fn update_score(
&mut self,
candidate: usize,
score: u64,
) -> (result: Result<(), CompetitiveSelectionError>) {
proof { use_type_invariant(&*self); }
if candidate >= self.inner.scores.len() {
return Err(CompetitiveSelectionError::CandidateOutOfRange);
}
if score < 1 || score > self.inner.max_score {
return Err(CompetitiveSelectionError::ScoreOutOfRange);
}
let mut carrier = soft_selection_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.update_score(candidate, score);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
}
pub struct CompetitiveSelectionRanked {
inner: CompetitiveSelectionRankedCarrier,
}
impl CompetitiveSelectionRanked {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.inv()
}
pub fn new(
scores: Vec<u64>,
k: usize,
max_score: u64,
) -> (result: Result<Self, CompetitiveSelectionError>) {
if !values_within_max(&scores, max_score) {
return Err(CompetitiveSelectionError::ScoreOutOfRange);
}
let inner = CompetitiveSelectionRankedCarrier::new(scores, k, max_score);
Ok(Self { inner })
}
pub fn len(&self) -> usize {
self.inner.scores.len()
}
pub fn is_empty(&self) -> bool {
self.inner.scores.is_empty()
}
pub fn limit(&self) -> usize {
self.inner.k
}
pub fn max_score(&self) -> u64 {
self.inner.max_score
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the candidate index is in bounds")]
pub fn score(&self, candidate: usize) -> Option<u64> {
if candidate < self.inner.scores.len() {
Some(self.inner.scores[candidate])
} else {
None
}
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the candidate index is in bounds")]
pub fn is_selected(&self, candidate: usize) -> Option<bool> {
if candidate < self.inner.selected.len() {
Some(self.inner.selected[candidate])
} else {
None
}
}
pub fn select(&mut self) {
proof { use_type_invariant(&*self); }
let mut carrier = ranked_selection_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.select();
core::mem::swap(&mut self.inner, &mut carrier);
}
pub fn update_scores(
&mut self,
scores: Vec<u64>,
) -> (result: Result<(), CompetitiveSelectionError>) {
proof { use_type_invariant(&*self); }
if scores.len() != self.inner.scores.len() {
return Err(CompetitiveSelectionError::ScoreCountMismatch);
}
if !values_within_max(&scores, self.inner.max_score) {
return Err(CompetitiveSelectionError::ScoreOutOfRange);
}
let mut carrier = ranked_selection_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
carrier.update_scores(scores);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(())
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum ConvergenceBuildError {
ThresholdOutOfRange,
EmptyWindow,
WindowSumOutOfRange,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum ConvergenceError {
DeltaOutOfRange,
}
pub struct ConvergenceGovernor {
inner: ConvergenceGovernorCarrier,
}
impl ConvergenceGovernor {
#[verifier::type_invariant]
closed spec fn well_formed(&self) -> bool {
self.inner.inv()
}
pub fn new(
threshold: u64,
awaken_threshold: u64,
window: usize,
max_delta: u64,
) -> (result: Result<Self, ConvergenceBuildError>) {
if threshold > u64::MAX / 2 {
return Err(ConvergenceBuildError::ThresholdOutOfRange);
}
if window == 0 {
return Err(ConvergenceBuildError::EmptyWindow);
}
if window > 1_000_000_000 || max_delta > 1_000_000_000 {
return Err(ConvergenceBuildError::WindowSumOutOfRange);
}
proof {
assert(window as int * max_delta as int <= u64::MAX as int) by (nonlinear_arith)
requires
window <= 1_000_000_000,
max_delta <= 1_000_000_000,
u64::MAX >= 1_000_000_000 * 1_000_000_000;
}
let inner = ConvergenceGovernorCarrier::new(
threshold,
awaken_threshold,
window,
max_delta,
);
Ok(Self { inner })
}
pub fn threshold(&self) -> u64 {
self.inner.threshold
}
pub fn awaken_threshold(&self) -> u64 {
self.inner.awaken_threshold
}
pub fn window(&self) -> usize {
self.inner.window
}
pub fn max_delta(&self) -> u64 {
self.inner.max_delta
}
pub fn state(&self) -> ConvergenceState {
self.inner.state
}
pub fn phase(&self) -> ConvergencePhase {
self.inner.gradient_phase
}
pub fn peak_observed(&self) -> bool {
self.inner.peak_observed
}
pub fn history_len(&self) -> usize {
self.inner.delta_history.len()
}
#[expect(clippy::indexing_slicing, reason = "the branch proves the history index is in bounds")]
pub fn history(&self, index: usize) -> Option<u64> {
if index < self.inner.delta_history.len() {
Some(self.inner.delta_history[index])
} else {
None
}
}
pub fn update(&mut self, delta: u64) -> (result: Result<u64, ConvergenceError>) {
proof { use_type_invariant(&*self); }
if delta > self.inner.max_delta {
return Err(ConvergenceError::DeltaOutOfRange);
}
let mut carrier = convergence_sentinel();
core::mem::swap(&mut self.inner, &mut carrier);
let average = carrier.update(delta);
core::mem::swap(&mut self.inner, &mut carrier);
Ok(average)
}
}
fn budget_sentinel() -> (carrier: BudgetCarrier)
ensures carrier.safety_invariant(),
{
BudgetCarrier::new(0)
}
fn registry_sentinel() -> (carrier: RegistryCarrier<u64, u64>)
ensures carrier.unique_mapping(),
{
RegistryCarrier::new()
}
fn audit_sentinel() -> (carrier: AuditSinkCarrier)
ensures carrier.inv(),
{
AuditSinkCarrier::new(0)
}
fn propagation_sentinel() -> (carrier: PropagationPassCarrier)
ensures carrier.inv(),
{
let edges: Vec<(usize, usize)> = Vec::new();
let values: Vec<u64> = Vec::new();
PropagationPassCarrier::new(0, 0, 0, edges, values)
}
fn actuation_sentinel() -> (carrier: ActuationPassCarrier)
ensures carrier.invariant(),
{
let allocation: Vec<Option<u64>> = Vec::new();
ActuationPassCarrier::new(allocation, 0)
}
fn quality_hierarchy_sentinel() -> (carrier: QualityHierarchyCarrier)
ensures
carrier.type_invariant(),
carrier.strict_level_descent(),
carrier.parent_edge_agreement(),
carrier.cost_monotonicity(),
{
QualityHierarchyCarrier::new(0, 0)
}
fn backtracking_sentinel() -> (carrier: BacktrackingTraversalCarrier)
ensures carrier.inv(),
{
BacktrackingTraversalCarrier::new(0, 0, 0)
}
fn hard_selection_sentinel() -> (carrier: CompetitiveSelectionHardCarrier)
ensures
carrier.inv(),
carrier.scores.len() >= 1,
{
CompetitiveSelectionHardCarrier::new(1)
}
fn hard_exclusive_selection_sentinel() -> (carrier: CompetitiveSelectionHardExclusiveCarrier)
ensures carrier.inv(),
{
CompetitiveSelectionHardExclusiveCarrier::new(0, 1, 0)
}
fn soft_selection_sentinel() -> (carrier: CompetitiveSelectionSoftCarrier)
ensures carrier.mutable_score_inv(),
{
let mut scores: Vec<u64> = Vec::new();
scores.push(1);
CompetitiveSelectionSoftCarrier::init(scores, 1, 1)
}
fn ranked_selection_sentinel() -> (carrier: CompetitiveSelectionRankedCarrier)
ensures carrier.inv(),
{
let scores: Vec<u64> = Vec::new();
CompetitiveSelectionRankedCarrier::new(scores, 0, 0)
}
fn convergence_sentinel() -> (carrier: ConvergenceGovernorCarrier)
ensures carrier.inv(),
{
ConvergenceGovernorCarrier::new(0, 0, 1, 0)
}
#[expect(clippy::indexing_slicing, reason = "the loop proves the value index is in bounds")]
#[expect(clippy::arithmetic_side_effects, reason = "the loop proves the cursor remains within the vector")]
#[expect(clippy::ptr_arg, reason = "Verus sequence-view contracts are stated over Vec in this checked boundary")]
pub(crate) fn values_within_max(values: &Vec<u64>, max_value: u64) -> (valid: bool)
ensures
valid == (forall|i: int| 0 <= i < values.len() ==> values@[i] <= max_value),
{
let mut index: usize = 0;
while index < values.len()
invariant
index <= values.len(),
forall|i: int| 0 <= i < index ==> values@[i] <= max_value,
decreases values.len() - index,
{
if values[index] > max_value {
assert(!(forall|i: int| 0 <= i < values.len() ==> values@[i] <= max_value));
return false;
}
index += 1;
}
true
}
#[expect(clippy::indexing_slicing, reason = "the loop proves the value index is in bounds")]
#[expect(clippy::arithmetic_side_effects, reason = "the loop proves the cursor remains within the vector")]
#[expect(clippy::ptr_arg, reason = "Verus sequence-view contracts are stated over Vec in this checked boundary")]
fn positive_values_within_max(values: &Vec<u64>, max_value: u64) -> (valid: bool)
ensures
valid == (forall|i: int| 0 <= i < values.len()
==> 1 <= #[trigger] values@[i] <= max_value),
{
let mut index: usize = 0;
while index < values.len()
invariant
index <= values.len(),
forall|i: int| 0 <= i < index ==> 1 <= #[trigger] values@[i] <= max_value,
decreases values.len() - index,
{
if values[index] < 1 || values[index] > max_value {
assert(!(forall|i: int| 0 <= i < values.len()
==> 1 <= #[trigger] values@[i] <= max_value));
return false;
}
index += 1;
}
true
}
#[expect(clippy::indexing_slicing, reason = "the loop proves the edge index is in bounds")]
#[expect(clippy::arithmetic_side_effects, reason = "the loop proves the cursor remains within the vector")]
#[expect(clippy::ptr_arg, reason = "Verus sequence-view contracts are stated over Vec in this checked boundary")]
fn edges_within_nodes(edges: &Vec<(usize, usize)>, num_nodes: usize) -> (valid: bool)
ensures
valid == (forall|i: int| 0 <= i < edges.len()
==> edges@[i].0 < num_nodes && edges@[i].1 < num_nodes),
{
let mut index: usize = 0;
while index < edges.len()
invariant
index <= edges.len(),
forall|i: int| 0 <= i < index
==> edges@[i].0 < num_nodes && edges@[i].1 < num_nodes,
decreases edges.len() - index,
{
if edges[index].0 >= num_nodes || edges[index].1 >= num_nodes {
assert(!(forall|i: int| 0 <= i < edges.len()
==> edges@[i].0 < num_nodes && edges@[i].1 < num_nodes));
return false;
}
index += 1;
}
true
}
}
impl Budget {
pub fn is_empty(&self) -> bool {
self.allocated() == 0 && self.reserved() == 0 && self.pending_eviction() == 0
}
pub fn is_full(&self) -> bool {
self.available() == 0
}
}
impl ResourceRegistry {
pub fn contains_key(&self, key: u64) -> bool {
self.get(key).is_some()
}
pub fn iter(&self) -> impl ExactSizeIterator<Item = &(u64, u64)> {
self.inner.entries.iter()
}
}
impl AuditSink {
pub fn is_full(&self) -> bool {
self.len() == self.capacity()
}
pub fn records(&self) -> impl ExactSizeIterator<Item = AuditRecord> + '_ {
self.inner.log.iter().map(|entry| AuditRecord {
operation: entry.operation,
previous_hash: entry.prev_hash,
hash: entry.hash,
})
}
}
impl PropagationPass {
pub fn edges(&self) -> &[(usize, usize)] {
self.inner.edges.as_slice()
}
pub fn values(&self) -> &[u64] {
self.inner.values.as_slice()
}
pub fn snapshot_values(&self) -> &[u64] {
self.inner.snapshot.as_slice()
}
pub fn updated_nodes(&self) -> &[bool] {
self.inner.updated.as_slice()
}
}
impl ActuationPass {
pub fn allocations(&self) -> &[Option<u64>] {
self.inner.allocation.as_slice()
}
pub fn effects(&self) -> &[Option<u64>] {
self.inner.effects.as_slice()
}
}
impl QualityHierarchy {
pub fn levels(&self) -> &[u64] {
self.inner.level.as_slice()
}
pub fn costs(&self) -> &[u64] {
self.inner.cost.as_slice()
}
pub fn encoded_parents(&self) -> &[usize] {
self.inner.parent.as_slice()
}
pub fn edges(&self) -> &[(usize, usize)] {
self.inner.edges.as_slice()
}
pub fn has_children(&self, node: usize) -> Option<bool> {
(node < self.len()).then(|| self.inner.has_children(node))
}
pub fn has_edge(&self, parent: usize, child: usize) -> Option<bool> {
(parent < self.len() && child < self.len()).then(|| self.inner.has_edge(parent, child))
}
}
impl BacktrackingTraversal {
pub fn branch_factor(&self) -> u64 {
self.inner.branch_factor
}
pub fn initial_auxiliary(&self) -> u64 {
self.inner.init_aux
}
pub fn choices(&self) -> &[u64] {
self.inner.path.as_slice()
}
pub fn visited_paths(&self) -> impl ExactSizeIterator<Item = &[u64]> {
self.inner.visited.iter().map(Vec::as_slice)
}
}
impl CompetitiveSelectionHard {
pub fn scores(&self) -> &[u64] {
self.inner.scores.as_slice()
}
}
impl CompetitiveSelectionHardExclusive {
pub fn is_empty(&self) -> bool {
self.seat_count() == 0
}
pub fn allocations(&self) -> &[Option<u64>] {
self.inner.allocation.as_slice()
}
pub fn scores(&self, seat: usize) -> Option<&[u64]> {
self.inner.scores.get(seat).map(Vec::as_slice)
}
}
impl CompetitiveSelectionSoft {
pub fn scores(&self) -> &[u64] {
self.inner.scores.as_slice()
}
pub fn weights(&self) -> impl ExactSizeIterator<Item = u64> + '_ {
self.inner.extra.iter().map(|extra| extra + 1)
}
}
impl CompetitiveSelectionRanked {
pub fn scores(&self) -> &[u64] {
self.inner.scores.as_slice()
}
pub fn selections(&self) -> &[bool] {
self.inner.selected.as_slice()
}
pub fn selected_len(&self) -> usize {
self.inner
.selected
.iter()
.filter(|selected| **selected)
.count()
}
}
impl ConvergenceGovernor {
pub fn history_values(&self) -> &[u64] {
self.inner.delta_history.as_slice()
}
}
impl Default for ResourceRegistry {
fn default() -> Self {
Self::new()
}
}
impl_observational_debug!(Budget, "Budget",
"capacity" => capacity,
"allocated" => allocated,
"reserved" => reserved,
"pending_eviction" => pending_eviction,
"available" => available,
);
impl_observational_debug!(ResourceRegistry, "ResourceRegistry", "len" => len);
impl_observational_debug!(AuditSink, "AuditSink",
"capacity" => capacity,
"len" => len,
"last_hash" => last_hash,
"valid" => validate,
);
impl_observational_debug!(Cursor, "Cursor", "position" => position);
impl_observational_debug!(PropagationPass, "PropagationPass",
"num_nodes" => num_nodes,
"max_iterations" => max_iterations,
"iteration" => iteration,
"round" => round,
"changed" => changed,
);
impl_observational_debug!(ActuationPass, "ActuationPass",
"len" => len,
"complete" => is_complete,
"ready_to_finish" => ready_to_finish,
);
impl_observational_debug!(QualityHierarchy, "QualityHierarchy",
"len" => len,
"max_level" => max_level,
"edge_count" => edge_count,
);
impl_observational_debug!(BacktrackingTraversal, "BacktrackingTraversal",
"max_depth" => max_depth,
"depth" => depth,
"auxiliary" => auxiliary,
"visited_count" => visited_count,
"leaf" => is_leaf,
);
impl_observational_debug!(CompetitiveSelectionHard, "CompetitiveSelectionHard",
"len" => len,
"winner" => winner,
);
impl_observational_debug!(CompetitiveSelectionHardExclusive, "CompetitiveSelectionHardExclusive",
"seat_count" => seat_count,
"candidate_count" => candidate_count,
"max_score" => max_score,
);
impl_observational_debug!(CompetitiveSelectionSoft, "CompetitiveSelectionSoft",
"len" => len,
"weight_total" => weight_total,
"assigned_weight" => assigned_weight,
"max_score" => max_score,
"complete" => is_complete,
);
impl_observational_debug!(CompetitiveSelectionRanked, "CompetitiveSelectionRanked",
"len" => len,
"limit" => limit,
"max_score" => max_score,
);
impl_observational_debug!(ConvergenceGovernor, "ConvergenceGovernor",
"threshold" => threshold,
"awaken_threshold" => awaken_threshold,
"window" => window,
"max_delta" => max_delta,
"state" => state,
"phase" => phase,
"peak_observed" => peak_observed,
"history_len" => history_len,
);
impl_public_error!(BudgetError, {
Self::AmountExceedsReservation => "amount exceeds the held reservation",
Self::AmountExceedsAllocation => "amount exceeds the committed allocation",
Self::AmountExceedsPendingEviction => "amount exceeds pending eviction",
});
impl_public_error!(CursorError, {
Self::Regression => "cursor movement would regress the retained position",
});
impl_public_error!(PropagationBuildError, {
Self::InitialValueOutOfRange => "an initial value exceeds the declared value ceiling",
Self::EdgeEndpointOutOfRange => "an edge endpoint is outside the admitted node set",
});
impl_public_error!(PropagationError, {
Self::NodeOutOfRange => "node is outside the admitted graph",
Self::RoundAlreadyRunning => "a propagation round is already running",
Self::RoundNotRunning => "no propagation round is running",
Self::NodeAlreadyUpdated => "node already committed an update in this round",
Self::RoundIncomplete => "not every node committed an update",
Self::PassTerminated => "propagation pass is settled or exhausted",
Self::PassStillRunning => "propagation pass has not reached a terminal state",
});
impl_public_error!(ActuationError, {
Self::SeatOutOfRange => "seat is outside the admitted seat set",
Self::PassComplete => "actuation pass is already complete",
Self::SeatAlreadyAllocated => "seat already holds a resource",
Self::SeatUnallocated => "seat holds no resource",
Self::SeatAlreadyActuated => "seat already committed its effect",
Self::PassIncomplete => "an allocated seat has not committed its effect",
});
impl_public_error!(QualityHierarchyError, {
Self::NodeOutOfRange => "node is outside the admitted hierarchy",
Self::ParentOutOfRange => "parent is outside the admitted hierarchy",
Self::ChildOutOfRange => "child is outside the admitted hierarchy",
Self::LevelOutOfRange => "level exceeds the hierarchy ceiling",
Self::CostOutOfRange => "cost exceeds the hierarchy ceiling",
Self::NodeNotIsolated => "node properties may change only while the node is isolated",
Self::SelfEdge => "a hierarchy node cannot be its own child",
Self::EdgeAlreadyExists => "the parent-child edge already exists",
Self::ChildAlreadyParented => "the child already has a parent",
Self::LevelOrderViolation => "parent level must strictly exceed child level",
Self::CostOrderViolation => "parent cost must not exceed child cost",
});
impl_public_error!(BacktrackingBuildError, {
Self::InitialAuxOutOfRange => "initial auxiliary value is outside the modulo-three domain",
});
impl_public_error!(BacktrackingError, {
Self::AtLeaf => "descent is disabled at a leaf",
Self::ChoiceOutOfRange => "branch choice is outside the admitted branch set",
Self::DeltaOutOfRange => "mutation delta must be one or two",
Self::NotLeaf => "visit requires a full-depth leaf",
Self::AlreadyVisited => "the current leaf was already visited",
Self::AtRoot => "ascent is disabled at the root",
});
impl_public_error!(CompetitiveSelectionError, {
Self::NoCandidates => "at least one candidate is required",
Self::CandidateOutOfRange => "candidate is outside the admitted candidate set",
Self::SeatOutOfRange => "seat is outside the admitted seat set",
Self::SeatAlreadyAllocated => "seat already holds an allocation",
Self::NoCandidateAvailable => "no candidate is available for the seat",
Self::ScoreOutOfRange => "score is outside the admitted score domain",
Self::ScoreCountMismatch => "replacement scores have a different candidate count",
Self::WeightTotalBelowReservedFloor => "weight total is smaller than the reserved candidate floor",
Self::WeightTotalOutOfRange => "weight total exceeds the verified arithmetic ceiling",
Self::MaxScoreOutOfRange => "maximum score exceeds the verified arithmetic ceiling",
Self::AllocationComplete => "all soft-selection weight has been assigned",
});
impl_public_error!(ConvergenceBuildError, {
Self::ThresholdOutOfRange => "convergence threshold cannot be doubled safely",
Self::EmptyWindow => "convergence history window must be nonempty",
Self::WindowSumOutOfRange => "maximum convergence window sum exceeds u64",
});
impl_public_error!(ConvergenceError, {
Self::DeltaOutOfRange => "delta exceeds the configured maximum",
});