qualia_core_db/modalities/logic/
computational_maths_shacl.rs1use crate::webizen::SlgOpcode;
16
17#[derive(Debug, Clone)]
19pub struct UnitsConfiguration {
20 pub dimension_components: u8,
22 pub require_dimensional_consistency: bool,
23 pub allowed_unit_systems: Vec<String>, }
25
26#[derive(Debug, Clone)]
28pub struct NumberTheoryConfiguration {
29 pub max_input_bits: u32, pub max_factorization_iterations: u32,
31 pub allowed_operations: Vec<String>, }
33
34#[derive(Debug, Clone)]
36pub struct SpecialFunctionConfiguration {
37 pub max_series_terms: u32,
38 pub convergence_tolerance: f64,
39 pub allowed_families: Vec<String>, }
41
42#[derive(Debug, Clone)]
44pub struct InterpolationConfiguration {
45 pub max_nodes: u32,
46 pub require_distinct_nodes: bool,
47 pub allowed_methods: Vec<String>, }
49
50#[derive(Debug, Clone)]
52pub struct IntegralTransformConfiguration {
53 pub max_samples: u32,
54 pub require_invertibility_check: bool,
55 pub allowed_transforms: Vec<String>, }
57
58#[derive(Debug, Clone)]
60pub struct VectorCalculusConfiguration {
61 pub max_spatial_dimension: u8, pub require_field_smoothness: bool,
63 pub allowed_operators: Vec<String>, }
65
66#[derive(Debug, Clone)]
68pub struct ExactArithmeticConfiguration {
69 pub max_digits: u32, pub require_exact: bool, pub allowed_types: Vec<String>, }
73
74#[derive(Debug, Clone)]
77pub struct SymbolicCalculusConfiguration {
78 pub max_order: u32, pub require_roundtrip_verification: bool, pub allowed_operations: Vec<String>, }
82
83#[derive(Debug, Clone)]
85pub struct AssumptionConfiguration {
86 pub require_sound_rewrite: bool, pub allowed_signs: Vec<String>, }
89
90#[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>, }
98
99impl 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 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
167pub 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
314pub 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}