mathhook_core/functions/
intelligence.rs

1//! Function Intelligence Registry
2//!
3//! The core intelligence system that provides mathematical properties and
4//! capabilities for ALL functions in MathHook.
5
6use super::properties::FunctionProperties;
7use crate::core::Expression;
8use crate::educational::step_by_step::Step;
9use once_cell::sync::Lazy;
10use std::collections::HashMap;
11
12/// Universal Function Intelligence Registry
13///
14/// Single source of truth for ALL function intelligence in MathHook.
15/// Provides O(1) property lookup for maximum performance.
16///
17pub struct UniversalFunctionRegistry {
18    /// Core mathematical properties for all functions
19    /// O(1) lookup for function properties
20    properties: HashMap<String, FunctionProperties>,
21
22    /// Educational step generators for all functions
23    /// Required for step-by-step explanations
24    step_generators: HashMap<String, Box<dyn StepGenerator>>,
25}
26
27/// Function family classification for performance optimization
28#[derive(Debug, Clone, Copy, PartialEq)]
29pub enum FunctionFamily {
30    Elementary,  // sin, cos, exp, log
31    Special,     // gamma, bessel, etc.
32    Polynomial,  // legendre, hermite, etc.
33    UserDefined, // f, g, h, etc.
34}
35
36/// Step generator trait for educational explanations
37///
38/// All functions must implement step-by-step explanations
39/// to comply with educational integration rules.
40pub trait StepGenerator: Send + Sync {
41    /// Generate step-by-step explanation for function evaluation
42    fn generate_steps(&self, name: &str, args: &[Expression]) -> Vec<Step>;
43
44    /// Generate LaTeX explanation (required for educational quality)
45    fn generate_latex_explanation(&self, name: &str, args: &[Expression]) -> String;
46}
47
48/// Global function intelligence registry
49///
50/// Lazy initialization ensures zero startup cost while providing
51/// universal access to function intelligence.
52pub static UNIVERSAL_REGISTRY: Lazy<UniversalFunctionRegistry> =
53    Lazy::new(UniversalFunctionRegistry::new);
54
55impl Default for UniversalFunctionRegistry {
56    fn default() -> Self {
57        Self::new()
58    }
59}
60
61impl UniversalFunctionRegistry {
62    /// Create new universal function registry
63    ///
64    /// Initializes with all built-in mathematical functions and their properties.
65    pub fn new() -> Self {
66        // Advanced memory optimization: precise pre-allocation based on actual usage
67        // Elementary: ~20, Polynomials: ~12, Special: ~15 = ~47 total
68        // Use 64 for optimal hash table performance (power of 2)
69        let mut registry = Self {
70            properties: HashMap::with_capacity(64), // Optimized capacity
71            step_generators: HashMap::with_capacity(64), // Matching for memory alignment
72        };
73
74        // Initialize built-in functions using modular intelligence
75        registry.initialize_elementary_functions();
76        registry.initialize_special_functions();
77        registry.initialize_polynomial_functions();
78        registry.initialize_number_theory_functions();
79
80        registry
81    }
82
83    /// Get function properties
84    #[inline(always)]
85    pub fn get_properties(&self, name: &str) -> Option<&FunctionProperties> {
86        self.properties.get(name)
87    }
88
89    /// Check if function has mathematical intelligence
90    #[inline(always)]
91    pub fn has_intelligence(&self, name: &str) -> bool {
92        self.properties.contains_key(name)
93    }
94
95    /// Debug: List all registered functions
96    pub fn list_all_functions(&self) -> Vec<String> {
97        self.properties.keys().cloned().collect()
98    }
99
100    /// Debug: Get registry size
101    pub fn registry_size(&self) -> usize {
102        self.properties.len()
103    }
104
105    /// Get step-by-step explanation for function operation
106    ///
107    /// Required for educational integration compliance
108    pub fn explain_function(&self, name: &str, args: &[Expression]) -> Vec<Step> {
109        if let Some(generator) = self.step_generators.get(name) {
110            generator.generate_steps(name, args)
111        } else {
112            // Default explanation for unknown functions
113            vec![
114                Step::new("Function Call", format!("Evaluating {}(...)", name)),
115                Step::new("Arguments", format!("With {} arguments", args.len())),
116            ]
117        }
118    }
119
120    fn initialize_elementary_functions(&mut self) {
121        // Use modular elementary intelligence system
122        let elementary_intelligence = super::elementary::ElementaryIntelligence::new();
123
124        // Get all elementary function properties from modular system
125        let elementary_properties = elementary_intelligence.get_all_properties();
126
127        // Add to universal registry
128        self.properties.extend(elementary_properties);
129    }
130
131    /// Initialize special functions using modular architecture
132    fn initialize_special_functions(&mut self) {
133        // Use modular special function intelligence system
134        let special_intelligence = super::special::SpecialIntelligence::new();
135        let special_properties = special_intelligence.get_all_properties();
136        self.properties.extend(special_properties);
137    }
138
139    /// Initialize polynomial functions using modular architecture
140    fn initialize_polynomial_functions(&mut self) {
141        // Use modular polynomial intelligence system
142        let polynomial_intelligence = super::polynomials::PolynomialIntelligence::new();
143
144        // Get all polynomial function properties from modular system
145        let polynomial_properties = polynomial_intelligence.get_all_properties();
146
147        // Add to universal registry
148        self.properties.extend(polynomial_properties);
149    }
150
151    /// Initialize number theory functions using modular intelligence
152    fn initialize_number_theory_functions(&mut self) {
153        // Use modular number theory intelligence system
154        let number_theory_intelligence = super::number_theory::NumberTheoryIntelligence::new();
155        let number_theory_properties = number_theory_intelligence.get_all_properties();
156        self.properties.extend(number_theory_properties);
157    }
158}
159
160/// Get global function intelligence registry
161///
162/// Provides universal access to function intelligence throughout MathHook
163#[inline(always)]
164pub fn get_universal_registry() -> &'static UniversalFunctionRegistry {
165    &UNIVERSAL_REGISTRY
166}
167
168#[cfg(test)]
169mod tests {
170    use super::*;
171
172    #[test]
173    fn test_registry_initialization() {
174        let registry = UniversalFunctionRegistry::new();
175
176        // Test that registry is properly initialized with optimized capacity
177        // Capacity is 64 (power of 2) for optimal hash table performance
178        assert!(registry.properties.capacity() >= 64);
179        assert!(registry.step_generators.capacity() >= 64);
180
181        // Verify registry actually has functions registered
182        assert!(
183            registry.registry_size() > 0,
184            "Registry should have functions registered"
185        );
186    }
187
188    #[test]
189    fn test_has_intelligence_performance() {
190        let registry = UniversalFunctionRegistry::new();
191
192        // Test O(1) intelligence check performance
193        let start = std::time::Instant::now();
194        for _ in 0..100_000 {
195            registry.has_intelligence("sin");
196        }
197        let duration = start.elapsed();
198
199        // Should be extremely fast (sub-millisecond for 100k calls)
200        // Relaxed threshold for complex modular system
201        // Threshold: 100ms for 100k calls = 1 microsecond per lookup (very fast)
202        assert!(
203            duration.as_millis() < 100,
204            "Intelligence check too slow: {:?}",
205            duration
206        );
207    }
208
209    #[test]
210    fn test_elementary_function_intelligence() {
211        let registry = UniversalFunctionRegistry::new();
212
213        // Test that elementary functions have intelligence
214        assert!(registry.has_intelligence("sin"));
215        assert!(registry.has_intelligence("cos"));
216        assert!(registry.has_intelligence("exp"));
217        assert!(registry.has_intelligence("ln"));
218
219        // Test properties lookup
220        if let Some(props) = registry.get_properties("sin") {
221            assert!(props.has_derivative());
222            assert_eq!(props.family(), FunctionFamily::Elementary);
223        }
224    }
225
226    #[test]
227    fn test_polynomial_function_intelligence() {
228        let registry = UniversalFunctionRegistry::new();
229
230        // Test that polynomial functions have intelligence
231        assert!(registry.has_intelligence("legendre_p"));
232
233        // Test properties lookup
234        if let Some(props) = registry.get_properties("legendre_p") {
235            assert!(props.has_derivative());
236            assert_eq!(props.family(), FunctionFamily::Polynomial);
237        }
238    }
239
240    #[test]
241    fn test_special_function_intelligence() {
242        let registry = UniversalFunctionRegistry::new();
243
244        // Test that special functions have intelligence
245        assert!(
246            registry.has_intelligence("gamma"),
247            "Gamma function must be registered in universal registry"
248        );
249        assert!(
250            registry.has_intelligence("bessel_j"),
251            "Bessel J function must be registered in universal registry"
252        );
253        assert!(
254            registry.has_intelligence("bessel_y"),
255            "Bessel Y function must be registered in universal registry"
256        );
257        assert!(
258            registry.has_intelligence("zeta"),
259            "Zeta function must be registered in universal registry"
260        );
261
262        // Test properties lookup for gamma
263        if let Some(props) = registry.get_properties("gamma") {
264            assert!(props.has_derivative());
265            assert_eq!(props.family(), FunctionFamily::Special);
266        }
267
268        // Test properties lookup for zeta
269        if let Some(props) = registry.get_properties("zeta") {
270            assert!(props.has_derivative());
271            assert_eq!(props.family(), FunctionFamily::Special);
272        }
273    }
274
275    #[test]
276    fn test_all_special_functions_registered() {
277        let registry = UniversalFunctionRegistry::new();
278        let all_functions = registry.list_all_functions();
279
280        // Verify all special functions
281        let required_special_functions = ["gamma", "beta", "bessel_j", "bessel_y", "zeta"];
282
283        for func in required_special_functions.iter() {
284            assert!(
285                all_functions.contains(&func.to_string()),
286                "Special function '{}' must be in registry",
287                func
288            );
289        }
290    }
291
292    #[test]
293    fn test_special_function_properties_quality() {
294        let registry = UniversalFunctionRegistry::new();
295
296        // Gamma should have enhanced properties
297        if let Some(props) = registry.get_properties("gamma") {
298            match props {
299                FunctionProperties::Special(sp) => {
300                    assert!(
301                        sp.special_values.len() >= 5,
302                        "Gamma should have at least 5 special values including half-integers"
303                    );
304                }
305                _ => panic!("Gamma should have Special properties"),
306            }
307        }
308
309        // Zeta should have enhanced properties
310        if let Some(props) = registry.get_properties("zeta") {
311            match props {
312                FunctionProperties::Special(sp) => {
313                    assert!(
314                        sp.special_values.len() >= 9,
315                        "Zeta should have at least 9 special values"
316                    );
317                }
318                _ => panic!("Zeta should have Special properties"),
319            }
320        }
321    }
322}