use std::collections::BTreeSet;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ContractId(pub u64);
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Claim {
Associative,
Commutative,
Distributive,
HasIdentity,
HasInverse,
Exact,
Approximate,
Deterministic,
Local,
CoverPreserving,
RestrictionCompatible,
Gluable,
NonArchimedeanNorm,
ValuationIdentity(String),
PrecisionPreserved,
PrecisionLossBounded(u32),
BackendSemantic(String),
FiniteFieldSpec {
prime: u64,
extension_degree: usize,
},
Custom(String),
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Scope {
Domain(String),
Object(String),
Operator(String),
Rewrite(String),
Backend(String),
Global,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Evidence {
Axiom,
Derived,
Checked,
Tested,
ExternalProof(String),
UnsafeAssumption,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Condition {
pub description: String,
}
impl Condition {
pub fn new(description: impl Into<String>) -> Self {
Self {
description: description.into(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Contract {
pub id: ContractId,
pub claim: Claim,
pub scope: Scope,
pub evidence: Evidence,
pub conditions: Vec<Condition>,
}
impl Contract {
pub fn new(id: ContractId, claim: Claim, scope: Scope, evidence: Evidence) -> Self {
Self {
id,
claim,
scope,
evidence,
conditions: Vec::new(),
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct ContractSet {
contracts: BTreeSet<Contract>,
}
impl ContractSet {
pub fn new() -> Self {
Self::default()
}
pub fn from_iter(contracts: impl IntoIterator<Item = Contract>) -> Self {
Self {
contracts: contracts.into_iter().collect(),
}
}
pub fn insert(&mut self, contract: Contract) {
self.contracts.insert(contract);
}
pub fn contains_claim(&self, claim: &Claim) -> bool {
self.contracts
.iter()
.any(|contract| &contract.claim == claim)
}
pub fn iter(&self) -> impl Iterator<Item = &Contract> {
self.contracts.iter()
}
pub fn extend(&mut self, other: ContractSet) {
self.contracts.extend(other.contracts);
}
pub fn is_empty(&self) -> bool {
self.contracts.is_empty()
}
}