use dashmap::DashMap;
use midstreamer_attractor::{AttractorAnalyzer, PhasePoint};
use midstreamer_neural_solver::TemporalNeuralSolver;
use midstreamer_temporal_compare::TemporalComparator;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum StrangeLoopError {
#[error("Max meta-depth exceeded: {0}")]
MaxDepthExceeded(usize),
#[error("Safety constraint violated: {0}")]
SafetyViolation(String),
#[error("Invalid modification: {0}")]
InvalidModification(String),
#[error("Meta-learning failed: {0}")]
MetaLearningFailed(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct MetaLevel(pub usize);
impl MetaLevel {
pub fn base() -> Self {
MetaLevel(0)
}
pub fn next(&self) -> Self {
MetaLevel(self.0 + 1)
}
pub fn level(&self) -> usize {
self.0
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetaKnowledge {
pub level: MetaLevel,
pub pattern: String,
pub confidence: f64,
pub applications: Vec<String>,
pub learned_at: u64,
}
impl MetaKnowledge {
pub fn new(level: MetaLevel, pattern: String, confidence: f64) -> Self {
Self {
level,
pattern,
confidence,
applications: Vec::new(),
learned_at: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis() as u64,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SafetyConstraint {
pub name: String,
pub formula: String, pub enforced: bool,
}
impl SafetyConstraint {
pub fn new(name: impl Into<String>, formula: impl Into<String>) -> Self {
Self {
name: name.into(),
formula: formula.into(),
enforced: true,
}
}
pub fn always_safe() -> Self {
Self::new("always_safe", "G(safe)")
}
pub fn eventually_terminates() -> Self {
Self::new("eventually_terminates", "F(done)")
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModificationRule {
pub name: String,
pub trigger: String,
pub action: String,
pub safety_check: bool,
}
impl ModificationRule {
pub fn new(
name: impl Into<String>,
trigger: impl Into<String>,
action: impl Into<String>,
) -> Self {
Self {
name: name.into(),
trigger: trigger.into(),
action: action.into(),
safety_check: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetaLearningSummary {
pub total_levels: usize,
pub total_knowledge: usize,
pub total_modifications: usize,
pub safety_violations: usize,
pub learning_iterations: u64,
}
#[derive(Debug, Clone)]
pub struct StrangeLoopConfig {
pub max_meta_depth: usize,
pub enable_self_modification: bool,
pub max_modifications_per_cycle: usize,
pub safety_check_enabled: bool,
}
impl Default for StrangeLoopConfig {
fn default() -> Self {
Self {
max_meta_depth: 3,
enable_self_modification: false, max_modifications_per_cycle: 5,
safety_check_enabled: true,
}
}
}
pub struct StrangeLoop {
config: StrangeLoopConfig,
meta_knowledge: Arc<DashMap<MetaLevel, Vec<MetaKnowledge>>>,
safety_constraints: Vec<SafetyConstraint>,
modification_rules: Vec<ModificationRule>,
learning_iterations: Arc<DashMap<MetaLevel, u64>>,
modification_count: usize,
safety_violations: usize,
#[allow(dead_code)]
temporal_comparator: TemporalComparator<String>,
attractor_analyzer: AttractorAnalyzer,
#[allow(dead_code)]
temporal_solver: TemporalNeuralSolver,
}
impl StrangeLoop {
pub fn new(config: StrangeLoopConfig) -> Self {
Self {
config,
meta_knowledge: Arc::new(DashMap::new()),
safety_constraints: vec![
SafetyConstraint::always_safe(),
SafetyConstraint::eventually_terminates(),
],
modification_rules: Vec::new(),
learning_iterations: Arc::new(DashMap::new()),
modification_count: 0,
safety_violations: 0,
temporal_comparator: TemporalComparator::new(1000, 10000),
attractor_analyzer: AttractorAnalyzer::new(3, 10000),
temporal_solver: TemporalNeuralSolver::default(),
}
}
pub fn learn_at_level(
&mut self,
level: MetaLevel,
data: &[String],
) -> Result<Vec<MetaKnowledge>, StrangeLoopError> {
if level.level() > self.config.max_meta_depth {
return Err(StrangeLoopError::MaxDepthExceeded(level.level()));
}
self.learning_iterations
.entry(level)
.and_modify(|v| *v += 1)
.or_insert(1);
let patterns = self.extract_patterns(level, data)?;
self.meta_knowledge
.entry(level)
.or_default()
.extend(patterns.clone());
if level.level() < self.config.max_meta_depth {
self.meta_learn_from_level(level)?;
}
Ok(patterns)
}
fn meta_learn_from_level(&mut self, level: MetaLevel) -> Result<(), StrangeLoopError> {
let knowledge = if let Some(k) = self.meta_knowledge.get(&level) {
k.clone()
} else {
return Ok(()); };
let meta_patterns: Vec<String> = knowledge.iter().map(|k| k.pattern.clone()).collect();
let next_level = level.next();
let _meta_knowledge = self.learn_at_level(next_level, &meta_patterns)?;
Ok(())
}
fn extract_patterns(
&self,
level: MetaLevel,
data: &[String],
) -> Result<Vec<MetaKnowledge>, StrangeLoopError> {
let mut patterns = Vec::new();
for i in 0..data.len() {
for j in i + 1..data.len() {
if data[i] == data[j] {
let pattern = MetaKnowledge::new(
level,
data[i].clone(),
0.8, );
patterns.push(pattern);
}
}
}
patterns.truncate(100);
Ok(patterns)
}
pub fn apply_modification(&mut self, rule: ModificationRule) -> Result<(), StrangeLoopError> {
if !self.config.enable_self_modification {
return Err(StrangeLoopError::InvalidModification(
"Self-modification is disabled".to_string(),
));
}
if self.modification_count >= self.config.max_modifications_per_cycle {
return Err(StrangeLoopError::InvalidModification(
"Max modifications per cycle reached".to_string(),
));
}
if rule.safety_check && self.config.safety_check_enabled {
self.check_safety_constraints()?;
}
self.modification_rules.push(rule);
self.modification_count += 1;
Ok(())
}
fn check_safety_constraints(&mut self) -> Result<(), StrangeLoopError> {
for constraint in &self.safety_constraints {
if constraint.enforced {
if constraint.formula.contains("safe") {
continue;
}
}
}
Ok(())
}
pub fn add_safety_constraint(&mut self, constraint: SafetyConstraint) {
self.safety_constraints.push(constraint);
}
pub fn get_knowledge_at_level(&self, level: MetaLevel) -> Vec<MetaKnowledge> {
self.meta_knowledge
.get(&level)
.map(|k| k.clone())
.unwrap_or_default()
}
pub fn get_all_knowledge(&self) -> HashMap<MetaLevel, Vec<MetaKnowledge>> {
let mut result = HashMap::new();
for entry in self.meta_knowledge.iter() {
result.insert(*entry.key(), entry.value().clone());
}
result
}
pub fn get_summary(&self) -> MetaLearningSummary {
let total_knowledge: usize = self
.meta_knowledge
.iter()
.map(|entry| entry.value().len())
.sum();
MetaLearningSummary {
total_levels: self.meta_knowledge.len(),
total_knowledge,
total_modifications: self.modification_count,
safety_violations: self.safety_violations,
learning_iterations: self
.learning_iterations
.iter()
.map(|entry| *entry.value())
.sum(),
}
}
pub fn reset(&mut self) {
self.meta_knowledge.clear();
self.learning_iterations.clear();
self.modification_rules.clear();
self.modification_count = 0;
self.safety_violations = 0;
}
pub fn analyze_behavior(
&mut self,
trajectory_data: Vec<Vec<f64>>,
) -> Result<String, StrangeLoopError> {
for (i, point_data) in trajectory_data.iter().enumerate() {
let point = PhasePoint::new(point_data.clone(), i as u64);
self.attractor_analyzer
.add_point(point)
.map_err(|e| StrangeLoopError::MetaLearningFailed(e.to_string()))?;
}
let analysis = self
.attractor_analyzer
.analyze()
.map_err(|e| StrangeLoopError::MetaLearningFailed(e.to_string()))?;
Ok(format!("{:?}", analysis.attractor_type))
}
}
impl Default for StrangeLoop {
fn default() -> Self {
Self::new(StrangeLoopConfig::default())
}
}
pub trait MetaLearner {
fn learn(&mut self, data: &[String]) -> Result<Vec<MetaKnowledge>, StrangeLoopError>;
fn meta_level(&self) -> MetaLevel;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_meta_level() {
let base = MetaLevel::base();
assert_eq!(base.level(), 0);
let next = base.next();
assert_eq!(next.level(), 1);
}
#[test]
fn test_strange_loop_creation() {
let config = StrangeLoopConfig::default();
let strange_loop = StrangeLoop::new(config);
assert_eq!(strange_loop.modification_count, 0);
assert_eq!(strange_loop.safety_violations, 0);
}
#[test]
fn test_learning_at_level() {
let mut strange_loop = StrangeLoop::default();
let data = vec![
"pattern1".to_string(),
"pattern2".to_string(),
"pattern1".to_string(),
];
let result = strange_loop.learn_at_level(MetaLevel::base(), &data);
assert!(result.is_ok());
let knowledge = strange_loop.get_knowledge_at_level(MetaLevel::base());
assert!(!knowledge.is_empty());
}
#[test]
fn test_max_depth_exceeded() {
let mut strange_loop = StrangeLoop::default();
let data = vec!["test".to_string()];
let deep_level = MetaLevel(10);
let result = strange_loop.learn_at_level(deep_level, &data);
assert!(result.is_err());
}
#[test]
fn test_safety_constraint() {
let constraint = SafetyConstraint::always_safe();
assert_eq!(constraint.name, "always_safe");
assert!(constraint.enforced);
}
#[test]
fn test_modification_disabled() {
let mut strange_loop = StrangeLoop::default();
let rule = ModificationRule::new("test_rule", "trigger", "action");
let result = strange_loop.apply_modification(rule);
assert!(result.is_err()); }
#[test]
fn test_summary() {
let mut strange_loop = StrangeLoop::default();
let data = vec!["pattern1".to_string(), "pattern2".to_string()];
let _ = strange_loop.learn_at_level(MetaLevel::base(), &data);
let summary = strange_loop.get_summary();
assert!(summary.total_knowledge > 0);
assert_eq!(summary.safety_violations, 0);
}
#[test]
fn test_reset() {
let mut strange_loop = StrangeLoop::default();
let data = vec!["pattern1".to_string()];
let _ = strange_loop.learn_at_level(MetaLevel::base(), &data);
strange_loop.reset();
let summary = strange_loop.get_summary();
assert_eq!(summary.total_knowledge, 0);
assert_eq!(summary.total_modifications, 0);
}
}