midstreamer_strange_loop/
lib.rs

1//! # Strange-Loop
2//!
3//! Self-referential systems and meta-learning inspired by Douglas Hofstadter.
4//!
5//! ## Features
6//! - Multi-level meta-learning
7//! - Self-modification with safety constraints
8//! - Recursive cognition
9//! - Tangled hierarchies
10//! - Meta-knowledge extraction
11
12use serde::{Deserialize, Serialize};
13use std::collections::HashMap;
14use thiserror::Error;
15use dashmap::DashMap;
16use std::sync::Arc;
17use midstreamer_temporal_compare::TemporalComparator;
18use midstreamer_attractor::{AttractorAnalyzer, PhasePoint};
19use midstreamer_neural_solver::TemporalNeuralSolver;
20
21/// Strange loop errors
22#[derive(Debug, Error)]
23pub enum StrangeLoopError {
24    #[error("Max meta-depth exceeded: {0}")]
25    MaxDepthExceeded(usize),
26
27    #[error("Safety constraint violated: {0}")]
28    SafetyViolation(String),
29
30    #[error("Invalid modification: {0}")]
31    InvalidModification(String),
32
33    #[error("Meta-learning failed: {0}")]
34    MetaLearningFailed(String),
35}
36
37/// Meta-level in the learning hierarchy
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
39pub struct MetaLevel(pub usize);
40
41impl MetaLevel {
42    pub fn base() -> Self {
43        MetaLevel(0)
44    }
45
46    pub fn next(&self) -> Self {
47        MetaLevel(self.0 + 1)
48    }
49
50    pub fn level(&self) -> usize {
51        self.0
52    }
53}
54
55/// Meta-knowledge extracted from lower levels
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct MetaKnowledge {
58    pub level: MetaLevel,
59    pub pattern: String,
60    pub confidence: f64,
61    pub applications: Vec<String>,
62    pub learned_at: u64,
63}
64
65impl MetaKnowledge {
66    pub fn new(level: MetaLevel, pattern: String, confidence: f64) -> Self {
67        Self {
68            level,
69            pattern,
70            confidence,
71            applications: Vec::new(),
72            learned_at: std::time::SystemTime::now()
73                .duration_since(std::time::UNIX_EPOCH)
74                .unwrap()
75                .as_millis() as u64,
76        }
77    }
78}
79
80/// Safety constraint for self-modification
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct SafetyConstraint {
83    pub name: String,
84    pub formula: String, // Simplified temporal formula
85    pub enforced: bool,
86}
87
88impl SafetyConstraint {
89    pub fn new(name: impl Into<String>, formula: impl Into<String>) -> Self {
90        Self {
91            name: name.into(),
92            formula: formula.into(),
93            enforced: true,
94        }
95    }
96
97    pub fn always_safe() -> Self {
98        Self::new("always_safe", "G(safe)")
99    }
100
101    pub fn eventually_terminates() -> Self {
102        Self::new("eventually_terminates", "F(done)")
103    }
104}
105
106/// Modification rule for self-improvement
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct ModificationRule {
109    pub name: String,
110    pub trigger: String,
111    pub action: String,
112    pub safety_check: bool,
113}
114
115impl ModificationRule {
116    pub fn new(
117        name: impl Into<String>,
118        trigger: impl Into<String>,
119        action: impl Into<String>,
120    ) -> Self {
121        Self {
122            name: name.into(),
123            trigger: trigger.into(),
124            action: action.into(),
125            safety_check: true,
126        }
127    }
128}
129
130/// Statistics about meta-learning performance
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct MetaLearningSummary {
133    pub total_levels: usize,
134    pub total_knowledge: usize,
135    pub total_modifications: usize,
136    pub safety_violations: usize,
137    pub learning_iterations: u64,
138}
139
140/// Configuration for strange loop
141#[derive(Debug, Clone)]
142pub struct StrangeLoopConfig {
143    pub max_meta_depth: usize,
144    pub enable_self_modification: bool,
145    pub max_modifications_per_cycle: usize,
146    pub safety_check_enabled: bool,
147}
148
149impl Default for StrangeLoopConfig {
150    fn default() -> Self {
151        Self {
152            max_meta_depth: 3,
153            enable_self_modification: false, // Disabled by default for safety
154            max_modifications_per_cycle: 5,
155            safety_check_enabled: true,
156        }
157    }
158}
159
160/// The main strange loop structure
161pub struct StrangeLoop {
162    config: StrangeLoopConfig,
163    meta_knowledge: Arc<DashMap<MetaLevel, Vec<MetaKnowledge>>>,
164    safety_constraints: Vec<SafetyConstraint>,
165    modification_rules: Vec<ModificationRule>,
166    learning_iterations: Arc<DashMap<MetaLevel, u64>>,
167    modification_count: usize,
168    safety_violations: usize,
169
170    // Integrated components (reserved for future use)
171    #[allow(dead_code)]
172    temporal_comparator: TemporalComparator<String>,
173    attractor_analyzer: AttractorAnalyzer,
174    #[allow(dead_code)]
175    temporal_solver: TemporalNeuralSolver,
176}
177
178impl StrangeLoop {
179    /// Create a new strange loop
180    pub fn new(config: StrangeLoopConfig) -> Self {
181        Self {
182            config,
183            meta_knowledge: Arc::new(DashMap::new()),
184            safety_constraints: vec![
185                SafetyConstraint::always_safe(),
186                SafetyConstraint::eventually_terminates(),
187            ],
188            modification_rules: Vec::new(),
189            learning_iterations: Arc::new(DashMap::new()),
190            modification_count: 0,
191            safety_violations: 0,
192            temporal_comparator: TemporalComparator::new(1000, 10000),
193            attractor_analyzer: AttractorAnalyzer::new(3, 10000),
194            temporal_solver: TemporalNeuralSolver::default(),
195        }
196    }
197
198    /// Learn at a specific meta-level
199    pub fn learn_at_level(
200        &mut self,
201        level: MetaLevel,
202        data: &[String],
203    ) -> Result<Vec<MetaKnowledge>, StrangeLoopError> {
204        if level.level() > self.config.max_meta_depth {
205            return Err(StrangeLoopError::MaxDepthExceeded(level.level()));
206        }
207
208        // Increment learning iterations
209        self.learning_iterations
210            .entry(level)
211            .and_modify(|v| *v += 1)
212            .or_insert(1);
213
214        // Extract patterns from data
215        let patterns = self.extract_patterns(level, data)?;
216
217        // Store meta-knowledge
218        self.meta_knowledge
219            .entry(level)
220            .or_insert_with(Vec::new)
221            .extend(patterns.clone());
222
223        // If not at max depth, meta-learn from this level
224        if level.level() < self.config.max_meta_depth {
225            self.meta_learn_from_level(level)?;
226        }
227
228        Ok(patterns)
229    }
230
231    /// Meta-learn from a lower level
232    fn meta_learn_from_level(&mut self, level: MetaLevel) -> Result<(), StrangeLoopError> {
233        // Get knowledge from this level
234        let knowledge = if let Some(k) = self.meta_knowledge.get(&level) {
235            k.clone()
236        } else {
237            return Ok(()); // No knowledge to learn from
238        };
239
240        // Extract meta-patterns
241        let meta_patterns: Vec<String> = knowledge
242            .iter()
243            .map(|k| k.pattern.clone())
244            .collect();
245
246        // Learn at next level
247        let next_level = level.next();
248        let _meta_knowledge = self.learn_at_level(next_level, &meta_patterns)?;
249
250        Ok(())
251    }
252
253    /// Extract patterns from data
254    fn extract_patterns(
255        &self,
256        level: MetaLevel,
257        data: &[String],
258    ) -> Result<Vec<MetaKnowledge>, StrangeLoopError> {
259        let mut patterns = Vec::new();
260
261        // Find recurring patterns using temporal comparison
262        for i in 0..data.len() {
263            for j in i+1..data.len() {
264                if data[i] == data[j] {
265                    // Found a repeating pattern
266                    let pattern = MetaKnowledge::new(
267                        level,
268                        data[i].clone(),
269                        0.8, // Confidence
270                    );
271                    patterns.push(pattern);
272                }
273            }
274        }
275
276        // Limit number of patterns
277        patterns.truncate(100);
278
279        Ok(patterns)
280    }
281
282    /// Apply self-modification with safety checks
283    pub fn apply_modification(
284        &mut self,
285        rule: ModificationRule,
286    ) -> Result<(), StrangeLoopError> {
287        if !self.config.enable_self_modification {
288            return Err(StrangeLoopError::InvalidModification(
289                "Self-modification is disabled".to_string()
290            ));
291        }
292
293        if self.modification_count >= self.config.max_modifications_per_cycle {
294            return Err(StrangeLoopError::InvalidModification(
295                "Max modifications per cycle reached".to_string()
296            ));
297        }
298
299        // Safety check
300        if rule.safety_check && self.config.safety_check_enabled {
301            self.check_safety_constraints()?;
302        }
303
304        // Apply modification
305        self.modification_rules.push(rule);
306        self.modification_count += 1;
307
308        Ok(())
309    }
310
311    /// Check all safety constraints
312    fn check_safety_constraints(&mut self) -> Result<(), StrangeLoopError> {
313        for constraint in &self.safety_constraints {
314            if constraint.enforced {
315                // Simplified safety check
316                // In production, this would use the temporal solver
317                if constraint.formula.contains("safe") {
318                    // Always pass for now
319                    continue;
320                }
321            }
322        }
323
324        Ok(())
325    }
326
327    /// Add a safety constraint
328    pub fn add_safety_constraint(&mut self, constraint: SafetyConstraint) {
329        self.safety_constraints.push(constraint);
330    }
331
332    /// Get knowledge at a specific level
333    pub fn get_knowledge_at_level(&self, level: MetaLevel) -> Vec<MetaKnowledge> {
334        self.meta_knowledge
335            .get(&level)
336            .map(|k| k.clone())
337            .unwrap_or_default()
338    }
339
340    /// Get all meta-knowledge
341    pub fn get_all_knowledge(&self) -> HashMap<MetaLevel, Vec<MetaKnowledge>> {
342        let mut result = HashMap::new();
343        for entry in self.meta_knowledge.iter() {
344            result.insert(*entry.key(), entry.value().clone());
345        }
346        result
347    }
348
349    /// Get summary statistics
350    pub fn get_summary(&self) -> MetaLearningSummary {
351        let total_knowledge: usize = self.meta_knowledge
352            .iter()
353            .map(|entry| entry.value().len())
354            .sum();
355
356        MetaLearningSummary {
357            total_levels: self.meta_knowledge.len(),
358            total_knowledge,
359            total_modifications: self.modification_count,
360            safety_violations: self.safety_violations,
361            learning_iterations: self.learning_iterations
362                .iter()
363                .map(|entry| *entry.value())
364                .sum(),
365        }
366    }
367
368    /// Reset the strange loop
369    pub fn reset(&mut self) {
370        self.meta_knowledge.clear();
371        self.learning_iterations.clear();
372        self.modification_rules.clear();
373        self.modification_count = 0;
374        self.safety_violations = 0;
375    }
376
377    /// Analyze behavioral dynamics using attractor analysis
378    pub fn analyze_behavior(&mut self, trajectory_data: Vec<Vec<f64>>) -> Result<String, StrangeLoopError> {
379        for (i, point_data) in trajectory_data.iter().enumerate() {
380            let point = PhasePoint::new(point_data.clone(), i as u64);
381            self.attractor_analyzer.add_point(point)
382                .map_err(|e| StrangeLoopError::MetaLearningFailed(e.to_string()))?;
383        }
384
385        let analysis = self.attractor_analyzer.analyze()
386            .map_err(|e| StrangeLoopError::MetaLearningFailed(e.to_string()))?;
387
388        Ok(format!("{:?}", analysis.attractor_type))
389    }
390}
391
392impl Default for StrangeLoop {
393    fn default() -> Self {
394        Self::new(StrangeLoopConfig::default())
395    }
396}
397
398/// Meta-learner trait for types that can engage in meta-learning
399pub trait MetaLearner {
400    fn learn(&mut self, data: &[String]) -> Result<Vec<MetaKnowledge>, StrangeLoopError>;
401    fn meta_level(&self) -> MetaLevel;
402}
403
404#[cfg(test)]
405mod tests {
406    use super::*;
407
408    #[test]
409    fn test_meta_level() {
410        let base = MetaLevel::base();
411        assert_eq!(base.level(), 0);
412
413        let next = base.next();
414        assert_eq!(next.level(), 1);
415    }
416
417    #[test]
418    fn test_strange_loop_creation() {
419        let config = StrangeLoopConfig::default();
420        let strange_loop = StrangeLoop::new(config);
421
422        assert_eq!(strange_loop.modification_count, 0);
423        assert_eq!(strange_loop.safety_violations, 0);
424    }
425
426    #[test]
427    fn test_learning_at_level() {
428        let mut strange_loop = StrangeLoop::default();
429
430        let data = vec![
431            "pattern1".to_string(),
432            "pattern2".to_string(),
433            "pattern1".to_string(),
434        ];
435
436        let result = strange_loop.learn_at_level(MetaLevel::base(), &data);
437        assert!(result.is_ok());
438
439        let knowledge = strange_loop.get_knowledge_at_level(MetaLevel::base());
440        assert!(!knowledge.is_empty());
441    }
442
443    #[test]
444    fn test_max_depth_exceeded() {
445        let mut strange_loop = StrangeLoop::default();
446
447        let data = vec!["test".to_string()];
448        let deep_level = MetaLevel(10); // Exceeds default max of 3
449
450        let result = strange_loop.learn_at_level(deep_level, &data);
451        assert!(result.is_err());
452    }
453
454    #[test]
455    fn test_safety_constraint() {
456        let constraint = SafetyConstraint::always_safe();
457        assert_eq!(constraint.name, "always_safe");
458        assert!(constraint.enforced);
459    }
460
461    #[test]
462    fn test_modification_disabled() {
463        let mut strange_loop = StrangeLoop::default();
464
465        let rule = ModificationRule::new("test_rule", "trigger", "action");
466        let result = strange_loop.apply_modification(rule);
467
468        assert!(result.is_err()); // Should fail because self-modification is disabled
469    }
470
471    #[test]
472    fn test_summary() {
473        let mut strange_loop = StrangeLoop::default();
474
475        let data = vec!["pattern1".to_string(), "pattern2".to_string()];
476        let _ = strange_loop.learn_at_level(MetaLevel::base(), &data);
477
478        let summary = strange_loop.get_summary();
479        assert!(summary.total_knowledge > 0);
480        assert_eq!(summary.safety_violations, 0);
481    }
482
483    #[test]
484    fn test_reset() {
485        let mut strange_loop = StrangeLoop::default();
486
487        let data = vec!["pattern1".to_string()];
488        let _ = strange_loop.learn_at_level(MetaLevel::base(), &data);
489
490        strange_loop.reset();
491
492        let summary = strange_loop.get_summary();
493        assert_eq!(summary.total_knowledge, 0);
494        assert_eq!(summary.total_modifications, 0);
495    }
496}