sublinear_solver/temporal_nexus/core/
identity.rs1use super::{TemporalError, TemporalResult, TscTimestamp};
8use std::collections::{HashMap, VecDeque};
9
10#[derive(Debug, Clone, Default)]
12pub struct ContinuityMetrics {
13 pub continuity_score: f64,
14 pub identity_stability: f64,
15 pub continuity_breaks: u64,
16 pub average_gap_duration_ns: f64,
17 pub max_gap_duration_ns: u64,
18 pub identity_coherence: f64,
19 pub temporal_consistency: f64,
20 pub preservation_efficiency: f64,
21}
22
23#[derive(Debug, Clone)]
25struct IdentitySnapshot {
26 timestamp: TscTimestamp,
27 state_hash: u64,
28 feature_vector: Vec<f64>,
29 coherence_score: f64,
30 stability_metric: f64,
31 memory_fingerprint: Vec<u8>,
32}
33
34impl IdentitySnapshot {
35 fn new(timestamp: TscTimestamp, state: &[u8]) -> Self {
37 let feature_vector = Self::extract_features(state);
38 let state_hash = Self::compute_hash(state);
39 let coherence_score = Self::calculate_coherence(&feature_vector);
40
41 Self {
42 timestamp,
43 state_hash,
44 feature_vector,
45 coherence_score,
46 stability_metric: 1.0, memory_fingerprint: state.to_vec(),
48 }
49 }
50
51 fn extract_features(state: &[u8]) -> Vec<f64> {
53 if state.is_empty() {
54 return vec![0.0; 16]; }
56
57 let mut features = Vec::with_capacity(16);
58
59 let mean = state.iter().map(|&x| x as f64).sum::<f64>() / state.len() as f64;
61 features.push(mean);
62
63 let variance = state
64 .iter()
65 .map(|&x| (x as f64 - mean).powi(2))
66 .sum::<f64>()
67 / state.len() as f64;
68 features.push(variance.sqrt());
69
70 let mut byte_counts = [0u32; 256];
72 for &byte in state {
73 byte_counts[byte as usize] += 1;
74 }
75
76 let entropy = byte_counts
77 .iter()
78 .filter(|&&count| count > 0)
79 .map(|&count| {
80 let p = count as f64 / state.len() as f64;
81 -p * p.ln()
82 })
83 .sum::<f64>();
84 features.push(entropy);
85
86 for i in 0..8 {
88 let freq_component = state
89 .iter()
90 .enumerate()
91 .map(|(j, &x)| {
92 let phase =
93 2.0 * std::f64::consts::PI * (i + 1) as f64 * j as f64 / state.len() as f64;
94 x as f64 * phase.cos()
95 })
96 .sum::<f64>();
97 features.push(freq_component / state.len() as f64);
98 }
99
100 let complexity = Self::estimate_complexity(state);
102 features.push(complexity);
103
104 let pattern_density = Self::calculate_pattern_density(state);
106 features.push(pattern_density);
107
108 let autocorr = Self::calculate_autocorrelation(state, 1);
110 features.push(autocorr);
111
112 let trend = Self::calculate_trend(state);
114 features.push(trend);
115
116 for feature in &mut features {
118 *feature = feature.tanh(); }
120
121 features
122 }
123
124 fn compute_hash(state: &[u8]) -> u64 {
126 use std::collections::hash_map::DefaultHasher;
127 use std::hash::{Hash, Hasher};
128
129 let mut hasher = DefaultHasher::new();
130 state.hash(&mut hasher);
131 hasher.finish()
132 }
133
134 fn calculate_coherence(features: &[f64]) -> f64 {
136 if features.is_empty() {
137 return 0.0;
138 }
139
140 let mean = features.iter().sum::<f64>() / features.len() as f64;
142 let variance =
143 features.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / features.len() as f64;
144
145 (-variance).exp().min(1.0)
147 }
148
149 fn calculate_similarity(&self, other: &IdentitySnapshot) -> f64 {
162 if self.feature_vector.len() != other.feature_vector.len() || self.feature_vector.is_empty()
163 {
164 return 0.0;
165 }
166
167 let dot_product: f64 = self
168 .feature_vector
169 .iter()
170 .zip(other.feature_vector.iter())
171 .map(|(a, b)| a * b)
172 .sum();
173 let magnitude_self: f64 = self
174 .feature_vector
175 .iter()
176 .map(|x| x * x)
177 .sum::<f64>()
178 .sqrt();
179 let magnitude_other: f64 = other
180 .feature_vector
181 .iter()
182 .map(|x| x * x)
183 .sum::<f64>()
184 .sqrt();
185
186 let cosine = if magnitude_self > 0.0 && magnitude_other > 0.0 {
187 dot_product / (magnitude_self * magnitude_other)
188 } else {
189 0.0
190 };
191
192 let mut mean_l1 = 0.0;
200 let mut max_diff: f64 = 0.0;
201 for (a, b) in self.feature_vector.iter().zip(other.feature_vector.iter()) {
202 let d = (a - b).abs();
203 mean_l1 += d;
204 if d > max_diff {
205 max_diff = d;
206 }
207 }
208 mean_l1 /= self.feature_vector.len() as f64;
209 let l1_similarity = (1.0 - mean_l1 / 2.0).max(0.0);
210 let chebyshev_similarity = (1.0 - max_diff / 2.0).max(0.0);
212
213 0.3 * cosine + 0.3 * l1_similarity + 0.4 * chebyshev_similarity
218 }
219
220 fn estimate_complexity(data: &[u8]) -> f64 {
223 if data.len() < 2 {
224 return 0.0;
225 }
226
227 let mut runs = 0;
229 let mut current_byte = data[0];
230
231 for &byte in &data[1..] {
232 if byte != current_byte {
233 runs += 1;
234 current_byte = byte;
235 }
236 }
237
238 runs as f64 / data.len() as f64
239 }
240
241 fn calculate_pattern_density(data: &[u8]) -> f64 {
242 if data.len() < 4 {
243 return 0.0;
244 }
245
246 let mut patterns = HashMap::new();
247
248 for window in data.windows(2) {
250 *patterns.entry((window[0], window[1])).or_insert(0) += 1;
251 }
252
253 patterns.len() as f64 / (data.len() - 1) as f64
254 }
255
256 fn calculate_autocorrelation(data: &[u8], lag: usize) -> f64 {
257 if data.len() <= lag {
258 return 0.0;
259 }
260
261 let mean = data.iter().map(|&x| x as f64).sum::<f64>() / data.len() as f64;
262
263 let numerator: f64 = data
264 .iter()
265 .take(data.len() - lag)
266 .zip(data.iter().skip(lag))
267 .map(|(&x, &y)| (x as f64 - mean) * (y as f64 - mean))
268 .sum();
269
270 let denominator: f64 = data.iter().map(|&x| (x as f64 - mean).powi(2)).sum();
271
272 if denominator > 0.0 {
273 numerator / denominator
274 } else {
275 0.0
276 }
277 }
278
279 fn calculate_trend(data: &[u8]) -> f64 {
280 if data.len() < 2 {
281 return 0.0;
282 }
283
284 let n = data.len() as f64;
285 let sum_x = (0..data.len()).sum::<usize>() as f64;
286 let sum_y = data.iter().map(|&x| x as f64).sum::<f64>();
287 let sum_xy = data
288 .iter()
289 .enumerate()
290 .map(|(i, &y)| i as f64 * y as f64)
291 .sum::<f64>();
292 let sum_x2 = (0..data.len()).map(|i| (i as f64).powi(2)).sum::<f64>();
293
294 let denominator = n * sum_x2 - sum_x * sum_x;
295 if denominator > 0.0 {
296 (n * sum_xy - sum_x * sum_y) / denominator
297 } else {
298 0.0
299 }
300 }
301}
302
303pub struct IdentityContinuityTracker {
305 snapshots: VecDeque<IdentitySnapshot>,
306 metrics: ContinuityMetrics,
307 max_snapshots: usize,
308 continuity_threshold: f64,
309 gap_tolerance_ns: u64,
310 identity_baseline: Option<IdentitySnapshot>,
311 last_validation_time: Option<TscTimestamp>,
312}
313
314impl IdentityContinuityTracker {
315 pub fn new() -> Self {
317 Self {
318 snapshots: VecDeque::new(),
319 metrics: ContinuityMetrics::default(),
320 max_snapshots: 1000,
321 continuity_threshold: 0.7, gap_tolerance_ns: 1_000_000, identity_baseline: None,
324 last_validation_time: None,
325 }
326 }
327
328 pub fn track_continuity(
330 &mut self,
331 timestamp: TscTimestamp,
332 state: &[u8],
333 ) -> TemporalResult<()> {
334 let snapshot = IdentitySnapshot::new(timestamp, state);
335
336 if self.identity_baseline.is_none() {
338 self.identity_baseline = Some(snapshot.clone());
339 }
340
341 let continuity_break_info = if let Some(prev_snapshot) = self.snapshots.back() {
343 Some((snapshot.clone(), prev_snapshot.clone()))
344 } else {
345 None
346 };
347
348 if let Some((current, previous)) = continuity_break_info {
349 self.check_continuity_break(¤t, &previous)?;
350 }
351
352 self.update_stability_metrics(&snapshot);
354
355 self.store_snapshot(snapshot);
357
358 self.update_metrics();
360
361 self.last_validation_time = Some(timestamp);
362
363 Ok(())
364 }
365
366 pub fn validate_continuity(&self) -> TemporalResult<()> {
374 if self.snapshots.len() < 2 {
375 return Ok(());
376 }
377 if self.metrics.continuity_score < self.continuity_threshold {
378 return Err(TemporalError::IdentityContinuityBreak {
379 gap_ns: self.metrics.max_gap_duration_ns,
380 });
381 }
382
383 Ok(())
384 }
385
386 pub fn get_metrics(&self) -> TemporalResult<ContinuityMetrics> {
388 Ok(self.metrics.clone())
389 }
390
391 pub fn get_identity_stability(&self) -> f64 {
393 self.metrics.identity_stability
394 }
395
396 pub fn get_continuity_score(&self) -> f64 {
398 self.metrics.continuity_score
399 }
400
401 pub fn reset(&mut self) {
403 self.snapshots.clear();
404 self.metrics = ContinuityMetrics::default();
405 self.identity_baseline = None;
406 self.last_validation_time = None;
407 }
408
409 pub fn set_continuity_threshold(&mut self, threshold: f64) {
411 self.continuity_threshold = threshold.clamp(0.0, 1.0);
412 }
413
414 pub fn get_identity_trajectory(&self, window_size: usize) -> Vec<f64> {
416 self.snapshots
417 .iter()
418 .rev()
419 .take(window_size)
420 .map(|s| s.coherence_score)
421 .collect()
422 }
423
424 pub fn calculate_identity_drift(&self) -> f64 {
426 if let Some(baseline) = &self.identity_baseline {
427 if let Some(current) = self.snapshots.back() {
428 return 1.0 - baseline.calculate_similarity(current);
429 }
430 }
431 0.0
432 }
433
434 fn check_continuity_break(
437 &mut self,
438 current: &IdentitySnapshot,
439 previous: &IdentitySnapshot,
440 ) -> TemporalResult<()> {
441 let gap_ns = current
443 .timestamp
444 .nanos_since(previous.timestamp, 3_000_000_000);
445 if gap_ns > self.gap_tolerance_ns {
446 self.metrics.continuity_breaks += 1;
447 self.metrics.max_gap_duration_ns = self.metrics.max_gap_duration_ns.max(gap_ns);
448 }
449
450 let similarity = current.calculate_similarity(previous);
452 if similarity < self.continuity_threshold {
453 self.metrics.continuity_breaks += 1;
454 }
455
456 Ok(())
457 }
458
459 fn update_stability_metrics(&mut self, snapshot: &IdentitySnapshot) {
460 if self.snapshots.len() < 2 {
461 return;
462 }
463
464 let recent_snapshots: Vec<_> = self.snapshots.iter().rev().take(10).collect();
466
467 if recent_snapshots.len() >= 2 {
468 let mut similarities = Vec::new();
469
470 for i in 0..recent_snapshots.len() - 1 {
471 let sim = recent_snapshots[i].calculate_similarity(recent_snapshots[i + 1]);
472 similarities.push(sim);
473 }
474
475 let current_sim = snapshot.calculate_similarity(recent_snapshots[0]);
477 similarities.push(current_sim);
478
479 let avg_similarity = similarities.iter().sum::<f64>() / similarities.len() as f64;
481
482 let alpha = 0.1;
484 self.metrics.identity_stability =
485 (1.0 - alpha) * self.metrics.identity_stability + alpha * avg_similarity;
486 }
487 }
488
489 fn store_snapshot(&mut self, snapshot: IdentitySnapshot) {
490 self.snapshots.push_back(snapshot);
491
492 while self.snapshots.len() > self.max_snapshots {
494 self.snapshots.pop_front();
495 }
496 }
497
498 fn update_metrics(&mut self) {
499 if self.snapshots.len() < 2 {
500 return;
501 }
502
503 let mut total_similarity = 0.0;
505 let mut similarity_count = 0;
506
507 for window in self.snapshots.iter().collect::<Vec<_>>().windows(2) {
508 let sim = window[1].calculate_similarity(window[0]);
509 total_similarity += sim;
510 similarity_count += 1;
511 }
512
513 if similarity_count > 0 {
514 self.metrics.continuity_score = total_similarity / similarity_count as f64;
515 }
516
517 let coherence_scores: Vec<f64> = self.snapshots.iter().map(|s| s.coherence_score).collect();
519
520 if !coherence_scores.is_empty() {
521 self.metrics.identity_coherence =
522 coherence_scores.iter().sum::<f64>() / coherence_scores.len() as f64;
523 }
524
525 self.calculate_temporal_consistency();
527
528 self.calculate_preservation_efficiency();
530
531 self.update_gap_metrics();
533 }
534
535 fn calculate_temporal_consistency(&mut self) {
536 if self.snapshots.len() < 3 {
537 return;
538 }
539
540 let mut consistency_scores = Vec::new();
542
543 for i in 2..self.snapshots.len() {
544 let s1 = &self.snapshots[i - 2];
545 let s2 = &self.snapshots[i - 1];
546 let s3 = &self.snapshots[i];
547
548 let vel1: Vec<f64> = s2
550 .feature_vector
551 .iter()
552 .zip(s1.feature_vector.iter())
553 .map(|(a, b)| a - b)
554 .collect();
555
556 let vel2: Vec<f64> = s3
557 .feature_vector
558 .iter()
559 .zip(s2.feature_vector.iter())
560 .map(|(a, b)| a - b)
561 .collect();
562
563 let dot_product: f64 = vel1.iter().zip(vel2.iter()).map(|(a, b)| a * b).sum();
565 let mag1: f64 = vel1.iter().map(|x| x * x).sum::<f64>().sqrt();
566 let mag2: f64 = vel2.iter().map(|x| x * x).sum::<f64>().sqrt();
567
568 if mag1 > 0.0 && mag2 > 0.0 {
569 consistency_scores.push(dot_product / (mag1 * mag2));
570 }
571 }
572
573 if !consistency_scores.is_empty() {
574 self.metrics.temporal_consistency =
575 consistency_scores.iter().sum::<f64>() / consistency_scores.len() as f64;
576 }
577 }
578
579 fn calculate_preservation_efficiency(&mut self) {
580 if let Some(baseline) = &self.identity_baseline {
581 if let Some(current) = self.snapshots.back() {
582 let similarity_to_baseline = current.calculate_similarity(baseline);
584 let time_factor = 1.0 / (1.0 + self.snapshots.len() as f64 / 1000.0); self.metrics.preservation_efficiency = similarity_to_baseline * time_factor;
587 }
588 }
589 }
590
591 fn update_gap_metrics(&mut self) {
592 if self.snapshots.len() < 2 {
593 return;
594 }
595
596 let mut gaps = Vec::new();
597
598 for window in self.snapshots.iter().collect::<Vec<_>>().windows(2) {
599 let gap_ns = window[1]
600 .timestamp
601 .nanos_since(window[0].timestamp, 3_000_000_000);
602 gaps.push(gap_ns);
603 }
604
605 if !gaps.is_empty() {
606 self.metrics.average_gap_duration_ns =
607 gaps.iter().sum::<u64>() as f64 / gaps.len() as f64;
608 self.metrics.max_gap_duration_ns = *gaps.iter().max().unwrap_or(&0);
609 }
610 }
611}
612
613impl Default for IdentityContinuityTracker {
614 fn default() -> Self {
615 Self::new()
616 }
617}
618
619#[cfg(test)]
620mod tests {
621 use super::*;
622
623 #[test]
624 fn test_identity_snapshot_creation() {
625 let timestamp = TscTimestamp::now();
626 let state = vec![1, 2, 3, 4, 5];
627
628 let snapshot = IdentitySnapshot::new(timestamp, &state);
629 assert_eq!(snapshot.timestamp, timestamp);
630 assert!(!snapshot.feature_vector.is_empty());
631 assert!(snapshot.coherence_score >= 0.0 && snapshot.coherence_score <= 1.0);
632 }
633
634 #[test]
635 fn test_feature_extraction() {
636 let state = vec![1, 2, 3, 4, 5, 4, 3, 2, 1];
637 let features = IdentitySnapshot::extract_features(&state);
638
639 assert!(!features.is_empty());
640 for &feature in &features {
642 assert!(feature >= -1.0 && feature <= 1.0);
643 }
644 }
645
646 #[test]
647 fn test_similarity_calculation() {
648 let timestamp = TscTimestamp::now();
649 let state1 = vec![1, 2, 3, 4, 5];
650 let state2 = vec![1, 2, 3, 4, 5]; let state3 = vec![5, 4, 3, 2, 1]; let snapshot1 = IdentitySnapshot::new(timestamp, &state1);
654 let snapshot2 = IdentitySnapshot::new(timestamp, &state2);
655 let snapshot3 = IdentitySnapshot::new(timestamp, &state3);
656
657 let sim12 = snapshot1.calculate_similarity(&snapshot2);
658 let sim13 = snapshot1.calculate_similarity(&snapshot3);
659
660 assert!(sim12 > sim13); assert!(sim12 >= 0.0 && sim12 <= 1.0);
662 assert!(sim13 >= 0.0 && sim13 <= 1.0);
663 }
664
665 #[test]
666 fn test_continuity_tracker() {
667 let mut tracker = IdentityContinuityTracker::new();
668 let timestamp = TscTimestamp::now();
669 let state = vec![1, 2, 3, 4, 5];
670
671 tracker.track_continuity(timestamp, &state).unwrap();
672 assert_eq!(tracker.snapshots.len(), 1);
673
674 let timestamp2 = timestamp.add_nanos(1000, 3_000_000_000);
676 let state2 = vec![1, 2, 3, 4, 6]; tracker.track_continuity(timestamp2, &state2).unwrap();
679 assert_eq!(tracker.snapshots.len(), 2);
680
681 let metrics = tracker.get_metrics().unwrap();
682 assert!(metrics.continuity_score > 0.0);
683 }
684
685 #[test]
686 fn test_continuity_break_detection() {
687 let mut tracker = IdentityContinuityTracker::new();
688 tracker.set_continuity_threshold(0.9); let timestamp = TscTimestamp::now();
691 let state1 = vec![1, 2, 3, 4, 5];
692 let state2 = vec![10, 20, 30, 40, 50]; tracker.track_continuity(timestamp, &state1).unwrap();
695
696 let timestamp2 = timestamp.add_nanos(1000, 3_000_000_000);
697 tracker.track_continuity(timestamp2, &state2).unwrap();
698
699 assert!(tracker.metrics.continuity_breaks > 0);
701 }
702
703 #[test]
704 fn test_identity_drift_calculation() {
705 let mut tracker = IdentityContinuityTracker::new();
706 let timestamp = TscTimestamp::now();
707
708 let baseline_state = vec![1, 2, 3, 4, 5];
710 tracker
711 .track_continuity(timestamp, &baseline_state)
712 .unwrap();
713
714 for i in 1..=10 {
716 let timestamp_i = timestamp.add_nanos(i * 1000, 3_000_000_000);
717 let drifted_state = vec![1 + i as u8, 2, 3, 4, 5];
718 tracker
719 .track_continuity(timestamp_i, &drifted_state)
720 .unwrap();
721 }
722
723 let drift = tracker.calculate_identity_drift();
724 assert!(drift > 0.0); assert!(drift <= 1.0); }
727
728 #[test]
729 fn test_stability_metrics() {
730 let mut tracker = IdentityContinuityTracker::new();
731 let timestamp = TscTimestamp::now();
732
733 for i in 0..10 {
735 let timestamp_i = timestamp.add_nanos(i * 1000, 3_000_000_000);
736 let stable_state = vec![1, 2, 3, 4, 5]; tracker
738 .track_continuity(timestamp_i, &stable_state)
739 .unwrap();
740 }
741
742 assert!(tracker.get_identity_stability() > 0.5); }
744}