pub mod circadian;
pub mod coherence;
pub mod predictive;
pub mod workspace;
pub use circadian::{
BudgetGuardrail, CircadianController, CircadianPhase, CircadianScheduler, HysteresisTracker,
NervousSystemMetrics, NervousSystemScorecard, PhaseModulation, ScorecardTargets,
};
pub use coherence::OscillatoryRouter;
pub use predictive::PredictiveLayer;
pub use workspace::{GlobalWorkspace, Representation};
#[derive(Debug, Clone)]
pub struct CoherenceGatedSystem {
router: OscillatoryRouter,
workspace: GlobalWorkspace,
predictive: Vec<PredictiveLayer>,
}
impl CoherenceGatedSystem {
pub fn new(
num_modules: usize,
vector_dim: usize,
gamma_frequency: f32,
workspace_capacity: usize,
) -> Self {
Self {
router: OscillatoryRouter::new(num_modules, gamma_frequency),
workspace: GlobalWorkspace::new(workspace_capacity),
predictive: (0..num_modules)
.map(|_| PredictiveLayer::new(vector_dim, 0.2))
.collect(),
}
}
pub fn step_oscillators(&mut self, dt: f32) {
self.router.step(dt);
}
pub fn route_with_coherence(
&mut self,
message: &[f32],
sender: usize,
receivers: &[usize],
dt: f32,
) -> Vec<(usize, Vec<f32>)> {
self.step_oscillators(dt);
if sender >= self.predictive.len() {
return Vec::new();
}
let residual = match self.predictive[sender].residual_gated_write(message) {
Some(res) => res,
None => return Vec::new(), };
let routed = self.router.route(&residual, sender, receivers);
for (receiver, weighted_msg) in &routed {
let gain = self.router.communication_gain(sender, *receiver);
if gain > 0.7 {
let salience = gain;
let rep = Representation::new(
weighted_msg.clone(),
salience,
sender as u16,
0, );
self.workspace.broadcast(rep);
}
}
routed
}
pub fn phases(&self) -> &[f32] {
self.router.phases()
}
pub fn workspace_contents(&self) -> Vec<Representation> {
self.workspace.retrieve()
}
pub fn compete_workspace(&mut self) {
self.workspace.compete();
}
pub fn synchronization(&self) -> f32 {
self.router.order_parameter()
}
pub fn workspace_occupancy(&self) -> f32 {
self.workspace.len() as f32 / self.workspace.capacity() as f32
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_integrated_system() {
let mut system = CoherenceGatedSystem::new(
5, 128, 40.0, 7, );
assert_eq!(system.phases().len(), 5);
assert_eq!(system.workspace_contents().len(), 0);
}
#[test]
fn test_route_with_coherence() {
let mut system = CoherenceGatedSystem::new(3, 16, 40.0, 5);
for _ in 0..1000 {
system.step_oscillators(0.001);
}
let message = vec![1.0; 16];
let receivers = vec![1, 2];
let routed = system.route_with_coherence(&message, 0, &receivers, 0.001);
assert!(!routed.is_empty());
}
#[test]
fn test_predictive_suppression() {
let mut system = CoherenceGatedSystem::new(2, 16, 40.0, 5);
let stable_message = vec![1.0; 16];
let receivers = vec![1];
let first = system.route_with_coherence(&stable_message, 0, &receivers, 0.001);
assert!(!first.is_empty());
for _ in 0..50 {
system.route_with_coherence(&stable_message, 0, &receivers, 0.001);
}
let mut suppressed_count = 0;
for _ in 0..20 {
let result = system.route_with_coherence(&stable_message, 0, &receivers, 0.001);
if result.is_empty() {
suppressed_count += 1;
}
}
assert!(suppressed_count > 10, "Should suppress predictable signals");
}
#[test]
fn test_workspace_integration() {
let mut system = CoherenceGatedSystem::new(3, 8, 40.0, 3);
for _ in 0..2000 {
system.step_oscillators(0.001);
}
let message = vec![1.0; 8];
let receivers = vec![1, 2];
system.route_with_coherence(&message, 0, &receivers, 0.001);
let workspace_items = system.workspace_contents();
assert!(!workspace_items.is_empty(), "Workspace should have items");
}
#[test]
fn test_synchronization_metric() {
let mut system = CoherenceGatedSystem::new(10, 16, 40.0, 7);
let initial_sync = system.synchronization();
for _ in 0..5000 {
system.step_oscillators(0.001);
}
let final_sync = system.synchronization();
assert!(
final_sync >= 0.0 && final_sync <= 1.0,
"Synchronization should be in valid range: {}",
final_sync
);
assert!(
initial_sync >= 0.0 && initial_sync <= 1.0,
"Initial sync should be valid: {}",
initial_sync
);
}
#[test]
fn test_workspace_occupancy() {
let mut system = CoherenceGatedSystem::new(3, 8, 40.0, 4);
assert_eq!(system.workspace_occupancy(), 0.0);
for i in 0..3 {
let rep = Representation::new(vec![1.0; 8], 0.8, i as u16, 0);
system.workspace.broadcast(rep);
}
assert_eq!(system.workspace_occupancy(), 0.75); }
#[test]
fn test_workspace_competition() {
let mut system = CoherenceGatedSystem::new(2, 8, 40.0, 3);
let rep = Representation::new(vec![1.0; 8], 0.3, 0_u16, 0);
system.workspace.broadcast(rep);
system.compete_workspace();
let contents = system.workspace_contents();
if !contents.is_empty() {
assert!(contents[0].salience < 0.3, "Salience should decay");
}
}
#[test]
fn test_end_to_end_routing() {
let mut system = CoherenceGatedSystem::new(4, 32, 40.0, 5);
for _ in 0..1000 {
system.step_oscillators(0.0001);
}
let mut routed_count = 0;
for i in 0..100 {
let signal_strength = (i as f32 * 0.1).sin();
let message: Vec<f32> = (0..32).map(|_| signal_strength).collect();
let receivers = vec![1, 2, 3];
let routed = system.route_with_coherence(&message, 0, &receivers, 0.0001);
if !routed.is_empty() {
routed_count += 1;
}
}
assert!(
routed_count > 0,
"Should have at least some successful routes, got {}",
routed_count
);
system.compete_workspace();
assert!(system.workspace_occupancy() <= 1.0);
}
#[test]
fn test_performance_integrated() {
let mut system = CoherenceGatedSystem::new(50, 128, 40.0, 7);
let message = vec![1.0; 128];
let receivers: Vec<usize> = (1..50).collect();
let start = std::time::Instant::now();
for _ in 0..100 {
system.route_with_coherence(&message, 0, &receivers, 0.001);
}
let elapsed = start.elapsed();
let avg_route = elapsed.as_micros() / 100;
println!("Average route time: {}μs (50 modules, 128-dim)", avg_route);
assert!(avg_route < 1000, "Routing should be fast");
}
}