1180 lines
38 KiB
Rust
1180 lines
38 KiB
Rust
//! Comprehensive integration tests for all 24 vendor-integrated WASM edge modules.
|
|
//!
|
|
//! ADR-041 Category 7: Tests cover initialization, basic operation, and edge cases
|
|
//! for each module. At least 3 tests per module = 72+ tests total.
|
|
//!
|
|
//! Run with:
|
|
//! cd v2
|
|
//! cargo test -p wifi-densepose-wasm-edge --features std -- --nocapture
|
|
|
|
// ============================================================================
|
|
// Imports
|
|
// ============================================================================
|
|
|
|
// Signal Intelligence
|
|
use wifi_densepose_wasm_edge::sig_coherence_gate::{CoherenceGate, GateDecision};
|
|
use wifi_densepose_wasm_edge::sig_flash_attention::FlashAttention;
|
|
use wifi_densepose_wasm_edge::sig_temporal_compress::TemporalCompressor;
|
|
use wifi_densepose_wasm_edge::sig_sparse_recovery::{
|
|
SparseRecovery, EVENT_RECOVERY_COMPLETE, EVENT_DROPOUT_RATE,
|
|
};
|
|
use wifi_densepose_wasm_edge::sig_mincut_person_match::PersonMatcher;
|
|
use wifi_densepose_wasm_edge::sig_optimal_transport::{
|
|
OptimalTransportDetector,
|
|
};
|
|
|
|
// Adaptive Learning
|
|
use wifi_densepose_wasm_edge::lrn_dtw_gesture_learn::GestureLearner;
|
|
use wifi_densepose_wasm_edge::lrn_anomaly_attractor::{
|
|
AttractorDetector, AttractorType, EVENT_BASIN_DEPARTURE,
|
|
};
|
|
use wifi_densepose_wasm_edge::lrn_meta_adapt::MetaAdapter;
|
|
use wifi_densepose_wasm_edge::lrn_ewc_lifelong::EwcLifelong;
|
|
|
|
// Spatial Reasoning
|
|
use wifi_densepose_wasm_edge::spt_pagerank_influence::PageRankInfluence;
|
|
use wifi_densepose_wasm_edge::spt_micro_hnsw::{MicroHnsw, EVENT_NEAREST_MATCH_ID};
|
|
use wifi_densepose_wasm_edge::spt_spiking_tracker::{SpikingTracker, EVENT_SPIKE_RATE};
|
|
|
|
// Temporal Analysis
|
|
use wifi_densepose_wasm_edge::tmp_pattern_sequence::PatternSequenceAnalyzer;
|
|
use wifi_densepose_wasm_edge::tmp_temporal_logic_guard::{
|
|
TemporalLogicGuard, FrameInput, RuleState,
|
|
};
|
|
use wifi_densepose_wasm_edge::tmp_goap_autonomy::GoapPlanner;
|
|
|
|
// AI Security
|
|
use wifi_densepose_wasm_edge::ais_prompt_shield::{PromptShield, EVENT_REPLAY_ATTACK};
|
|
use wifi_densepose_wasm_edge::ais_behavioral_profiler::{
|
|
BehavioralProfiler, EVENT_BEHAVIOR_ANOMALY,
|
|
};
|
|
|
|
// Quantum-Inspired
|
|
use wifi_densepose_wasm_edge::qnt_quantum_coherence::QuantumCoherenceMonitor;
|
|
use wifi_densepose_wasm_edge::qnt_interference_search::{InterferenceSearch, Hypothesis};
|
|
|
|
// Autonomous Systems
|
|
use wifi_densepose_wasm_edge::aut_psycho_symbolic::{
|
|
PsychoSymbolicEngine, EVENT_INFERENCE_RESULT, EVENT_RULE_FIRED,
|
|
};
|
|
use wifi_densepose_wasm_edge::aut_self_healing_mesh::{
|
|
SelfHealingMesh, EVENT_COVERAGE_SCORE, EVENT_NODE_DEGRADED,
|
|
};
|
|
|
|
// Exotic / Research
|
|
use wifi_densepose_wasm_edge::exo_time_crystal::{TimeCrystalDetector, EVENT_CRYSTAL_DETECTED};
|
|
use wifi_densepose_wasm_edge::exo_hyperbolic_space::{
|
|
HyperbolicEmbedder, EVENT_HIERARCHY_LEVEL, EVENT_LOCATION_LABEL,
|
|
};
|
|
|
|
// ============================================================================
|
|
// Test Data Generators
|
|
// ============================================================================
|
|
|
|
/// Generate coherent phases (all subcarriers aligned).
|
|
fn coherent_phases(n: usize, value: f32) -> Vec<f32> {
|
|
vec![value; n]
|
|
}
|
|
|
|
/// Generate incoherent phases (spread across range).
|
|
fn incoherent_phases(n: usize) -> Vec<f32> {
|
|
(0..n)
|
|
.map(|i| -3.14159 + (i as f32) * (6.28318 / n as f32))
|
|
.collect()
|
|
}
|
|
|
|
/// Generate sine wave amplitudes.
|
|
fn sine_amplitudes(n: usize, amplitude: f32, period: usize) -> Vec<f32> {
|
|
(0..n)
|
|
.map(|i| {
|
|
let t = (i as f32) * 2.0 * 3.14159 / (period as f32);
|
|
amplitude * (1.0 + libm::sinf(t)) * 0.5 + 0.1
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
/// Generate uniform amplitudes.
|
|
fn uniform_amplitudes(n: usize, value: f32) -> Vec<f32> {
|
|
vec![value; n]
|
|
}
|
|
|
|
/// Generate ramp amplitudes.
|
|
fn ramp_amplitudes(n: usize, start: f32, end: f32) -> Vec<f32> {
|
|
(0..n)
|
|
.map(|i| start + (end - start) * (i as f32) / (n as f32 - 1.0))
|
|
.collect()
|
|
}
|
|
|
|
/// Generate variance pattern for multi-person tracking.
|
|
fn person_variance_pattern(n: usize, pattern_id: usize) -> Vec<f32> {
|
|
(0..n)
|
|
.map(|i| {
|
|
let base = (pattern_id as f32 + 1.0) * 0.3;
|
|
base + 0.1 * libm::sinf(i as f32 * (pattern_id as f32 + 1.0) * 0.5)
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
/// Generate a normal FrameInput for temporal logic guard.
|
|
fn normal_frame_input() -> FrameInput {
|
|
FrameInput {
|
|
presence: 1,
|
|
n_persons: 1,
|
|
motion_energy: 0.05,
|
|
coherence: 0.8,
|
|
breathing_bpm: 16.0,
|
|
heartrate_bpm: 72.0,
|
|
fall_alert: false,
|
|
intrusion_alert: false,
|
|
person_id_active: true,
|
|
vital_signs_active: true,
|
|
seizure_detected: false,
|
|
normal_gait: true,
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// 1. Signal Intelligence -- sig_coherence_gate (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn sig_coherence_gate_init() {
|
|
let gate = CoherenceGate::new();
|
|
assert_eq!(gate.frame_count(), 0);
|
|
assert_eq!(gate.gate(), GateDecision::Accept);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_coherence_gate_accepts_coherent_signal() {
|
|
let mut gate = CoherenceGate::new();
|
|
let phases = coherent_phases(16, 0.5);
|
|
for _ in 0..50 {
|
|
gate.process_frame(&phases);
|
|
}
|
|
assert_eq!(gate.gate(), GateDecision::Accept);
|
|
assert!(
|
|
gate.coherence() > 0.7,
|
|
"coherent signal should yield high coherence, got {}",
|
|
gate.coherence()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_coherence_gate_coherence_drops_with_noisy_deltas() {
|
|
let mut gate = CoherenceGate::new();
|
|
// Feed coherent signal (same phases each frame => zero deltas => coherence=1).
|
|
let phases = coherent_phases(16, 0.5);
|
|
for _ in 0..30 {
|
|
gate.process_frame(&phases);
|
|
}
|
|
let coh_before = gate.coherence();
|
|
// Feed phases that CHANGE between frames to produce incoherent deltas.
|
|
// Alternate between two different phase sets so the phase delta is spread.
|
|
let phases_a: Vec<f32> = (0..16).map(|i| (i as f32) * 0.3).collect();
|
|
let phases_b: Vec<f32> = (0..16).map(|i| (i as f32) * -0.5 + 1.0).collect();
|
|
for frame in 0..100 {
|
|
if frame % 2 == 0 {
|
|
gate.process_frame(&phases_a);
|
|
} else {
|
|
gate.process_frame(&phases_b);
|
|
}
|
|
}
|
|
let coh_after = gate.coherence();
|
|
// With non-uniform phase deltas, coherence should drop.
|
|
assert!(
|
|
coh_after < coh_before,
|
|
"noisy phase deltas should lower coherence: before={}, after={}",
|
|
coh_before, coh_after
|
|
);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2. Signal Intelligence -- sig_flash_attention (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn sig_flash_attention_init() {
|
|
let fa = FlashAttention::new();
|
|
assert_eq!(fa.frame_count(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_flash_attention_produces_weights() {
|
|
let mut fa = FlashAttention::new();
|
|
let phases = coherent_phases(32, 0.3);
|
|
let amps = sine_amplitudes(32, 5.0, 8);
|
|
fa.process_frame(&phases, &s);
|
|
fa.process_frame(&phases, &s);
|
|
let w = fa.weights();
|
|
let sum: f32 = w.iter().sum();
|
|
assert!(
|
|
(sum - 1.0).abs() < 0.1,
|
|
"attention weights should sum to ~1.0, got {}",
|
|
sum
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_flash_attention_focused_activity() {
|
|
let mut fa = FlashAttention::new();
|
|
let phases_a = coherent_phases(32, 0.1);
|
|
let amps_a = uniform_amplitudes(32, 1.0);
|
|
fa.process_frame(&phases_a, &s_a);
|
|
|
|
let mut phases_b = coherent_phases(32, 0.1);
|
|
for i in 0..4 {
|
|
phases_b[i] = 1.5;
|
|
}
|
|
let amps_b = uniform_amplitudes(32, 1.0);
|
|
for _ in 0..20 {
|
|
fa.process_frame(&phases_b, &s_b);
|
|
}
|
|
let entropy = fa.entropy();
|
|
assert!(
|
|
entropy < 2.5,
|
|
"focused activity should lower entropy, got {}",
|
|
entropy
|
|
);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 3. Signal Intelligence -- sig_temporal_compress (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn sig_temporal_compress_init() {
|
|
let tc = TemporalCompressor::new();
|
|
assert_eq!(tc.total_written(), 0);
|
|
assert_eq!(tc.occupied(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_temporal_compress_stores_frames() {
|
|
let mut tc = TemporalCompressor::new();
|
|
let phases = coherent_phases(8, 0.5);
|
|
let amps = uniform_amplitudes(8, 3.0);
|
|
for i in 0..100u32 {
|
|
tc.push_frame(&phases, &s, i);
|
|
}
|
|
assert!(tc.occupied() > 0, "should have stored frames");
|
|
assert_eq!(tc.total_written(), 100);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_temporal_compress_compression_ratio() {
|
|
let mut tc = TemporalCompressor::new();
|
|
let phases = coherent_phases(8, 0.5);
|
|
let amps = uniform_amplitudes(8, 3.0);
|
|
for i in 0..200u32 {
|
|
tc.push_frame(&phases, &s, i);
|
|
}
|
|
let ratio = tc.compression_ratio();
|
|
assert!(
|
|
ratio > 1.0,
|
|
"compression ratio should exceed 1.0, got {}",
|
|
ratio
|
|
);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 4. Signal Intelligence -- sig_sparse_recovery (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn sig_sparse_recovery_init() {
|
|
let sr = SparseRecovery::new();
|
|
assert!(!sr.is_initialized());
|
|
assert_eq!(sr.dropout_rate(), 0.0);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_sparse_recovery_no_dropout_passthrough() {
|
|
let mut sr = SparseRecovery::new();
|
|
for _ in 0..20 {
|
|
let mut amps: Vec<f32> = ramp_amplitudes(16, 1.0, 5.0);
|
|
sr.process_frame(&mut amps);
|
|
}
|
|
assert!(sr.is_initialized());
|
|
assert!(
|
|
sr.dropout_rate() < 0.15,
|
|
"no dropout should yield low rate, got {}",
|
|
sr.dropout_rate()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_sparse_recovery_handles_dropout() {
|
|
let mut sr = SparseRecovery::new();
|
|
for _ in 0..20 {
|
|
let mut amps = ramp_amplitudes(16, 1.0, 5.0);
|
|
sr.process_frame(&mut amps);
|
|
}
|
|
let mut amps_dropout = ramp_amplitudes(16, 1.0, 5.0);
|
|
for i in 0..6 {
|
|
amps_dropout[i] = 0.0;
|
|
}
|
|
let events = sr.process_frame(&mut amps_dropout);
|
|
let has_dropout = events.iter().any(|&(t, _)| t == EVENT_DROPOUT_RATE);
|
|
let has_recovery = events.iter().any(|&(t, _)| t == EVENT_RECOVERY_COMPLETE);
|
|
assert!(
|
|
has_dropout || has_recovery || sr.dropout_rate() > 0.2,
|
|
"should detect or recover from dropout"
|
|
);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 5. Signal Intelligence -- sig_mincut_person_match (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn sig_mincut_person_match_init() {
|
|
let pm = PersonMatcher::new();
|
|
assert_eq!(pm.active_persons(), 0);
|
|
assert_eq!(pm.total_swaps(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_mincut_person_match_tracks_one_person() {
|
|
let mut pm = PersonMatcher::new();
|
|
let amps = uniform_amplitudes(16, 1.0);
|
|
let vars = person_variance_pattern(16, 0);
|
|
for _ in 0..20 {
|
|
pm.process_frame(&s, &vars, 1);
|
|
}
|
|
assert_eq!(pm.active_persons(), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_mincut_person_match_too_few_subcarriers() {
|
|
let mut pm = PersonMatcher::new();
|
|
let amps = [1.0f32; 4];
|
|
let vars = [0.5f32; 4];
|
|
let events = pm.process_frame(&s, &vars, 1);
|
|
assert!(events.is_empty(), "too few subcarriers should return empty");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 6. Signal Intelligence -- sig_optimal_transport (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn sig_optimal_transport_init() {
|
|
let ot = OptimalTransportDetector::new();
|
|
assert_eq!(ot.frame_count(), 0);
|
|
assert_eq!(ot.distance(), 0.0);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_optimal_transport_identical_zero_distance() {
|
|
let mut ot = OptimalTransportDetector::new();
|
|
let amps = ramp_amplitudes(16, 1.0, 8.0);
|
|
ot.process_frame(&s);
|
|
ot.process_frame(&s);
|
|
assert!(
|
|
ot.distance() < 0.01,
|
|
"identical frames should produce ~0 distance, got {}",
|
|
ot.distance()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn sig_optimal_transport_distance_increases_with_shift() {
|
|
let mut ot = OptimalTransportDetector::new();
|
|
// Establish baseline with ramp amplitudes.
|
|
let a = ramp_amplitudes(16, 1.0, 8.0);
|
|
ot.process_frame(&a);
|
|
ot.process_frame(&a);
|
|
let d_same = ot.distance();
|
|
// Now shift to very different distribution.
|
|
let b = ramp_amplitudes(16, 50.0, 100.0);
|
|
ot.process_frame(&b);
|
|
let d_shifted = ot.distance();
|
|
assert!(
|
|
d_shifted > d_same,
|
|
"shifted distribution should increase distance: same={}, shifted={}",
|
|
d_same, d_shifted
|
|
);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 7. Adaptive Learning -- lrn_dtw_gesture_learn (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn lrn_dtw_gesture_learn_init() {
|
|
let gl = GestureLearner::new();
|
|
assert_eq!(gl.template_count(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn lrn_dtw_gesture_learn_stillness_detection() {
|
|
let mut gl = GestureLearner::new();
|
|
let phases = coherent_phases(8, 0.1);
|
|
for _ in 0..100 {
|
|
gl.process_frame(&phases, 0.01);
|
|
}
|
|
assert_eq!(gl.template_count(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn lrn_dtw_gesture_learn_processes_motion() {
|
|
let mut gl = GestureLearner::new();
|
|
let phases = coherent_phases(8, 0.1);
|
|
for cycle in 0..3 {
|
|
for _ in 0..70 {
|
|
gl.process_frame(&phases, 0.01);
|
|
}
|
|
for i in 0..30 {
|
|
let mut p = coherent_phases(8, 0.1);
|
|
p[0] = 0.1 + (i as f32) * 0.1;
|
|
gl.process_frame(&p, 0.5 + cycle as f32 * 0.01);
|
|
}
|
|
}
|
|
assert!(true, "gesture learner processed motion cycles without error");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 8. Adaptive Learning -- lrn_anomaly_attractor (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn lrn_anomaly_attractor_init() {
|
|
let det = AttractorDetector::new();
|
|
assert!(!det.is_initialized());
|
|
assert_eq!(det.attractor_type(), AttractorType::Unknown);
|
|
}
|
|
|
|
#[test]
|
|
fn lrn_anomaly_attractor_learns_stable_room() {
|
|
let mut det = AttractorDetector::new();
|
|
// Need tiny perturbations for Lyapunov computation (constant data gives
|
|
// zero deltas and lyapunov_count stays 0, blocking initialization).
|
|
for i in 0..220 {
|
|
let tiny = (i as f32) * 1e-5;
|
|
let phases = [0.1 + tiny; 8];
|
|
let amps = [1.0 + tiny; 8];
|
|
det.process_frame(&phases, &s, tiny);
|
|
}
|
|
assert!(det.is_initialized(), "should complete learning after 200+ frames");
|
|
let at = det.attractor_type();
|
|
assert!(at != AttractorType::Unknown, "should classify attractor after learning");
|
|
}
|
|
|
|
#[test]
|
|
fn lrn_anomaly_attractor_detects_departure() {
|
|
let mut det = AttractorDetector::new();
|
|
// Learn with tiny perturbations.
|
|
for i in 0..220 {
|
|
let tiny = (i as f32) * 1e-5;
|
|
let phases = [0.1 + tiny; 8];
|
|
let amps = [1.0 + tiny; 8];
|
|
det.process_frame(&phases, &s, tiny);
|
|
}
|
|
assert!(det.is_initialized());
|
|
// Inject a large departure.
|
|
let wild_phases = [5.0f32; 8];
|
|
let wild_amps = [50.0f32; 8];
|
|
let events = det.process_frame(&wild_phases, &wild_amps, 10.0);
|
|
let has_departure = events.iter().any(|&(id, _)| id == EVENT_BASIN_DEPARTURE);
|
|
assert!(has_departure, "large deviation should trigger basin departure");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 9. Adaptive Learning -- lrn_meta_adapt (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn lrn_meta_adapt_init() {
|
|
let ma = MetaAdapter::new();
|
|
assert_eq!(ma.iteration_count(), 0);
|
|
assert_eq!(ma.success_count(), 0);
|
|
assert_eq!(ma.meta_level(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn lrn_meta_adapt_default_params() {
|
|
let ma = MetaAdapter::new();
|
|
assert!((ma.get_param(0) - 0.05).abs() < 0.01);
|
|
assert!((ma.get_param(1) - 0.10).abs() < 0.01);
|
|
assert!((ma.get_param(2) - 0.70).abs() < 0.01);
|
|
assert_eq!(ma.get_param(99), 0.0);
|
|
}
|
|
|
|
#[test]
|
|
fn lrn_meta_adapt_optimization_cycle() {
|
|
let mut ma = MetaAdapter::new();
|
|
for _ in 0..10 {
|
|
ma.report_true_positive();
|
|
ma.on_timer();
|
|
}
|
|
for _ in 0..10 {
|
|
ma.report_true_positive();
|
|
ma.on_timer();
|
|
}
|
|
assert_eq!(ma.iteration_count(), 1, "should complete one optimization iteration");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 10. Adaptive Learning -- lrn_ewc_lifelong (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn lrn_ewc_lifelong_init() {
|
|
let ewc = EwcLifelong::new();
|
|
assert_eq!(ewc.task_count(), 0);
|
|
assert!(!ewc.has_prior_task());
|
|
assert_eq!(ewc.frame_count(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn lrn_ewc_lifelong_learns_and_predicts() {
|
|
let mut ewc = EwcLifelong::new();
|
|
let features = [0.5f32, 0.3, 0.8, 0.1, 0.6, 0.2, 0.9, 0.4];
|
|
let target_zone = 2;
|
|
|
|
for _ in 0..200 {
|
|
ewc.process_frame(&features, target_zone);
|
|
}
|
|
|
|
assert!(
|
|
ewc.last_loss() < 1.0,
|
|
"loss should decrease after training, got {}",
|
|
ewc.last_loss()
|
|
);
|
|
|
|
let p1 = ewc.predict(&features);
|
|
let p2 = ewc.predict(&features);
|
|
assert_eq!(p1, p2, "predict should be deterministic");
|
|
assert!(p1 < 4, "predicted zone should be 0-3");
|
|
}
|
|
|
|
#[test]
|
|
fn lrn_ewc_lifelong_penalty_zero_without_prior() {
|
|
let mut ewc = EwcLifelong::new();
|
|
let features = [1.0f32; 8];
|
|
ewc.process_frame(&features, 0);
|
|
assert!(!ewc.has_prior_task());
|
|
assert!(
|
|
ewc.last_penalty() < 1e-8,
|
|
"EWC penalty should be 0 without prior task, got {}",
|
|
ewc.last_penalty()
|
|
);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 11. Spatial Reasoning -- spt_pagerank_influence (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn spt_pagerank_influence_init() {
|
|
let pr = PageRankInfluence::new();
|
|
assert_eq!(pr.dominant_person(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn spt_pagerank_influence_single_person() {
|
|
let mut pr = PageRankInfluence::new();
|
|
let phases = coherent_phases(32, 0.5);
|
|
for _ in 0..20 {
|
|
pr.process_frame(&phases, 1);
|
|
}
|
|
let dom = pr.dominant_person();
|
|
assert!(dom < 4, "dominant person should be valid index");
|
|
}
|
|
|
|
#[test]
|
|
fn spt_pagerank_influence_multi_person() {
|
|
let mut pr = PageRankInfluence::new();
|
|
let mut phases = coherent_phases(32, 0.1);
|
|
for i in 0..8 {
|
|
phases[i] = 2.0 + (i as f32) * 0.5;
|
|
}
|
|
for _ in 0..30 {
|
|
pr.process_frame(&phases, 4);
|
|
}
|
|
let rank0 = pr.rank(0);
|
|
assert!(rank0 > 0.0, "person 0 should have nonzero rank");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 12. Spatial Reasoning -- spt_micro_hnsw (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn spt_micro_hnsw_init() {
|
|
let hnsw = MicroHnsw::new();
|
|
assert_eq!(hnsw.size(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn spt_micro_hnsw_insert_and_search() {
|
|
let mut hnsw = MicroHnsw::new();
|
|
let v1 = [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
|
|
let v2 = [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
|
|
hnsw.insert(&v1, 10);
|
|
hnsw.insert(&v2, 20);
|
|
assert_eq!(hnsw.size(), 2);
|
|
// search() returns (node_index, distance), not (label, distance).
|
|
// Use process_frame to get label via event emission, or just verify index.
|
|
let query = [0.9, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
|
|
let (node_idx, dist) = hnsw.search(&query);
|
|
assert_eq!(node_idx, 0, "should match node 0 (closest to v1)");
|
|
assert!(dist < 1.0, "distance should be small");
|
|
// Verify label via process_frame event or last_label.
|
|
hnsw.process_frame(&query);
|
|
assert_eq!(hnsw.last_label(), 10, "label should be 10 for closest match");
|
|
}
|
|
|
|
#[test]
|
|
fn spt_micro_hnsw_process_frame_emits_events() {
|
|
let mut hnsw = MicroHnsw::new();
|
|
let v1 = [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
|
|
hnsw.insert(&v1, 42);
|
|
let query = [1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
|
|
let events = hnsw.process_frame(&query);
|
|
let has_match = events.iter().any(|&(t, _)| t == EVENT_NEAREST_MATCH_ID);
|
|
assert!(has_match, "process_frame should emit match events");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 13. Spatial Reasoning -- spt_spiking_tracker (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn spt_spiking_tracker_init() {
|
|
let st = SpikingTracker::new();
|
|
assert_eq!(st.current_zone(), -1);
|
|
assert!(!st.is_tracking());
|
|
}
|
|
|
|
#[test]
|
|
fn spt_spiking_tracker_activates_zone() {
|
|
let mut st = SpikingTracker::new();
|
|
// Alternate between two frame states so the input spiking neurons see
|
|
// large phase changes only in the zone-0 subcarriers (0..7).
|
|
let prev = [0.0f32; 32];
|
|
let mut active = [0.0f32; 32];
|
|
for i in 0..8 {
|
|
active[i] = 2.0; // Strong activity in zone 0 subcarriers.
|
|
}
|
|
for frame in 0..60 {
|
|
if frame % 2 == 0 {
|
|
st.process_frame(&active, &prev);
|
|
} else {
|
|
st.process_frame(&prev, &active);
|
|
}
|
|
}
|
|
// Zone 0 should have tracking activity.
|
|
let current = st.current_zone();
|
|
let is_tracking = st.is_tracking();
|
|
// At minimum, the tracker should process without panic and produce zone rates.
|
|
let r0 = st.zone_spike_rate(0);
|
|
assert!(
|
|
r0 > 0.0 || is_tracking,
|
|
"zone 0 should show activity or tracker should be active: r0={}, zone={}, tracking={}",
|
|
r0, current, is_tracking
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn spt_spiking_tracker_no_activity_no_track() {
|
|
let mut st = SpikingTracker::new();
|
|
let phases = [0.0f32; 32];
|
|
let prev = [0.0f32; 32];
|
|
st.process_frame(&phases, &prev);
|
|
assert!(!st.is_tracking());
|
|
let events = st.process_frame(&phases, &prev);
|
|
let has_spike_rate = events.iter().any(|&(t, _)| t == EVENT_SPIKE_RATE);
|
|
assert!(has_spike_rate, "should emit spike rate even without tracking");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 14. Temporal Analysis -- tmp_pattern_sequence (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn tmp_pattern_sequence_init() {
|
|
let psa = PatternSequenceAnalyzer::new();
|
|
assert_eq!(psa.pattern_count(), 0);
|
|
assert_eq!(psa.current_minute(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn tmp_pattern_sequence_records_events() {
|
|
let mut psa = PatternSequenceAnalyzer::new();
|
|
for min in 0..120 {
|
|
for _ in 0..20 {
|
|
psa.on_frame(1, 0.3, min);
|
|
}
|
|
}
|
|
assert!(psa.current_minute() <= 120);
|
|
}
|
|
|
|
#[test]
|
|
fn tmp_pattern_sequence_on_timer() {
|
|
let mut psa = PatternSequenceAnalyzer::new();
|
|
for min in 0..60 {
|
|
for _ in 0..20 {
|
|
psa.on_frame(1, 0.5, min);
|
|
}
|
|
}
|
|
let events = psa.on_timer();
|
|
assert!(events.len() <= 4, "events should be bounded");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 15. Temporal Analysis -- tmp_temporal_logic_guard (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn tmp_temporal_logic_guard_init() {
|
|
let guard = TemporalLogicGuard::new();
|
|
assert_eq!(guard.satisfied_count(), 8);
|
|
assert_eq!(guard.frame_index(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn tmp_temporal_logic_guard_normal_all_satisfied() {
|
|
let mut guard = TemporalLogicGuard::new();
|
|
let input = normal_frame_input();
|
|
for _ in 0..100 {
|
|
guard.on_frame(&input);
|
|
}
|
|
assert_eq!(guard.satisfied_count(), 8, "normal input should satisfy all 8 rules");
|
|
}
|
|
|
|
#[test]
|
|
fn tmp_temporal_logic_guard_detects_violation() {
|
|
let mut guard = TemporalLogicGuard::new();
|
|
let mut input = FrameInput::default();
|
|
input.presence = 0;
|
|
input.fall_alert = true;
|
|
// Drop result to avoid borrow conflict with guard.
|
|
let _ = guard.on_frame(&input);
|
|
assert_eq!(guard.rule_state(0), RuleState::Violated);
|
|
assert_eq!(guard.violation_count(0), 1);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 16. Temporal Analysis -- tmp_goap_autonomy (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn tmp_goap_autonomy_init() {
|
|
let planner = GoapPlanner::new();
|
|
assert_eq!(planner.world_state(), 0);
|
|
assert_eq!(planner.current_goal(), 0xFF);
|
|
assert_eq!(planner.plan_len(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn tmp_goap_autonomy_world_state_update() {
|
|
let mut planner = GoapPlanner::new();
|
|
planner.update_world(1, 0.5, 2, 0.8, 0.1, true, false);
|
|
assert!(planner.has_property(0), "should have presence");
|
|
assert!(planner.has_property(1), "should have motion");
|
|
assert!(planner.has_property(6), "should have vitals");
|
|
}
|
|
|
|
#[test]
|
|
fn tmp_goap_autonomy_plans_and_executes() {
|
|
let mut planner = GoapPlanner::new();
|
|
planner.set_goal_priority(5, 0.99);
|
|
planner.update_world(0, 0.0, 0, 0.3, 0.0, false, false);
|
|
for _ in 0..60 {
|
|
planner.on_timer();
|
|
}
|
|
let _events = planner.on_timer();
|
|
// plan_step() returns u8; verify planning occurred
|
|
let _ = planner.plan_step();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 17. AI Security -- ais_prompt_shield (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn ais_prompt_shield_init() {
|
|
let ps = PromptShield::new();
|
|
assert_eq!(ps.frame_count(), 0);
|
|
assert!(!ps.is_calibrated());
|
|
}
|
|
|
|
#[test]
|
|
fn ais_prompt_shield_calibrates() {
|
|
let mut ps = PromptShield::new();
|
|
for i in 0..100u32 {
|
|
ps.process_frame(&[(i as f32) * 0.01; 16], &[1.0; 16]);
|
|
}
|
|
assert!(ps.is_calibrated(), "should be calibrated after 100 frames");
|
|
}
|
|
|
|
#[test]
|
|
fn ais_prompt_shield_detects_replay() {
|
|
let mut ps = PromptShield::new();
|
|
for i in 0..100u32 {
|
|
ps.process_frame(&[(i as f32) * 0.02; 16], &[1.0; 16]);
|
|
}
|
|
assert!(ps.is_calibrated());
|
|
let rp = [99.0f32; 16];
|
|
let ra = [2.5f32; 16];
|
|
ps.process_frame(&rp, &ra);
|
|
let events = ps.process_frame(&rp, &ra);
|
|
let replay_detected = events.iter().any(|&(t, _)| t == EVENT_REPLAY_ATTACK);
|
|
assert!(replay_detected, "should detect replay attack");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 18. AI Security -- ais_behavioral_profiler (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn ais_behavioral_profiler_init() {
|
|
let bp = BehavioralProfiler::new();
|
|
assert_eq!(bp.frame_count(), 0);
|
|
assert!(!bp.is_mature());
|
|
assert_eq!(bp.total_anomalies(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn ais_behavioral_profiler_matures() {
|
|
let mut bp = BehavioralProfiler::new();
|
|
for _ in 0..1000 {
|
|
bp.process_frame(true, 0.5, 1);
|
|
}
|
|
assert!(bp.is_mature(), "should mature after 1000 frames");
|
|
}
|
|
|
|
#[test]
|
|
fn ais_behavioral_profiler_detects_anomaly() {
|
|
let mut bp = BehavioralProfiler::new();
|
|
// Vary behavior across observation windows so Welford stats build non-zero
|
|
// variance. Each observation window is 200 frames; we need 5 cycles.
|
|
for i in 0..1000u32 {
|
|
let window_id = i / 200;
|
|
let pres = window_id % 2 != 0;
|
|
let mot = 0.1 + (window_id as f32) * 0.05;
|
|
let per = (window_id % 3) as u8;
|
|
bp.process_frame(pres, mot, per);
|
|
}
|
|
assert!(bp.is_mature());
|
|
// Inject dramatically different behavior.
|
|
let mut found = false;
|
|
for _ in 0..4000 {
|
|
let ev = bp.process_frame(true, 10.0, 5);
|
|
if ev.iter().any(|&(t, _)| t == EVENT_BEHAVIOR_ANOMALY) {
|
|
found = true;
|
|
}
|
|
}
|
|
assert!(found, "dramatic behavior change should trigger anomaly");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 19. Quantum-Inspired -- qnt_quantum_coherence (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn qnt_quantum_coherence_init() {
|
|
let mon = QuantumCoherenceMonitor::new();
|
|
assert_eq!(mon.frame_count(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn qnt_quantum_coherence_uniform_high_coherence() {
|
|
let mut mon = QuantumCoherenceMonitor::new();
|
|
let phases = coherent_phases(16, 0.0);
|
|
for _ in 0..21 {
|
|
mon.process_frame(&phases);
|
|
}
|
|
let coh = mon.coherence();
|
|
assert!(
|
|
(coh - 1.0).abs() < 0.1,
|
|
"zero phases should give coherence ~1.0, got {}",
|
|
coh
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn qnt_quantum_coherence_spread_low_coherence() {
|
|
let mut mon = QuantumCoherenceMonitor::new();
|
|
let phases = incoherent_phases(32);
|
|
for _ in 0..51 {
|
|
mon.process_frame(&phases);
|
|
}
|
|
let coh = mon.coherence();
|
|
assert!(coh < 0.5, "spread phases should yield low coherence, got {}", coh);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 20. Quantum-Inspired -- qnt_interference_search (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn qnt_interference_search_init_uniform() {
|
|
let search = InterferenceSearch::new();
|
|
assert_eq!(search.iterations(), 0);
|
|
assert!(!search.is_converged());
|
|
let expected = 1.0 / 16.0;
|
|
let p = search.probability(Hypothesis::Empty);
|
|
assert!(
|
|
(p - expected).abs() < 0.01,
|
|
"initial probability should be ~{}, got {}",
|
|
expected, p
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn qnt_interference_search_empty_room_converges() {
|
|
let mut search = InterferenceSearch::new();
|
|
for _ in 0..100 {
|
|
search.process_frame(0, 0.0, 0);
|
|
}
|
|
assert_eq!(search.winner(), Hypothesis::Empty);
|
|
// The Grover-inspired diffusion amplifies the oracle-matching hypothesis.
|
|
// With 16 hypotheses the initial probability is 1/16 = 0.0625, so any
|
|
// amplification above that confirms the oracle is working.
|
|
assert!(
|
|
search.winner_probability() > 0.1,
|
|
"should amplify Empty hypothesis above initial 0.0625, got {}",
|
|
search.winner_probability()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn qnt_interference_search_normalization_preserved() {
|
|
let mut search = InterferenceSearch::new();
|
|
for _ in 0..50 {
|
|
search.process_frame(1, 0.5, 1);
|
|
}
|
|
let total_prob = search.probability(Hypothesis::Empty)
|
|
+ search.probability(Hypothesis::PersonZoneA)
|
|
+ search.probability(Hypothesis::PersonZoneB)
|
|
+ search.probability(Hypothesis::PersonZoneC)
|
|
+ search.probability(Hypothesis::PersonZoneD)
|
|
+ search.probability(Hypothesis::TwoPersons)
|
|
+ search.probability(Hypothesis::ThreePersons)
|
|
+ search.probability(Hypothesis::MovingLeft)
|
|
+ search.probability(Hypothesis::MovingRight)
|
|
+ search.probability(Hypothesis::Sitting)
|
|
+ search.probability(Hypothesis::Standing)
|
|
+ search.probability(Hypothesis::Falling)
|
|
+ search.probability(Hypothesis::Exercising)
|
|
+ search.probability(Hypothesis::Sleeping)
|
|
+ search.probability(Hypothesis::Cooking)
|
|
+ search.probability(Hypothesis::Working);
|
|
assert!(
|
|
(total_prob - 1.0).abs() < 0.05,
|
|
"total probability should be ~1.0, got {}",
|
|
total_prob
|
|
);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 21. Autonomous Systems -- aut_psycho_symbolic (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn aut_psycho_symbolic_init() {
|
|
let engine = PsychoSymbolicEngine::new();
|
|
assert_eq!(engine.frame_count(), 0);
|
|
assert_eq!(engine.fired_rules(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn aut_psycho_symbolic_empty_room() {
|
|
let mut engine = PsychoSymbolicEngine::new();
|
|
engine.set_coherence(0.8);
|
|
let events = engine.process_frame(0.0, 2.0, 0.0, 0.0, 0.0, 1.0);
|
|
let result = events.iter().find(|e| e.0 == EVENT_INFERENCE_RESULT);
|
|
assert!(result.is_some(), "should produce inference for empty room");
|
|
assert_eq!(result.unwrap().1 as u8, 15);
|
|
}
|
|
|
|
#[test]
|
|
fn aut_psycho_symbolic_fires_rules() {
|
|
let mut engine = PsychoSymbolicEngine::new();
|
|
engine.set_coherence(0.8);
|
|
let events = engine.process_frame(1.0, 10.0, 15.0, 70.0, 1.0, 1.0);
|
|
let rule_fired_count = events.iter().filter(|e| e.0 == EVENT_RULE_FIRED).count();
|
|
assert!(rule_fired_count >= 1, "should fire at least one rule");
|
|
}
|
|
|
|
// ============================================================================
|
|
// 22. Autonomous Systems -- aut_self_healing_mesh (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn aut_self_healing_mesh_init() {
|
|
let mesh = SelfHealingMesh::new();
|
|
assert_eq!(mesh.frame_count(), 0);
|
|
assert_eq!(mesh.active_nodes(), 0);
|
|
assert!(!mesh.is_healing());
|
|
}
|
|
|
|
#[test]
|
|
fn aut_self_healing_mesh_healthy_nodes() {
|
|
let mut mesh = SelfHealingMesh::new();
|
|
let qualities = [0.9, 0.85, 0.88, 0.92];
|
|
let events = mesh.process_frame(&qualities);
|
|
let cov_ev = events.iter().find(|e| e.0 == EVENT_COVERAGE_SCORE);
|
|
assert!(cov_ev.is_some(), "should emit coverage score event");
|
|
assert!(
|
|
cov_ev.unwrap().1 > 0.8,
|
|
"healthy mesh should have high coverage, got {}",
|
|
cov_ev.unwrap().1
|
|
);
|
|
assert!(!mesh.is_healing(), "healthy mesh should not be healing");
|
|
}
|
|
|
|
#[test]
|
|
fn aut_self_healing_mesh_detects_degradation() {
|
|
let mut mesh = SelfHealingMesh::new();
|
|
let fragile_qualities = [0.9, 0.05, 0.85, 0.88];
|
|
for _ in 0..20 {
|
|
mesh.process_frame(&fragile_qualities);
|
|
}
|
|
let events = mesh.process_frame(&fragile_qualities);
|
|
let has_degraded = events.iter().any(|e| e.0 == EVENT_NODE_DEGRADED);
|
|
assert!(
|
|
mesh.is_healing() || has_degraded,
|
|
"fragile mesh should trigger healing or node degraded event"
|
|
);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 23. Exotic -- exo_time_crystal (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn exo_time_crystal_init() {
|
|
let tc = TimeCrystalDetector::new();
|
|
assert_eq!(tc.frame_count(), 0);
|
|
assert_eq!(tc.multiplier(), 0);
|
|
assert_eq!(tc.coordination_index(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn exo_time_crystal_constant_no_detection() {
|
|
let mut tc = TimeCrystalDetector::new();
|
|
for _ in 0..256 {
|
|
let events = tc.process_frame(1.0);
|
|
for ev in events {
|
|
assert_ne!(ev.0, EVENT_CRYSTAL_DETECTED, "constant signal should not detect crystal");
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn exo_time_crystal_periodic_autocorrelation() {
|
|
let mut tc = TimeCrystalDetector::new();
|
|
for frame in 0..256 {
|
|
let val = if (frame % 10) < 5 { 1.0 } else { 0.0 };
|
|
tc.process_frame(val);
|
|
}
|
|
let acorr = tc.autocorrelation()[9];
|
|
assert!(
|
|
acorr > 0.5,
|
|
"periodic signal should produce strong autocorrelation at period lag, got {}",
|
|
acorr
|
|
);
|
|
}
|
|
|
|
// ============================================================================
|
|
// 24. Exotic -- exo_hyperbolic_space (3 tests)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn exo_hyperbolic_space_init() {
|
|
let he = HyperbolicEmbedder::new();
|
|
assert_eq!(he.frame_count(), 0);
|
|
assert_eq!(he.label(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn exo_hyperbolic_space_emits_three_events() {
|
|
let mut he = HyperbolicEmbedder::new();
|
|
let amps = uniform_amplitudes(32, 10.0);
|
|
let events = he.process_frame(&s);
|
|
assert_eq!(events.len(), 3, "should emit hierarchy, radius, label events");
|
|
assert_eq!(events[0].0, EVENT_HIERARCHY_LEVEL);
|
|
assert_eq!(events[2].0, EVENT_LOCATION_LABEL);
|
|
}
|
|
|
|
#[test]
|
|
fn exo_hyperbolic_space_label_in_range() {
|
|
let mut he = HyperbolicEmbedder::new();
|
|
let amps = uniform_amplitudes(32, 10.0);
|
|
for _ in 0..20 {
|
|
let events = he.process_frame(&s);
|
|
if events.len() == 3 {
|
|
let label = events[2].1 as u8;
|
|
assert!(label < 16, "label {} should be < 16", label);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Cross-module integration tests (bonus)
|
|
// ============================================================================
|
|
|
|
#[test]
|
|
fn cross_module_coherence_gate_feeds_attractor() {
|
|
let mut gate = CoherenceGate::new();
|
|
let mut attractor = AttractorDetector::new();
|
|
|
|
// Use tiny perturbations so attractor's Lyapunov count accumulates.
|
|
for i in 0..220 {
|
|
let tiny = (i as f32) * 1e-5;
|
|
let phases: Vec<f32> = (0..16).map(|_| 0.3 + tiny).collect();
|
|
let amps: Vec<f32> = (0..8).map(|_| 1.0 + tiny).collect();
|
|
gate.process_frame(&phases);
|
|
let coh = gate.coherence();
|
|
attractor.process_frame(&phases[..8], &s, coh);
|
|
}
|
|
assert!(attractor.is_initialized(), "attractor should learn from gate-fed data");
|
|
}
|
|
|
|
#[test]
|
|
fn cross_module_shield_and_coherence() {
|
|
let mut shield = PromptShield::new();
|
|
let mut qc = QuantumCoherenceMonitor::new();
|
|
|
|
for i in 0..100u32 {
|
|
let phases = coherent_phases(16, (i as f32) * 0.01);
|
|
let amps = uniform_amplitudes(16, 1.0);
|
|
shield.process_frame(&phases, &s);
|
|
qc.process_frame(&phases);
|
|
}
|
|
assert!(shield.is_calibrated());
|
|
assert_eq!(qc.frame_count(), 100);
|
|
}
|
|
|
|
#[test]
|
|
fn cross_module_all_modules_construct() {
|
|
let _cg = CoherenceGate::new();
|
|
let _fa = FlashAttention::new();
|
|
let _tc = TemporalCompressor::new();
|
|
let _sr = SparseRecovery::new();
|
|
let _pm = PersonMatcher::new();
|
|
let _ot = OptimalTransportDetector::new();
|
|
let _gl = GestureLearner::new();
|
|
let _ad = AttractorDetector::new();
|
|
let _ma = MetaAdapter::new();
|
|
let _ewc = EwcLifelong::new();
|
|
let _pr = PageRankInfluence::new();
|
|
let _hnsw = MicroHnsw::new();
|
|
let _st = SpikingTracker::new();
|
|
let _psa = PatternSequenceAnalyzer::new();
|
|
let _tlg = TemporalLogicGuard::new();
|
|
let _gp = GoapPlanner::new();
|
|
let _ps = PromptShield::new();
|
|
let _bp = BehavioralProfiler::new();
|
|
let _qcm = QuantumCoherenceMonitor::new();
|
|
let _is = InterferenceSearch::new();
|
|
let _pse = PsychoSymbolicEngine::new();
|
|
let _shm = SelfHealingMesh::new();
|
|
let _tcd = TimeCrystalDetector::new();
|
|
let _he = HyperbolicEmbedder::new();
|
|
assert!(true, "all 24 vendor modules constructed successfully");
|
|
}
|