Skip to main content

sublinear_solver/temporal_nexus/quantum/
validators.rs

1//! Energy-Time Uncertainty Relation Validators
2//!
3//! This module implements validation of the Heisenberg uncertainty principle
4//! for energy and time, ensuring that temporal consciousness operations
5//! respect fundamental quantum mechanical constraints.
6//!
7//! ## Heisenberg Uncertainty Principle
8//!
9//! The energy-time uncertainty relation states:
10//! ```text
11//! ΔE · Δt ≥ ℏ/2
12//! ```
13//!
14//! Where:
15//! - ΔE: energy uncertainty (or energy scale of the process)
16//! - Δt: time uncertainty (or duration of the process)
17//! - ℏ: reduced Planck constant
18//!
19//! This principle fundamentally limits the precision with which we can
20//! simultaneously know the energy and timing of quantum processes.
21
22use crate::temporal_nexus::quantum::{constants, QuantumError, QuantumResult};
23
24/// Energy-time uncertainty principle validator
25#[derive(Debug, Clone)]
26pub struct UncertaintyValidator {
27    /// Reduced Planck constant
28    hbar: f64,
29    /// Minimum energy scale for consciousness (J)
30    min_consciousness_energy: f64,
31    /// Temperature for thermal energy calculations (K)
32    temperature: f64,
33}
34
35impl UncertaintyValidator {
36    /// Create new uncertainty validator
37    pub fn new() -> Self {
38        Self {
39            hbar: constants::PLANCK_HBAR,
40            min_consciousness_energy: 1e-18, // 1 attojoule minimum
41            temperature: constants::ROOM_TEMPERATURE_K,
42        }
43    }
44
45    /// Create validator with custom temperature
46    pub fn with_temperature(temperature_k: f64) -> Self {
47        Self {
48            hbar: constants::PLANCK_HBAR,
49            min_consciousness_energy: 1e-18,
50            temperature: temperature_k,
51        }
52    }
53
54    /// Calculate minimum uncertainty product
55    pub fn minimum_uncertainty_product(&self) -> f64 {
56        self.hbar / 2.0
57    }
58
59    /// Calculate thermal energy at current temperature
60    pub fn thermal_energy(&self) -> f64 {
61        constants::BOLTZMANN_K * self.temperature
62    }
63
64    /// Validate energy-time uncertainty relation
65    pub fn validate_energy_time_product(
66        &self,
67        energy_j: f64,
68        time_s: f64,
69    ) -> QuantumResult<UncertaintyResult> {
70        let product = energy_j * time_s;
71        let min_product = self.minimum_uncertainty_product();
72        let is_valid = product >= min_product;
73
74        // Calculate energy in electron volts for reporting
75        let energy_ev = energy_j / constants::EV_TO_JOULES;
76        let thermal_energy_j = self.thermal_energy();
77        let thermal_energy_ev = thermal_energy_j / constants::EV_TO_JOULES;
78
79        if !is_valid {
80            return Err(QuantumError::UncertaintyViolation {
81                product,
82                hbar_half: min_product,
83            });
84        }
85
86        Ok(UncertaintyResult {
87            is_valid,
88            energy_j,
89            energy_ev,
90            time_s,
91            uncertainty_product: product,
92            minimum_product: min_product,
93            margin: product / min_product,
94            thermal_energy_j,
95            thermal_energy_ev,
96            temperature_k: self.temperature,
97            energy_scale_classification: self.classify_energy_scale(energy_j),
98        })
99    }
100
101    /// Classify energy scale for consciousness operations
102    pub fn classify_energy_scale(&self, energy_j: f64) -> EnergyScale {
103        let energy_ev = energy_j / constants::EV_TO_JOULES;
104        let _thermal_ev = self.thermal_energy() / constants::EV_TO_JOULES;
105
106        if energy_ev < 1e-6 {
107            EnergyScale::SubAttoElectronVolt
108        } else if energy_ev < 1e-3 {
109            EnergyScale::AttoElectronVolt
110        } else if energy_ev < 1.0 {
111            EnergyScale::MilliElectronVolt
112        } else if energy_ev < 1000.0 {
113            EnergyScale::ElectronVolt
114        } else if energy_ev < 1e6 {
115            EnergyScale::KiloElectronVolt
116        } else {
117            EnergyScale::MegaElectronVolt
118        }
119    }
120
121    /// Calculate required energy for given time constraint
122    pub fn calculate_required_energy(&self, time_constraint_s: f64) -> f64 {
123        self.minimum_uncertainty_product() / time_constraint_s
124    }
125
126    /// Calculate maximum time for given energy budget.
127    ///
128    /// From ΔE · Δt ≥ ℏ/2: t_max = (ℏ/2) / E. The previous implementation
129    /// divided in the opposite direction, which has units of 1/time (a
130    /// frequency-like quantity), so a 1 ns target round-tripped to 1 GHz
131    /// instead of 1 ns and `test_energy_time_consistency` would fail.
132    pub fn calculate_maximum_time(&self, energy_budget_j: f64) -> f64 {
133        if energy_budget_j <= 0.0 {
134            return 0.0;
135        }
136        self.minimum_uncertainty_product() / energy_budget_j
137    }
138
139    /// Validate nanosecond consciousness energy requirements
140    pub fn validate_nanosecond_consciousness(&self) -> UncertaintyResult {
141        let nanosecond = 1e-9;
142        let required_energy = self.calculate_required_energy(nanosecond);
143
144        self.validate_energy_time_product(required_energy, nanosecond)
145            .unwrap_or_else(|_| UncertaintyResult {
146                is_valid: false,
147                energy_j: required_energy,
148                energy_ev: required_energy / constants::EV_TO_JOULES,
149                time_s: nanosecond,
150                uncertainty_product: required_energy * nanosecond,
151                minimum_product: self.minimum_uncertainty_product(),
152                margin: 1.0,
153                thermal_energy_j: self.thermal_energy(),
154                thermal_energy_ev: self.thermal_energy() / constants::EV_TO_JOULES,
155                temperature_k: self.temperature,
156                energy_scale_classification: self.classify_energy_scale(required_energy),
157            })
158    }
159
160    /// Analyze uncertainty constraints across time scales
161    pub fn analyze_time_scales(&self) -> UncertaintyAnalysis {
162        let scales = vec![
163            ("attosecond", 1e-18),
164            ("femtosecond", 1e-15),
165            ("picosecond", 1e-12),
166            ("nanosecond", 1e-9),
167            ("microsecond", 1e-6),
168            ("millisecond", 1e-3),
169        ];
170
171        let mut constraints = Vec::new();
172
173        for (name, time_s) in scales {
174            let required_energy_j = self.calculate_required_energy(time_s);
175            let required_energy_ev = required_energy_j / constants::EV_TO_JOULES;
176            let thermal_ratio = required_energy_j / self.thermal_energy();
177
178            constraints.push(UncertaintyConstraint {
179                scale_name: name.to_string(),
180                time_s,
181                required_energy_j,
182                required_energy_ev,
183                thermal_energy_ratio: thermal_ratio,
184                is_above_thermal: thermal_ratio > 1.0,
185                is_feasible: required_energy_ev < 1000.0, // 1 keV practical limit
186                energy_scale: self.classify_energy_scale(required_energy_j),
187            });
188        }
189
190        UncertaintyAnalysis {
191            temperature_k: self.temperature,
192            thermal_energy_j: self.thermal_energy(),
193            thermal_energy_ev: self.thermal_energy() / constants::EV_TO_JOULES,
194            hbar: self.hbar,
195            minimum_product: self.minimum_uncertainty_product(),
196            constraints,
197            recommended_scale: "nanosecond".to_string(),
198        }
199    }
200}
201
202impl Default for UncertaintyValidator {
203    fn default() -> Self {
204        Self::new()
205    }
206}
207
208/// Result of uncertainty relation validation
209#[derive(Debug, Clone)]
210pub struct UncertaintyResult {
211    pub is_valid: bool,
212    pub energy_j: f64,
213    pub energy_ev: f64,
214    pub time_s: f64,
215    pub uncertainty_product: f64,
216    pub minimum_product: f64,
217    pub margin: f64,
218    pub thermal_energy_j: f64,
219    pub thermal_energy_ev: f64,
220    pub temperature_k: f64,
221    pub energy_scale_classification: EnergyScale,
222}
223
224impl UncertaintyResult {
225    /// Get human-readable summary
226    pub fn summary(&self) -> String {
227        format!(
228            "Uncertainty Check: {} (ΔE·Δt = {:.2e}, min = {:.2e}, margin = {:.1}x)",
229            if self.is_valid { "PASS" } else { "FAIL" },
230            self.uncertainty_product,
231            self.minimum_product,
232            self.margin
233        )
234    }
235}
236
237/// Energy scale classification for consciousness operations
238#[derive(Debug, Clone, PartialEq)]
239pub enum EnergyScale {
240    SubAttoElectronVolt, // < 1 aeV
241    AttoElectronVolt,    // 1 aeV - 1 feV
242    MilliElectronVolt,   // 1 feV - 1 eV
243    ElectronVolt,        // 1 eV - 1 keV
244    KiloElectronVolt,    // 1 keV - 1 MeV
245    MegaElectronVolt,    // > 1 MeV
246}
247
248impl EnergyScale {
249    pub fn description(&self) -> &'static str {
250        match self {
251            EnergyScale::SubAttoElectronVolt => "Sub-atto-eV (quantum vacuum scale)",
252            EnergyScale::AttoElectronVolt => "Atto-eV (ultra-low energy)",
253            EnergyScale::MilliElectronVolt => "Milli-eV (molecular vibrations)",
254            EnergyScale::ElectronVolt => "eV (atomic scale)",
255            EnergyScale::KiloElectronVolt => "keV (X-ray scale)",
256            EnergyScale::MegaElectronVolt => "MeV (nuclear scale)",
257        }
258    }
259}
260
261/// Analysis of uncertainty constraints across time scales
262#[derive(Debug, Clone)]
263pub struct UncertaintyAnalysis {
264    pub temperature_k: f64,
265    pub thermal_energy_j: f64,
266    pub thermal_energy_ev: f64,
267    pub hbar: f64,
268    pub minimum_product: f64,
269    pub constraints: Vec<UncertaintyConstraint>,
270    pub recommended_scale: String,
271}
272
273/// Uncertainty constraint for a specific time scale
274#[derive(Debug, Clone)]
275pub struct UncertaintyConstraint {
276    pub scale_name: String,
277    pub time_s: f64,
278    pub required_energy_j: f64,
279    pub required_energy_ev: f64,
280    pub thermal_energy_ratio: f64,
281    pub is_above_thermal: bool,
282    pub is_feasible: bool,
283    pub energy_scale: EnergyScale,
284}
285
286#[cfg(test)]
287mod tests {
288    use super::*;
289    use approx::assert_relative_eq;
290
291    #[test]
292    fn test_uncertainty_principle_validation() {
293        let validator = UncertaintyValidator::new();
294
295        // Valid case: large energy and time
296        let result = validator.validate_energy_time_product(1e-15, 1e-9).unwrap();
297        assert!(result.is_valid);
298        assert!(result.margin > 1.0);
299
300        // Invalid case would be caught by error
301        let min_product = validator.minimum_uncertainty_product();
302        let small_energy = 1e-40;
303        let small_time = 1e-40;
304        assert!(small_energy * small_time < min_product);
305    }
306
307    #[test]
308    fn test_nanosecond_consciousness_validation() {
309        let validator = UncertaintyValidator::new();
310        let result = validator.validate_nanosecond_consciousness();
311
312        assert_eq!(result.time_s, 1e-9);
313        // Nanosecond consciousness should be feasible
314        assert!(result.energy_ev < 1000.0); // Under 1 keV
315    }
316
317    #[test]
318    fn test_energy_scale_classification() {
319        let validator = UncertaintyValidator::new();
320
321        // Test different energy scales. The previous version used
322        // `1e-21` as "1 aeV in joules", but 1 aeV = 1e-18 eV which is
323        // EV_TO_JOULES * 1e-18 ≈ 1.6e-37 J. 1e-21 J is actually ≈6.2 meV,
324        // which the classifier correctly bucketed as MilliElectronVolt.
325        // Compute the joule values from the eV constant so the labels
326        // match the classifier thresholds.
327        let sub_atto_energy = constants::EV_TO_JOULES * 1e-18; // 1 aeV in J (sub-atto bucket)
328        let ev_energy = constants::EV_TO_JOULES; // 1 eV
329        let kev_energy = 1000.0 * constants::EV_TO_JOULES; // 1 keV
330
331        assert_eq!(
332            validator.classify_energy_scale(sub_atto_energy),
333            EnergyScale::SubAttoElectronVolt,
334        );
335        assert_eq!(
336            validator.classify_energy_scale(ev_energy),
337            EnergyScale::ElectronVolt,
338        );
339        assert_eq!(
340            validator.classify_energy_scale(kev_energy),
341            EnergyScale::KiloElectronVolt,
342        );
343    }
344
345    #[test]
346    fn test_time_scale_analysis() {
347        let validator = UncertaintyValidator::new();
348        let analysis = validator.analyze_time_scales();
349
350        assert_eq!(analysis.constraints.len(), 6);
351        assert_eq!(analysis.recommended_scale, "nanosecond");
352
353        // Check that required energies increase as time decreases
354        let mut prev_energy = 0.0;
355        for constraint in analysis.constraints.iter().rev() {
356            assert!(constraint.required_energy_j > prev_energy);
357            prev_energy = constraint.required_energy_j;
358        }
359    }
360
361    #[test]
362    fn test_thermal_energy_calculations() {
363        let validator = UncertaintyValidator::with_temperature(300.0); // 300K
364        let thermal_j = validator.thermal_energy();
365        let thermal_ev = thermal_j / constants::EV_TO_JOULES;
366
367        // At 300K, thermal energy should be ~26 meV
368        assert_relative_eq!(thermal_ev, 0.026, epsilon = 0.01);
369    }
370
371    #[test]
372    fn test_energy_time_consistency() {
373        let validator = UncertaintyValidator::new();
374
375        let time = 1e-9;
376        let required_energy = validator.calculate_required_energy(time);
377        let max_time = validator.calculate_maximum_time(required_energy);
378
379        // Should be consistent within numerical precision
380        assert_relative_eq!(time, max_time, epsilon = 1e-10);
381    }
382
383    #[test]
384    fn test_minimum_uncertainty_product() {
385        let validator = UncertaintyValidator::new();
386        let min_product = validator.minimum_uncertainty_product();
387
388        // Should equal ℏ/2
389        assert_relative_eq!(min_product, constants::PLANCK_HBAR / 2.0, epsilon = 1e-10);
390    }
391}