#![warn(missing_docs)]
#![warn(clippy::all)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(not(feature = "std"))]
extern crate alloc;
pub use coherence::{Coherence, CoherenceBounds, CoherenceState};
pub use transition::{Transition, TransitionConstraint, TransitionResult};
pub use attractor::{Attractor, AttractorBasin, GuidanceForce};
pub use enforcement::{DeltaEnforcer, EnforcementResult};
pub mod wasm;
pub mod simd_utils;
pub mod applications;
pub trait DeltaSystem {
type State: Clone;
type Transition;
type Error;
fn coherence(&self) -> Coherence;
fn step(&mut self, transition: &Self::Transition) -> Result<(), Self::Error>;
fn predict_coherence(&self, transition: &Self::Transition) -> Coherence;
fn state(&self) -> &Self::State;
fn in_attractor(&self) -> bool;
}
#[derive(Debug, Clone)]
pub struct DeltaConfig {
pub bounds: CoherenceBounds,
pub energy: EnergyConfig,
pub scheduling: SchedulingConfig,
pub gating: GatingConfig,
pub guidance_strength: f64,
}
impl Default for DeltaConfig {
fn default() -> Self {
Self {
bounds: CoherenceBounds::default(),
energy: EnergyConfig::default(),
scheduling: SchedulingConfig::default(),
gating: GatingConfig::default(),
guidance_strength: 0.5,
}
}
}
impl DeltaConfig {
pub fn strict() -> Self {
Self {
bounds: CoherenceBounds {
min_coherence: Coherence::clamped(0.5),
throttle_threshold: Coherence::clamped(0.7),
target_coherence: Coherence::clamped(0.9),
max_delta_drop: 0.05,
},
guidance_strength: 0.8,
..Default::default()
}
}
pub fn relaxed() -> Self {
Self {
bounds: CoherenceBounds {
min_coherence: Coherence::clamped(0.2),
throttle_threshold: Coherence::clamped(0.4),
target_coherence: Coherence::clamped(0.7),
max_delta_drop: 0.15,
},
guidance_strength: 0.3,
..Default::default()
}
}
}
#[derive(Debug, Clone)]
pub struct EnergyConfig {
pub base_cost: f64,
pub instability_exponent: f64,
pub max_cost: f64,
pub budget_per_tick: f64,
}
impl Default for EnergyConfig {
fn default() -> Self {
Self {
base_cost: 1.0,
instability_exponent: 2.0,
max_cost: 100.0,
budget_per_tick: 10.0,
}
}
}
#[derive(Debug, Clone)]
pub struct SchedulingConfig {
pub priority_thresholds: [f64; 5],
pub rate_limits: [usize; 5],
}
impl Default for SchedulingConfig {
fn default() -> Self {
Self {
priority_thresholds: [0.0, 0.3, 0.5, 0.7, 0.9],
rate_limits: [100, 50, 20, 10, 5],
}
}
}
#[derive(Debug, Clone)]
pub struct GatingConfig {
pub min_write_coherence: f64,
pub min_post_write_coherence: f64,
pub recovery_margin: f64,
}
impl Default for GatingConfig {
fn default() -> Self {
Self {
min_write_coherence: 0.3,
min_post_write_coherence: 0.25,
recovery_margin: 0.2,
}
}
}
pub mod coherence {
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct Coherence(f64);
impl Coherence {
pub fn new(value: f64) -> Result<Self, &'static str> {
if !(0.0..=1.0).contains(&value) {
Err("Coherence must be between 0.0 and 1.0")
} else {
Ok(Self(value))
}
}
pub fn clamped(value: f64) -> Self {
Self(value.clamp(0.0, 1.0))
}
pub fn maximum() -> Self {
Self(1.0)
}
pub fn minimum() -> Self {
Self(0.0)
}
pub fn value(&self) -> f64 {
self.0
}
pub fn is_above(&self, threshold: f64) -> bool {
self.0 >= threshold
}
pub fn is_below(&self, threshold: f64) -> bool {
self.0 < threshold
}
pub fn drop_from(&self, other: &Coherence) -> f64 {
(other.0 - self.0).max(0.0)
}
}
#[derive(Debug, Clone)]
pub struct CoherenceBounds {
pub min_coherence: Coherence,
pub throttle_threshold: Coherence,
pub target_coherence: Coherence,
pub max_delta_drop: f64,
}
impl Default for CoherenceBounds {
fn default() -> Self {
Self {
min_coherence: Coherence(0.3),
throttle_threshold: Coherence(0.5),
target_coherence: Coherence(0.8),
max_delta_drop: 0.1,
}
}
}
#[derive(Debug, Clone)]
pub struct CoherenceState {
pub current: Coherence,
pub history: Vec<Coherence>,
pub trend: f64,
}
impl CoherenceState {
pub fn new(initial: Coherence) -> Self {
Self {
current: initial,
history: vec![initial],
trend: 0.0,
}
}
pub fn update(&mut self, new_coherence: Coherence) {
let old = self.current.value();
self.current = new_coherence;
self.history.push(new_coherence);
if self.history.len() > 100 {
self.history.remove(0);
}
let delta = new_coherence.value() - old;
self.trend = self.trend * 0.9 + delta * 0.1;
}
pub fn is_declining(&self) -> bool {
self.trend < -0.01
}
pub fn is_improving(&self) -> bool {
self.trend > 0.01
}
}
}
pub mod transition {
use super::coherence::Coherence;
#[derive(Debug, Clone)]
pub struct Transition<T> {
pub data: T,
pub priority: u8,
pub estimated_impact: f64,
}
#[derive(Debug, Clone)]
pub struct TransitionConstraint {
pub name: String,
pub max_coherence_drop: f64,
pub min_required_coherence: Coherence,
}
impl Default for TransitionConstraint {
fn default() -> Self {
Self {
name: "default".to_string(),
max_coherence_drop: 0.1,
min_required_coherence: Coherence::clamped(0.3),
}
}
}
#[derive(Debug, Clone)]
pub enum TransitionResult<T, E> {
Applied {
result: T,
coherence_delta: f64,
},
Blocked {
reason: E,
},
Throttled {
delay_ms: u64,
},
Modified {
result: T,
modifications: String,
},
}
}
pub mod attractor {
#[derive(Debug, Clone)]
pub struct Attractor<S> {
pub state: S,
pub strength: f64,
pub radius: f64,
}
#[derive(Debug, Clone)]
pub struct AttractorBasin<S> {
pub attractor: Attractor<S>,
pub distance: f64,
pub inside: bool,
}
#[derive(Debug, Clone)]
pub struct GuidanceForce {
pub direction: Vec<f64>,
pub magnitude: f64,
}
impl GuidanceForce {
pub fn zero(dimensions: usize) -> Self {
Self {
direction: vec![0.0; dimensions],
magnitude: 0.0,
}
}
pub fn toward(from: &[f64], to: &[f64], strength: f64) -> Self {
let direction: Vec<f64> = from
.iter()
.zip(to.iter())
.map(|(a, b)| b - a)
.collect();
let magnitude: f64 = direction.iter().map(|x| x * x).sum::<f64>().sqrt();
if magnitude < 0.0001 {
return Self::zero(from.len());
}
let normalized: Vec<f64> = direction.iter().map(|x| x / magnitude).collect();
Self {
direction: normalized,
magnitude: magnitude * strength,
}
}
}
}
pub mod enforcement {
use super::coherence::Coherence;
use super::DeltaConfig;
use core::time::Duration;
pub struct DeltaEnforcer {
config: DeltaConfig,
energy_budget: f64,
in_recovery: bool,
}
impl DeltaEnforcer {
pub fn new(config: DeltaConfig) -> Self {
Self {
energy_budget: config.energy.budget_per_tick * 10.0,
config,
in_recovery: false,
}
}
pub fn check(
&mut self,
current: Coherence,
predicted: Coherence,
) -> EnforcementResult {
if self.in_recovery {
let recovery_target = self.config.bounds.min_coherence.value()
+ self.config.gating.recovery_margin;
if current.value() < recovery_target {
return EnforcementResult::Blocked(
"In recovery mode - waiting for coherence to improve".to_string()
);
}
self.in_recovery = false;
}
if predicted.value() < self.config.bounds.min_coherence.value() {
self.in_recovery = true;
return EnforcementResult::Blocked(format!(
"Would drop coherence to {:.3} (min: {:.3})",
predicted.value(),
self.config.bounds.min_coherence.value()
));
}
let drop = predicted.drop_from(¤t);
if drop > self.config.bounds.max_delta_drop {
return EnforcementResult::Blocked(format!(
"Coherence drop {:.3} exceeds max {:.3}",
drop, self.config.bounds.max_delta_drop
));
}
if predicted.value() < self.config.bounds.throttle_threshold.value() {
return EnforcementResult::Throttled(Duration::from_millis(100));
}
let cost = self.calculate_cost(current, predicted);
if cost > self.energy_budget {
return EnforcementResult::Blocked("Energy budget exhausted".to_string());
}
self.energy_budget -= cost;
EnforcementResult::Allowed
}
fn calculate_cost(&self, current: Coherence, predicted: Coherence) -> f64 {
let drop = (current.value() - predicted.value()).max(0.0);
let instability_factor = (1.0_f64 / predicted.value().max(0.1))
.powf(self.config.energy.instability_exponent);
(self.config.energy.base_cost + drop * 10.0 * instability_factor)
.min(self.config.energy.max_cost)
}
pub fn tick(&mut self) {
self.energy_budget = (self.energy_budget + self.config.energy.budget_per_tick)
.min(self.config.energy.budget_per_tick * 20.0);
}
}
#[derive(Debug, Clone)]
pub enum EnforcementResult {
Allowed,
Blocked(String),
Throttled(Duration),
}
impl EnforcementResult {
pub fn is_allowed(&self) -> bool {
matches!(self, EnforcementResult::Allowed)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
struct TestSystem {
state: f64,
coherence: Coherence,
}
impl TestSystem {
fn new() -> Self {
Self {
state: 0.0,
coherence: Coherence::maximum(),
}
}
}
impl DeltaSystem for TestSystem {
type State = f64;
type Transition = f64;
type Error = &'static str;
fn coherence(&self) -> Coherence {
self.coherence
}
fn step(&mut self, delta: &f64) -> Result<(), Self::Error> {
let predicted = self.predict_coherence(delta);
if predicted.value() < 0.3 {
return Err("Would violate coherence bound");
}
self.state += delta;
self.coherence = predicted;
Ok(())
}
fn predict_coherence(&self, delta: &f64) -> Coherence {
let impact = delta.abs() * 0.1;
Coherence::clamped(self.coherence.value() - impact)
}
fn state(&self) -> &f64 {
&self.state
}
fn in_attractor(&self) -> bool {
self.state.abs() < 0.1
}
}
#[test]
fn test_coherence_bounds() {
let c = Coherence::new(0.5).unwrap();
assert_eq!(c.value(), 0.5);
assert!(c.is_above(0.4));
assert!(c.is_below(0.6));
}
#[test]
fn test_coherence_clamping() {
let c = Coherence::clamped(1.5);
assert_eq!(c.value(), 1.0);
let c = Coherence::clamped(-0.5);
assert_eq!(c.value(), 0.0);
}
#[test]
fn test_delta_system() {
let mut system = TestSystem::new();
assert!(system.step(&0.1).is_ok());
assert!(system.coherence().value() > 0.9);
assert!(system.step(&10.0).is_err());
}
#[test]
fn test_enforcer() {
let config = DeltaConfig::default();
let mut enforcer = enforcement::DeltaEnforcer::new(config);
let current = Coherence::new(0.8).unwrap();
let good_prediction = Coherence::new(0.75).unwrap();
let bad_prediction = Coherence::new(0.2).unwrap();
assert!(enforcer.check(current, good_prediction).is_allowed());
assert!(!enforcer.check(current, bad_prediction).is_allowed());
}
#[test]
fn test_config_presets() {
let strict = DeltaConfig::strict();
let relaxed = DeltaConfig::relaxed();
assert!(strict.bounds.min_coherence.value() > relaxed.bounds.min_coherence.value());
assert!(strict.guidance_strength > relaxed.guidance_strength);
}
}