Skip to main content

qualia_core_db/modalities/logic/
computational_maths_shacl.rs

1//! SHACL constraint surface for the **computational-mathematics engine**.
2//!
3//! Mirrors, in the SHACL/`SlgOpcode` validation layer, the STEM capability libraries built
4//! out under the CALCULUS plan + the computational-engine gap analysis: units & dimensional
5//! analysis, number theory &
6//! combinatorics, special functions, interpolation, integral transforms, vector calculus,
7//! exact/arbitrary-precision arithmetic, the CAS calculus extensions (symbolic integration /
8//! series / limits / equation-solving / assumptions / trig / ODE-PDE / multivariable diff),
9//! and the general-dimension numerical methods.
10//!
11//! Each capability has a typed `*Configuration` (compiled to a bounded `Vec<SlgOpcode>` at
12//! config time, off the hot path) and a SHACL `NodeShape` in [`get_computational_maths_shacl_ttl`].
13//! Wired into the runtime via [`super::shacl::shacl_extension_bridge::append_extension_opcodes`].
14
15use crate::webizen::SlgOpcode;
16
17/// `q42:UnitsConfiguration` — dimensional-analysis / unit-conversion validation.
18#[derive(Debug, Clone)]
19pub struct UnitsConfiguration {
20    /// SI base-dimension vector length (mass, length, time, current, temp, amount, luminous = 7).
21    pub dimension_components: u8,
22    pub require_dimensional_consistency: bool,
23    pub allowed_unit_systems: Vec<String>, // ["si", "cgs", "imperial"]
24}
25
26/// `q42:NumberTheoryConfiguration` — primality / factorization / modular bounds.
27#[derive(Debug, Clone)]
28pub struct NumberTheoryConfiguration {
29    pub max_input_bits: u32, // Miller-Rabin / Pollard-rho input bound
30    pub max_factorization_iterations: u32,
31    pub allowed_operations: Vec<String>, // ["primality","factorization","gcd","totient","modular","combinatorics"]
32}
33
34/// `q42:SpecialFunctionConfiguration` — special-function evaluation parameters.
35#[derive(Debug, Clone)]
36pub struct SpecialFunctionConfiguration {
37    pub max_series_terms: u32,
38    pub convergence_tolerance: f64,
39    pub allowed_families: Vec<String>, // ["bessel","airy","zeta","legendre","chebyshev","hermite","laguerre"]
40}
41
42/// `q42:InterpolationConfiguration` — interpolation / approximation parameters.
43#[derive(Debug, Clone)]
44pub struct InterpolationConfiguration {
45    pub max_nodes: u32,
46    pub require_distinct_nodes: bool,
47    pub allowed_methods: Vec<String>, // ["lagrange","newton","cubic_spline","least_squares"]
48}
49
50/// `q42:IntegralTransformConfiguration` — DFT / Laplace / Z transform parameters.
51#[derive(Debug, Clone)]
52pub struct IntegralTransformConfiguration {
53    pub max_samples: u32,
54    pub require_invertibility_check: bool,
55    pub allowed_transforms: Vec<String>, // ["dft","laplace","ztransform"]
56}
57
58/// `q42:VectorCalculusConfiguration` — grad/div/curl + line/surface integral parameters.
59#[derive(Debug, Clone)]
60pub struct VectorCalculusConfiguration {
61    pub max_spatial_dimension: u8, // 2 or 3
62    pub require_field_smoothness: bool,
63    pub allowed_operators: Vec<String>, // ["gradient","divergence","curl","laplacian","line_integral","surface_integral"]
64}
65
66/// `q42:ExactArithmeticConfiguration` — arbitrary-precision integer / rational parameters.
67#[derive(Debug, Clone)]
68pub struct ExactArithmeticConfiguration {
69    pub max_digits: u32,            // precision ceiling
70    pub require_exact: bool,        // no silent float fallback
71    pub allowed_types: Vec<String>, // ["bigint","bigrational"]
72}
73
74/// `q42:SymbolicCalculusConfiguration` — CAS calculus operations (integration, series,
75/// limits, equation-solving, ODE/PDE, multivariable differentiation).
76#[derive(Debug, Clone)]
77pub struct SymbolicCalculusConfiguration {
78    pub max_order: u32,                       // Taylor / derivative order ceiling
79    pub require_roundtrip_verification: bool, // the honesty gate (d/dx ∘ ∫, residual checks)
80    pub allowed_operations: Vec<String>, // ["integrate","series","limit","solve","ode_solve","pde_classify","gradient","jacobian","hessian"]
81}
82
83/// `q42:AssumptionConfiguration` — simplify-under-assumptions soundness parameters.
84#[derive(Debug, Clone)]
85pub struct AssumptionConfiguration {
86    pub require_sound_rewrite: bool, // no rewrite unless the sign side-condition is proven
87    pub allowed_signs: Vec<String>, // ["positive","nonnegative","negative","nonpositive","nonzero"]
88}
89
90/// `q42:NumericalMethodConfiguration` — general-dimension RK4 / Simpson / shooting-BVP.
91#[derive(Debug, Clone)]
92pub struct NumericalMethodConfiguration {
93    pub max_state_dimension: u32,
94    pub max_steps: u32,
95    pub convergence_tolerance: f64,
96    pub allowed_integrators: Vec<String>, // ["rk4","simpson","shooting_bvp"]
97}
98
99// ── Opcode generation ──────────────────────────────────────────────────────────
100
101impl UnitsConfiguration {
102    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
103        vec![SlgOpcode::CheckMaxInclusive(
104            self.dimension_components as f64,
105        )]
106    }
107}
108impl NumberTheoryConfiguration {
109    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
110        vec![
111            SlgOpcode::CheckMaxInclusive(self.max_input_bits as f64),
112            SlgOpcode::CheckMaxInclusive(self.max_factorization_iterations as f64),
113        ]
114    }
115}
116impl SpecialFunctionConfiguration {
117    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
118        vec![
119            SlgOpcode::CheckMaxInclusive(self.max_series_terms as f64),
120            SlgOpcode::CheckMinInclusive(self.convergence_tolerance),
121        ]
122    }
123}
124impl InterpolationConfiguration {
125    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
126        vec![SlgOpcode::CheckMaxInclusive(self.max_nodes as f64)]
127    }
128}
129impl IntegralTransformConfiguration {
130    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
131        vec![SlgOpcode::CheckMaxInclusive(self.max_samples as f64)]
132    }
133}
134impl VectorCalculusConfiguration {
135    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
136        vec![SlgOpcode::CheckMaxInclusive(
137            self.max_spatial_dimension as f64,
138        )]
139    }
140}
141impl ExactArithmeticConfiguration {
142    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
143        vec![SlgOpcode::CheckMaxInclusive(self.max_digits as f64)]
144    }
145}
146impl SymbolicCalculusConfiguration {
147    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
148        vec![SlgOpcode::CheckMaxInclusive(self.max_order as f64)]
149    }
150}
151impl AssumptionConfiguration {
152    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
153        // A single representative allowed sign is bound-checked via has-value.
154        let first = self.allowed_signs.first().cloned().unwrap_or_default();
155        vec![SlgOpcode::CheckHasValue(crate::q_hash(&first))]
156    }
157}
158impl NumericalMethodConfiguration {
159    pub fn to_opcodes(&self) -> Vec<SlgOpcode> {
160        vec![
161            SlgOpcode::CheckMaxInclusive(self.max_state_dimension as f64),
162            SlgOpcode::CheckMaxInclusive(self.max_steps as f64),
163        ]
164    }
165}
166
167/// Comprehensive SHACL TTL vocabulary for the computational-mathematics engine.
168pub fn get_computational_maths_shacl_ttl() -> &'static str {
169    r#"
170@prefix q42: <https://webizen.org/q42#> .
171@prefix sh: <http://www.w3.org/ns/shacl#> .
172@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
173
174q42:UnitsConfigurationShape a sh:NodeShape ;
175    sh:property [
176        sh:path q42:dimensionComponents ;
177        sh:datatype xsd:integer ;
178        sh:minInclusive 1 ;
179        sh:maxInclusive 7 ;
180        sh:message "SI base-dimension vector has 7 components" ;
181    ] ;
182    sh:property [
183        sh:path q42:allowedUnitSystems ;
184        sh:in ("si" "cgs" "imperial") ;
185        sh:message "Unit system must be supported" ;
186    ] .
187
188q42:NumberTheoryConfigurationShape a sh:NodeShape ;
189    sh:property [
190        sh:path q42:maxInputBits ;
191        sh:datatype xsd:integer ;
192        sh:minInclusive 1 ;
193        sh:maxInclusive 4096 ;
194        sh:message "Number-theory input must be within the supported bit width" ;
195    ] ;
196    sh:property [
197        sh:path q42:allowedOperations ;
198        sh:in ("primality" "factorization" "gcd" "totient" "modular" "combinatorics") ;
199        sh:message "Operation must be a supported number-theory primitive" ;
200    ] .
201
202q42:SpecialFunctionConfigurationShape a sh:NodeShape ;
203    sh:property [
204        sh:path q42:maxSeriesTerms ;
205        sh:datatype xsd:integer ;
206        sh:minInclusive 1 ;
207        sh:maxInclusive 100000 ;
208        sh:message "Series truncation must be within bounds" ;
209    ] ;
210    sh:property [
211        sh:path q42:allowedFamilies ;
212        sh:in ("bessel" "airy" "zeta" "legendre" "chebyshev" "hermite" "laguerre") ;
213        sh:message "Special-function family must be supported" ;
214    ] .
215
216q42:InterpolationConfigurationShape a sh:NodeShape ;
217    sh:property [
218        sh:path q42:maxNodes ;
219        sh:datatype xsd:integer ;
220        sh:minInclusive 2 ;
221        sh:maxInclusive 1000000 ;
222        sh:message "Interpolation node count must be between 2 and 1,000,000" ;
223    ] ;
224    sh:property [
225        sh:path q42:allowedMethods ;
226        sh:in ("lagrange" "newton" "cubic_spline" "least_squares") ;
227        sh:message "Interpolation method must be supported" ;
228    ] .
229
230q42:IntegralTransformConfigurationShape a sh:NodeShape ;
231    sh:property [
232        sh:path q42:maxSamples ;
233        sh:datatype xsd:integer ;
234        sh:minInclusive 2 ;
235        sh:maxInclusive 16777216 ;
236        sh:message "Transform sample count must be within bounds" ;
237    ] ;
238    sh:property [
239        sh:path q42:allowedTransforms ;
240        sh:in ("dft" "laplace" "ztransform") ;
241        sh:message "Transform must be supported" ;
242    ] .
243
244q42:VectorCalculusConfigurationShape a sh:NodeShape ;
245    sh:property [
246        sh:path q42:maxSpatialDimension ;
247        sh:datatype xsd:integer ;
248        sh:minInclusive 2 ;
249        sh:maxInclusive 3 ;
250        sh:message "Vector calculus supports 2D and 3D fields" ;
251    ] ;
252    sh:property [
253        sh:path q42:allowedOperators ;
254        sh:in ("gradient" "divergence" "curl" "laplacian" "line_integral" "surface_integral") ;
255        sh:message "Vector-calculus operator must be supported" ;
256    ] .
257
258q42:ExactArithmeticConfigurationShape a sh:NodeShape ;
259    sh:property [
260        sh:path q42:maxDigits ;
261        sh:datatype xsd:integer ;
262        sh:minInclusive 1 ;
263        sh:maxInclusive 1000000 ;
264        sh:message "Arbitrary-precision digit count must be within bounds" ;
265    ] ;
266    sh:property [
267        sh:path q42:allowedTypes ;
268        sh:in ("bigint" "bigrational") ;
269        sh:message "Exact-arithmetic type must be supported" ;
270    ] .
271
272q42:SymbolicCalculusConfigurationShape a sh:NodeShape ;
273    sh:property [
274        sh:path q42:maxOrder ;
275        sh:datatype xsd:integer ;
276        sh:minInclusive 1 ;
277        sh:maxInclusive 1024 ;
278        sh:message "Symbolic calculus order must be within bounds" ;
279    ] ;
280    sh:property [
281        sh:path q42:allowedOperations ;
282        sh:in ("integrate" "series" "limit" "solve" "ode_solve" "pde_classify" "gradient" "jacobian" "hessian") ;
283        sh:message "Symbolic-calculus operation must be supported" ;
284    ] .
285
286q42:AssumptionConfigurationShape a sh:NodeShape ;
287    sh:property [
288        sh:path q42:requireSoundRewrite ;
289        sh:datatype xsd:boolean ;
290        sh:message "Assumption-gated rewrites must remain sound" ;
291    ] ;
292    sh:property [
293        sh:path q42:allowedSigns ;
294        sh:in ("positive" "nonnegative" "negative" "nonpositive" "nonzero") ;
295        sh:message "Sign assumption must be a supported domain predicate" ;
296    ] .
297
298q42:NumericalMethodConfigurationShape a sh:NodeShape ;
299    sh:property [
300        sh:path q42:maxStateDimension ;
301        sh:datatype xsd:integer ;
302        sh:minInclusive 1 ;
303        sh:maxInclusive 100000 ;
304        sh:message "ODE state dimension must be within bounds" ;
305    ] ;
306    sh:property [
307        sh:path q42:allowedIntegrators ;
308        sh:in ("rk4" "simpson" "shooting_bvp") ;
309        sh:message "Numerical integrator must be supported" ;
310    ] .
311"#
312}
313
314/// Every NodeShape name in this module's vocabulary (full-coverage assertion target).
315pub const COMPUTATIONAL_MATHS_SHAPES: &[&str] = &[
316    "q42:UnitsConfigurationShape",
317    "q42:NumberTheoryConfigurationShape",
318    "q42:SpecialFunctionConfigurationShape",
319    "q42:InterpolationConfigurationShape",
320    "q42:IntegralTransformConfigurationShape",
321    "q42:VectorCalculusConfigurationShape",
322    "q42:ExactArithmeticConfigurationShape",
323    "q42:SymbolicCalculusConfigurationShape",
324    "q42:AssumptionConfigurationShape",
325    "q42:NumericalMethodConfigurationShape",
326];
327
328#[cfg(test)]
329mod tests {
330    use super::*;
331
332    #[test]
333    fn every_capability_has_a_shape() {
334        let ttl = get_computational_maths_shacl_ttl();
335        for shape in COMPUTATIONAL_MATHS_SHAPES {
336            assert!(ttl.contains(shape), "missing SHACL shape: {shape}");
337        }
338    }
339
340    #[test]
341    fn every_config_generates_opcodes() {
342        assert!(!UnitsConfiguration {
343            dimension_components: 7,
344            require_dimensional_consistency: true,
345            allowed_unit_systems: vec!["si".into()],
346        }
347        .to_opcodes()
348        .is_empty());
349        assert!(!NumberTheoryConfiguration {
350            max_input_bits: 256,
351            max_factorization_iterations: 100_000,
352            allowed_operations: vec!["primality".into()],
353        }
354        .to_opcodes()
355        .is_empty());
356        assert!(!SpecialFunctionConfiguration {
357            max_series_terms: 1000,
358            convergence_tolerance: 1e-12,
359            allowed_families: vec!["bessel".into()],
360        }
361        .to_opcodes()
362        .is_empty());
363        assert!(!InterpolationConfiguration {
364            max_nodes: 1024,
365            require_distinct_nodes: true,
366            allowed_methods: vec!["cubic_spline".into()],
367        }
368        .to_opcodes()
369        .is_empty());
370        assert!(!IntegralTransformConfiguration {
371            max_samples: 4096,
372            require_invertibility_check: true,
373            allowed_transforms: vec!["dft".into()],
374        }
375        .to_opcodes()
376        .is_empty());
377        assert!(!VectorCalculusConfiguration {
378            max_spatial_dimension: 3,
379            require_field_smoothness: true,
380            allowed_operators: vec!["curl".into()],
381        }
382        .to_opcodes()
383        .is_empty());
384        assert!(!ExactArithmeticConfiguration {
385            max_digits: 10_000,
386            require_exact: true,
387            allowed_types: vec!["bigint".into()],
388        }
389        .to_opcodes()
390        .is_empty());
391        assert!(!SymbolicCalculusConfiguration {
392            max_order: 16,
393            require_roundtrip_verification: true,
394            allowed_operations: vec!["integrate".into()],
395        }
396        .to_opcodes()
397        .is_empty());
398        assert!(!AssumptionConfiguration {
399            require_sound_rewrite: true,
400            allowed_signs: vec!["positive".into()],
401        }
402        .to_opcodes()
403        .is_empty());
404        assert!(!NumericalMethodConfiguration {
405            max_state_dimension: 64,
406            max_steps: 10_000,
407            convergence_tolerance: 1e-9,
408            allowed_integrators: vec!["rk4".into()],
409        }
410        .to_opcodes()
411        .is_empty());
412    }
413}