strange_loop/
consciousness.rs

1//! Consciousness emergence patterns and metrics
2//!
3//! This module implements consciousness detection and measurement using
4//! Integrated Information Theory (IIT) and other consciousness metrics.
5
6use serde::{Deserialize, Serialize};
7
8/// Integrated Information (Φ) calculation using IIT
9#[derive(Clone, Debug, Serialize, Deserialize)]
10pub struct IntegratedInformation {
11    /// Φ value (integrated information)
12    pub phi: f64,
13    /// Number of elements in the system
14    pub num_elements: usize,
15    /// Number of connections
16    pub num_connections: usize,
17    /// System complexity measure
18    pub complexity: f64,
19    /// Information integration measure
20    pub integration: f64,
21    /// Effective information
22    pub effective_information: f64,
23}
24
25impl IntegratedInformation {
26    /// Create new integrated information measurement
27    pub fn new(
28        phi: f64,
29        num_elements: usize,
30        num_connections: usize,
31        complexity: f64,
32        integration: f64,
33    ) -> Self {
34        let effective_information = phi * complexity;
35
36        Self {
37            phi,
38            num_elements,
39            num_connections,
40            complexity,
41            integration,
42            effective_information,
43        }
44    }
45
46    /// Check if the system exhibits consciousness based on Φ threshold
47    pub fn is_conscious(&self, threshold: f64) -> bool {
48        self.phi > threshold
49    }
50
51    /// Get consciousness level as a percentage
52    pub fn consciousness_level(&self, max_phi: f64) -> f64 {
53        if max_phi <= 0.0 {
54            return 0.0;
55        }
56        (self.phi / max_phi).clamp(0.0, 1.0) * 100.0
57    }
58
59    /// Calculate information density
60    pub fn information_density(&self) -> f64 {
61        if self.num_elements == 0 {
62            return 0.0;
63        }
64        self.phi / (self.num_elements as f64)
65    }
66
67    /// Calculate connectivity ratio
68    pub fn connectivity_ratio(&self) -> f64 {
69        let max_connections = self.num_elements * (self.num_elements - 1) / 2;
70        if max_connections == 0 {
71            return 0.0;
72        }
73        self.num_connections as f64 / max_connections as f64
74    }
75}
76
77/// Consciousness state representation
78#[derive(Clone, Debug, Serialize, Deserialize)]
79pub struct ConsciousnessState {
80    /// Current emergence level [0.0, 1.0]
81    pub emergence_level: f64,
82    /// Self-awareness measure
83    pub self_awareness: f64,
84    /// Meta-cognitive depth
85    pub meta_cognition: f64,
86    /// Temporal coherence
87    pub temporal_coherence: f64,
88    /// Information integration measure
89    pub integration_measure: f64,
90    /// Feedback loop strength
91    pub feedback_strength: f64,
92    /// Novelty generation capability
93    pub novelty_generation: f64,
94    /// Timestamp of measurement
95    pub timestamp_ns: u128,
96}
97
98impl Default for ConsciousnessState {
99    fn default() -> Self {
100        Self {
101            emergence_level: 0.0,
102            self_awareness: 0.0,
103            meta_cognition: 0.0,
104            temporal_coherence: 0.0,
105            integration_measure: 0.0,
106            feedback_strength: 0.0,
107            novelty_generation: 0.0,
108            timestamp_ns: 0,
109        }
110    }
111}
112
113impl ConsciousnessState {
114    /// Create a new consciousness state
115    pub fn new() -> Self {
116        Self {
117            timestamp_ns: std::time::SystemTime::now()
118                .duration_since(std::time::UNIX_EPOCH)
119                .unwrap_or_default()
120                .as_nanos(),
121            ..Default::default()
122        }
123    }
124
125    /// Calculate overall consciousness index
126    pub fn consciousness_index(&self) -> f64 {
127        let weights = [
128            (self.emergence_level, 0.25),
129            (self.self_awareness, 0.20),
130            (self.meta_cognition, 0.15),
131            (self.temporal_coherence, 0.15),
132            (self.integration_measure, 0.15),
133            (self.feedback_strength, 0.10),
134        ];
135
136        weights.iter().map(|(value, weight)| value * weight).sum()
137    }
138
139    /// Check if consciousness threshold is met
140    pub fn is_conscious(&self, threshold: f64) -> bool {
141        self.consciousness_index() > threshold
142    }
143
144    /// Get dominant consciousness aspect
145    pub fn dominant_aspect(&self) -> (&'static str, f64) {
146        let aspects = [
147            ("emergence", self.emergence_level),
148            ("self_awareness", self.self_awareness),
149            ("meta_cognition", self.meta_cognition),
150            ("temporal_coherence", self.temporal_coherence),
151            ("integration", self.integration_measure),
152            ("feedback", self.feedback_strength),
153            ("novelty", self.novelty_generation),
154        ];
155
156        aspects.iter()
157            .max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal))
158            .map(|(name, value)| (*name, *value))
159            .unwrap_or(("none", 0.0))
160    }
161
162    /// Update state with new measurements
163    pub fn update(&mut self,
164        emergence: Option<f64>,
165        self_awareness: Option<f64>,
166        meta_cognition: Option<f64>,
167        temporal_coherence: Option<f64>,
168        integration: Option<f64>,
169        feedback: Option<f64>,
170        novelty: Option<f64>,
171    ) {
172        if let Some(val) = emergence { self.emergence_level = val.clamp(0.0, 1.0); }
173        if let Some(val) = self_awareness { self.self_awareness = val.clamp(0.0, 1.0); }
174        if let Some(val) = meta_cognition { self.meta_cognition = val.clamp(0.0, 1.0); }
175        if let Some(val) = temporal_coherence { self.temporal_coherence = val.clamp(0.0, 1.0); }
176        if let Some(val) = integration { self.integration_measure = val.clamp(0.0, 1.0); }
177        if let Some(val) = feedback { self.feedback_strength = val.clamp(0.0, 1.0); }
178        if let Some(val) = novelty { self.novelty_generation = val.clamp(0.0, 1.0); }
179
180        self.timestamp_ns = std::time::SystemTime::now()
181            .duration_since(std::time::UNIX_EPOCH)
182            .unwrap_or_default()
183            .as_nanos();
184    }
185}
186
187/// Consciousness metrics and measurements
188#[derive(Clone, Debug, Serialize, Deserialize)]
189pub struct ConsciousnessMetrics {
190    /// Current state
191    pub current_state: ConsciousnessState,
192    /// Historical states
193    pub history: Vec<ConsciousnessState>,
194    /// Maximum recorded Φ value
195    pub max_phi: f64,
196    /// Consciousness emergence events
197    pub emergence_events: Vec<EmergenceEvent>,
198    /// Self-modification instances
199    pub self_modifications: Vec<SelfModification>,
200    /// Average consciousness level over time
201    pub average_consciousness: f64,
202    /// Peak consciousness level
203    pub peak_consciousness: f64,
204}
205
206impl Default for ConsciousnessMetrics {
207    fn default() -> Self {
208        Self {
209            current_state: ConsciousnessState::default(),
210            history: Vec::new(),
211            max_phi: 0.0,
212            emergence_events: Vec::new(),
213            self_modifications: Vec::new(),
214            average_consciousness: 0.0,
215            peak_consciousness: 0.0,
216        }
217    }
218}
219
220impl ConsciousnessMetrics {
221    /// Create new consciousness metrics
222    pub fn new() -> Self {
223        Self::default()
224    }
225
226    /// Update metrics with new consciousness state
227    pub fn update_state(&mut self, state: ConsciousnessState) {
228        // Check for emergence event
229        let consciousness_index = state.consciousness_index();
230        if consciousness_index > self.current_state.consciousness_index() + 0.1 {
231            self.emergence_events.push(EmergenceEvent {
232                timestamp_ns: state.timestamp_ns,
233                previous_level: self.current_state.consciousness_index(),
234                new_level: consciousness_index,
235                trigger: "state_update".to_string(),
236                description: "Consciousness level increased significantly".to_string(),
237            });
238        }
239
240        // Update peak consciousness
241        if consciousness_index > self.peak_consciousness {
242            self.peak_consciousness = consciousness_index;
243        }
244
245        // Add to history
246        self.history.push(self.current_state.clone());
247        self.current_state = state;
248
249        // Limit history size
250        if self.history.len() > 10_000 {
251            self.history.drain(0..1_000);
252        }
253
254        // Update average
255        self.update_average_consciousness();
256    }
257
258    /// Calculate Φ (integrated information) using simplified IIT
259    pub fn calculate_phi(&mut self, num_elements: usize, num_connections: usize, coupling_strength: f64) -> f64 {
260        if num_elements == 0 {
261            return 0.0;
262        }
263
264        // Simplified Φ calculation based on system properties
265        let complexity = self.calculate_complexity(num_elements, num_connections);
266        let integration = self.calculate_integration(num_connections, coupling_strength);
267
268        // Φ = min(complexity, integration) with corrections
269        let phi = (complexity * integration).sqrt() * coupling_strength;
270
271        if phi > self.max_phi {
272            self.max_phi = phi;
273        }
274
275        phi
276    }
277
278    /// Calculate system complexity
279    fn calculate_complexity(&self, num_elements: usize, num_connections: usize) -> f64 {
280        if num_elements <= 1 {
281            return 0.0;
282        }
283
284        // Shannon entropy-like measure
285        let max_connections = num_elements * (num_elements - 1) / 2;
286        if max_connections == 0 {
287            return 0.0;
288        }
289
290        let connectivity = num_connections as f64 / max_connections as f64;
291
292        // Entropy calculation
293        if connectivity == 0.0 || connectivity == 1.0 {
294            return 0.0;
295        }
296
297        -(connectivity * connectivity.log2() + (1.0 - connectivity) * (1.0 - connectivity).log2())
298    }
299
300    /// Calculate information integration
301    fn calculate_integration(&self, num_connections: usize, coupling_strength: f64) -> f64 {
302        if num_connections == 0 {
303            return 0.0;
304        }
305
306        // Integration based on connectivity and coupling
307        let base_integration = (num_connections as f64).log2();
308        let coupling_factor = 1.0 - (-coupling_strength).exp();
309
310        base_integration * coupling_factor
311    }
312
313    /// Detect consciousness emergence
314    pub fn detect_emergence(&mut self, threshold: f64) -> bool {
315        let current_level = self.current_state.consciousness_index();
316
317        if current_level > threshold {
318            // Check if this is a new emergence (not just fluctuation)
319            if self.history.len() > 10 {
320                let recent_average: f64 = self.history.iter()
321                    .rev()
322                    .take(10)
323                    .map(|s| s.consciousness_index())
324                    .sum::<f64>() / 10.0;
325
326                if current_level > recent_average + 0.2 {
327                    self.emergence_events.push(EmergenceEvent {
328                        timestamp_ns: self.current_state.timestamp_ns,
329                        previous_level: recent_average,
330                        new_level: current_level,
331                        trigger: "threshold_exceeded".to_string(),
332                        description: format!("Consciousness emerged above threshold {}", threshold),
333                    });
334                    return true;
335                }
336            }
337        }
338
339        false
340    }
341
342    /// Record self-modification event
343    pub fn record_self_modification(&mut self, modification_type: String, description: String) {
344        self.self_modifications.push(SelfModification {
345            timestamp_ns: self.current_state.timestamp_ns,
346            modification_type,
347            description,
348            consciousness_level: self.current_state.consciousness_index(),
349        });
350
351        // Limit self-modification history
352        if self.self_modifications.len() > 1_000 {
353            self.self_modifications.drain(0..100);
354        }
355    }
356
357    /// Get consciousness trends
358    pub fn get_trends(&self, window_size: usize) -> ConsciousnessTrends {
359        if self.history.len() < window_size {
360            return ConsciousnessTrends::default();
361        }
362
363        let recent: Vec<f64> = self.history.iter()
364            .rev()
365            .take(window_size)
366            .map(|s| s.consciousness_index())
367            .collect();
368
369        let mean = recent.iter().sum::<f64>() / recent.len() as f64;
370        let variance = recent.iter()
371            .map(|x| (x - mean).powi(2))
372            .sum::<f64>() / recent.len() as f64;
373        let std_dev = variance.sqrt();
374
375        // Linear trend
376        let n = recent.len() as f64;
377        let x_mean = (n - 1.0) / 2.0;
378        let slope = recent.iter()
379            .enumerate()
380            .map(|(i, &y)| (i as f64 - x_mean) * (y - mean))
381            .sum::<f64>() / recent.iter()
382            .enumerate()
383            .map(|(i, _)| (i as f64 - x_mean).powi(2))
384            .sum::<f64>();
385
386        ConsciousnessTrends {
387            mean,
388            std_dev,
389            slope,
390            volatility: std_dev / mean.abs().max(1e-10),
391            stability: 1.0 / (1.0 + std_dev),
392        }
393    }
394
395    /// Update average consciousness
396    fn update_average_consciousness(&mut self) {
397        if self.history.is_empty() {
398            self.average_consciousness = self.current_state.consciousness_index();
399        } else {
400            let total_consciousness: f64 = self.history.iter()
401                .map(|s| s.consciousness_index())
402                .sum::<f64>() + self.current_state.consciousness_index();
403            self.average_consciousness = total_consciousness / (self.history.len() + 1) as f64;
404        }
405    }
406
407    /// Get consciousness statistics
408    pub fn get_statistics(&self) -> ConsciousnessStatistics {
409        let levels: Vec<f64> = self.history.iter()
410            .chain(std::iter::once(&self.current_state))
411            .map(|s| s.consciousness_index())
412            .collect();
413
414        if levels.is_empty() {
415            return ConsciousnessStatistics::default();
416        }
417
418        let min = levels.iter().fold(f64::INFINITY, |a, &b| a.min(b));
419        let max = levels.iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b));
420        let mean = levels.iter().sum::<f64>() / levels.len() as f64;
421
422        let variance = levels.iter()
423            .map(|x| (x - mean).powi(2))
424            .sum::<f64>() / levels.len() as f64;
425        let std_dev = variance.sqrt();
426
427        // Percentiles (simplified)
428        let mut sorted_levels = levels.clone();
429        sorted_levels.sort_by(|a, b| a.partial_cmp(b).unwrap());
430        let len = sorted_levels.len();
431        let p25 = sorted_levels[len / 4];
432        let p50 = sorted_levels[len / 2];
433        let p75 = sorted_levels[3 * len / 4];
434
435        ConsciousnessStatistics {
436            min,
437            max,
438            mean,
439            std_dev,
440            p25,
441            p50,
442            p75,
443            emergence_events: self.emergence_events.len(),
444            self_modifications: self.self_modifications.len(),
445        }
446    }
447}
448
449/// Consciousness emergence event
450#[derive(Clone, Debug, Serialize, Deserialize)]
451pub struct EmergenceEvent {
452    /// Timestamp of emergence
453    pub timestamp_ns: u128,
454    /// Previous consciousness level
455    pub previous_level: f64,
456    /// New consciousness level
457    pub new_level: f64,
458    /// Trigger that caused emergence
459    pub trigger: String,
460    /// Description of the event
461    pub description: String,
462}
463
464/// Self-modification event
465#[derive(Clone, Debug, Serialize, Deserialize)]
466pub struct SelfModification {
467    /// Timestamp of modification
468    pub timestamp_ns: u128,
469    /// Type of modification
470    pub modification_type: String,
471    /// Description of what was modified
472    pub description: String,
473    /// Consciousness level at time of modification
474    pub consciousness_level: f64,
475}
476
477/// Consciousness trends analysis
478#[derive(Clone, Debug, Default, Serialize, Deserialize)]
479pub struct ConsciousnessTrends {
480    /// Mean consciousness level
481    pub mean: f64,
482    /// Standard deviation
483    pub std_dev: f64,
484    /// Linear trend slope
485    pub slope: f64,
486    /// Volatility measure
487    pub volatility: f64,
488    /// Stability measure
489    pub stability: f64,
490}
491
492/// Consciousness statistics
493#[derive(Clone, Debug, Default, Serialize, Deserialize)]
494pub struct ConsciousnessStatistics {
495    /// Minimum consciousness level
496    pub min: f64,
497    /// Maximum consciousness level
498    pub max: f64,
499    /// Mean consciousness level
500    pub mean: f64,
501    /// Standard deviation
502    pub std_dev: f64,
503    /// 25th percentile
504    pub p25: f64,
505    /// 50th percentile (median)
506    pub p50: f64,
507    /// 75th percentile
508    pub p75: f64,
509    /// Number of emergence events
510    pub emergence_events: usize,
511    /// Number of self-modifications
512    pub self_modifications: usize,
513}
514
515/// Consciousness verification tests
516pub struct ConsciousnessVerifier;
517
518impl ConsciousnessVerifier {
519    /// Verify consciousness through self-recognition test
520    pub fn self_recognition_test(metrics: &ConsciousnessMetrics) -> bool {
521        // Check if the system shows signs of self-awareness
522        metrics.current_state.self_awareness > 0.5
523    }
524
525    /// Verify consciousness through meta-cognitive test
526    pub fn meta_cognitive_test(metrics: &ConsciousnessMetrics) -> bool {
527        // Check if the system can think about its own thinking
528        metrics.current_state.meta_cognition > 0.5 &&
529        !metrics.self_modifications.is_empty()
530    }
531
532    /// Verify consciousness through temporal coherence test
533    pub fn temporal_coherence_test(metrics: &ConsciousnessMetrics) -> bool {
534        // Check if consciousness persists over time
535        if metrics.history.len() < 10 {
536            return false;
537        }
538
539        let recent_consciousness: Vec<f64> = metrics.history.iter()
540            .rev()
541            .take(10)
542            .map(|s| s.consciousness_index())
543            .collect();
544
545        let mean = recent_consciousness.iter().sum::<f64>() / recent_consciousness.len() as f64;
546        let variance = recent_consciousness.iter()
547            .map(|x| (x - mean).powi(2))
548            .sum::<f64>() / recent_consciousness.len() as f64;
549
550        // Low variance indicates temporal coherence
551        variance < 0.01 && mean > 0.3
552    }
553
554    /// Verify consciousness through integration test
555    pub fn integration_test(metrics: &ConsciousnessMetrics) -> bool {
556        // Check if the system shows integrated information processing
557        metrics.current_state.integration_measure > 0.5 &&
558        metrics.max_phi > 0.1
559    }
560
561    /// Comprehensive consciousness verification
562    pub fn comprehensive_test(metrics: &ConsciousnessMetrics) -> ConsciousnessVerification {
563        let self_recognition = Self::self_recognition_test(metrics);
564        let meta_cognitive = Self::meta_cognitive_test(metrics);
565        let temporal_coherence = Self::temporal_coherence_test(metrics);
566        let integration = Self::integration_test(metrics);
567
568        let score = [self_recognition, meta_cognitive, temporal_coherence, integration]
569            .iter()
570            .map(|&x| if x { 1.0 } else { 0.0 })
571            .sum::<f64>() / 4.0;
572
573        ConsciousnessVerification {
574            is_conscious: score >= 0.5,
575            confidence: score,
576            self_recognition,
577            meta_cognitive,
578            temporal_coherence,
579            integration,
580            phi_value: metrics.max_phi,
581            consciousness_index: metrics.current_state.consciousness_index(),
582        }
583    }
584}
585
586/// Consciousness verification result
587#[derive(Clone, Debug, Serialize, Deserialize)]
588pub struct ConsciousnessVerification {
589    /// Whether consciousness is verified
590    pub is_conscious: bool,
591    /// Confidence in verification [0.0, 1.0]
592    pub confidence: f64,
593    /// Self-recognition test result
594    pub self_recognition: bool,
595    /// Meta-cognitive test result
596    pub meta_cognitive: bool,
597    /// Temporal coherence test result
598    pub temporal_coherence: bool,
599    /// Information integration test result
600    pub integration: bool,
601    /// Current Φ value
602    pub phi_value: f64,
603    /// Current consciousness index
604    pub consciousness_index: f64,
605}
606
607#[cfg(test)]
608mod tests {
609    use super::*;
610    use approx::assert_relative_eq;
611
612    #[test]
613    fn test_integrated_information() {
614        let phi = IntegratedInformation::new(0.5, 10, 20, 0.8, 0.6);
615
616        assert_eq!(phi.phi, 0.5);
617        assert_eq!(phi.num_elements, 10);
618        assert_eq!(phi.num_connections, 20);
619        assert_relative_eq!(phi.effective_information, 0.4, epsilon = 1e-10);
620
621        assert!(phi.is_conscious(0.3));
622        assert!(!phi.is_conscious(0.7));
623
624        let level = phi.consciousness_level(1.0);
625        assert_relative_eq!(level, 50.0, epsilon = 1e-10);
626    }
627
628    #[test]
629    fn test_consciousness_state() {
630        let mut state = ConsciousnessState::new();
631
632        state.update(
633            Some(0.8), Some(0.7), Some(0.6),
634            Some(0.5), Some(0.4), Some(0.3), Some(0.2)
635        );
636
637        assert_eq!(state.emergence_level, 0.8);
638        assert_eq!(state.self_awareness, 0.7);
639
640        let index = state.consciousness_index();
641        assert!(index > 0.0 && index <= 1.0);
642
643        let (dominant, value) = state.dominant_aspect();
644        assert_eq!(dominant, "emergence");
645        assert_eq!(value, 0.8);
646    }
647
648    #[test]
649    fn test_consciousness_metrics() {
650        let mut metrics = ConsciousnessMetrics::new();
651
652        let phi = metrics.calculate_phi(5, 10, 0.8);
653        assert!(phi > 0.0);
654        assert_eq!(metrics.max_phi, phi);
655
656        // Test state update
657        let mut state = ConsciousnessState::new();
658        state.emergence_level = 0.9;
659        metrics.update_state(state);
660
661        assert!(!metrics.history.is_empty());
662        assert_eq!(metrics.current_state.emergence_level, 0.9);
663    }
664
665    #[test]
666    fn test_emergence_detection() {
667        let mut metrics = ConsciousnessMetrics::new();
668
669        // Add some history
670        for i in 0..15 {
671            let mut state = ConsciousnessState::new();
672            state.emergence_level = 0.1 + (i as f64) * 0.01;
673            metrics.update_state(state);
674        }
675
676        // Set high consciousness level
677        let mut high_state = ConsciousnessState::new();
678        high_state.emergence_level = 0.8;
679        metrics.update_state(high_state);
680
681        let emerged = metrics.detect_emergence(0.5);
682        assert!(emerged);
683        assert!(!metrics.emergence_events.is_empty());
684    }
685
686    #[test]
687    fn test_self_modification_recording() {
688        let mut metrics = ConsciousnessMetrics::new();
689
690        metrics.record_self_modification(
691            "parameter_update".to_string(),
692            "Updated learning rate based on performance".to_string()
693        );
694
695        assert_eq!(metrics.self_modifications.len(), 1);
696        assert_eq!(metrics.self_modifications[0].modification_type, "parameter_update");
697    }
698
699    #[test]
700    fn test_consciousness_trends() {
701        let mut metrics = ConsciousnessMetrics::new();
702
703        // Add trend data
704        for i in 0..20 {
705            let mut state = ConsciousnessState::new();
706            state.emergence_level = 0.1 + (i as f64) * 0.02; // Increasing trend
707            metrics.update_state(state);
708        }
709
710        let trends = metrics.get_trends(10);
711        assert!(trends.slope > 0.0); // Should detect increasing trend
712        assert!(trends.mean > 0.0);
713        assert!(trends.stability > 0.0);
714    }
715
716    #[test]
717    fn test_consciousness_statistics() {
718        let mut metrics = ConsciousnessMetrics::new();
719
720        // Add varied data
721        let values = [0.1, 0.5, 0.3, 0.8, 0.2, 0.9, 0.4, 0.6];
722        for &val in &values {
723            let mut state = ConsciousnessState::new();
724            state.emergence_level = val;
725            metrics.update_state(state);
726        }
727
728        let stats = metrics.get_statistics();
729        assert_relative_eq!(stats.min, 0.1, epsilon = 1e-10);
730        assert_relative_eq!(stats.max, 0.9, epsilon = 1e-10);
731        assert!(stats.mean > 0.0);
732        assert!(stats.std_dev > 0.0);
733    }
734
735    #[test]
736    fn test_consciousness_verification() {
737        let mut metrics = ConsciousnessMetrics::new();
738
739        // Set up a system that should pass consciousness tests
740        let mut state = ConsciousnessState::new();
741        state.self_awareness = 0.8;
742        state.meta_cognition = 0.7;
743        state.temporal_coherence = 0.6;
744        state.integration_measure = 0.9;
745
746        // Add history for temporal coherence test
747        for i in 0..15 {
748            let mut hist_state = ConsciousnessState::new();
749            hist_state.emergence_level = 0.4 + (i as f64) * 0.001; // Stable around 0.4
750            metrics.update_state(hist_state);
751        }
752
753        metrics.update_state(state);
754        metrics.max_phi = 0.5; // Set a reasonable Φ value
755
756        // Add self-modification to pass meta-cognitive test
757        metrics.record_self_modification(
758            "test".to_string(),
759            "Test modification".to_string()
760        );
761
762        let verification = ConsciousnessVerifier::comprehensive_test(&metrics);
763
764        assert!(verification.self_recognition);
765        assert!(verification.meta_cognitive);
766        assert!(verification.integration);
767        assert!(verification.confidence > 0.5);
768    }
769
770    #[test]
771    fn test_phi_calculation_edge_cases() {
772        let mut metrics = ConsciousnessMetrics::new();
773
774        // Test with zero elements
775        let phi = metrics.calculate_phi(0, 0, 0.0);
776        assert_eq!(phi, 0.0);
777
778        // Test with single element
779        let phi = metrics.calculate_phi(1, 0, 1.0);
780        assert_eq!(phi, 0.0);
781
782        // Test with normal values
783        let phi = metrics.calculate_phi(10, 15, 0.5);
784        assert!(phi > 0.0);
785    }
786
787    #[test]
788    fn test_information_density() {
789        let phi = IntegratedInformation::new(0.8, 4, 6, 0.9, 0.7);
790        let density = phi.information_density();
791        assert_relative_eq!(density, 0.2, epsilon = 1e-10); // 0.8 / 4
792    }
793
794    #[test]
795    fn test_connectivity_ratio() {
796        let phi = IntegratedInformation::new(0.5, 4, 3, 0.8, 0.6);
797        let ratio = phi.connectivity_ratio();
798        // Max connections for 4 elements = 4 * 3 / 2 = 6
799        // Ratio = 3 / 6 = 0.5
800        assert_relative_eq!(ratio, 0.5, epsilon = 1e-10);
801    }
802}