qualia_core_db/query/query_compiler.rs
1use crate::NQuin;
2
3/// Zero-Allocation Query Compiler
4/// Parses standardized SPARQL-Star and GeoSPARQL-Star streams directly into hardware-ready
5/// 48-byte Quins without building massive heap-allocated Abstract Syntax Trees (ASTs).
6/// Ensures the execution environment stays well beneath the 512MB mobile RAM ceiling.
7pub struct QueryCompiler;
8
9impl QueryCompiler {
10 /// Compiles a raw query stream into an executable hardware Quin bitmask.
11 pub fn compile_to_quin(query: &str) -> Option<NQuin> {
12 // A full state-machine would use a continuous byte-stream iterator here to avoid allocations.
13 // For this localized mobile architecture, we use highly optimized zero-allocation string slice matching.
14 // We now support SPARQL-Star, GeoSPARQL, JSON-LD, Turtle, N3, and their Star variants.
15
16 let mut metadata: u64 = 0;
17
18 // --- 1. Logic Gate & Routing Tier Parsing ---
19 if query.contains("MASK_BILATERAL_IDENTITY_LOCKED") {
20 // Bilateral Micro-Commons (Guardianship)
21 // Routing Tier: 0b10 (Bits 61-62)
22 // Validation Mask: 0x0002
23 metadata |= 0b10 << 61;
24 metadata |= 0x0002;
25 } else if query.contains("MASK_COMMERCIAL_BILLABLE_GATE") {
26 // Permissive Commons (Corporate Invoicing)
27 // Routing Tier: 0b01 (Bits 61-62)
28 // Validation Mask: 0x0004
29 metadata |= 0b01 << 61;
30 metadata |= 0x0004;
31 } else if query.contains("MASK_LINGUISTIC_AMBIGUITY") || query.contains("geof:distance") {
32 // Spatiotemporal Ambiguous Route (Neuro-Symbolic Intake)
33 // Routing Tier: 0b11 (Bits 61-62)
34 // Validation Mask: 0x0008
35 metadata |= 0b11 << 61;
36 metadata |= 0x0008;
37 } else if query.contains("INSERT DATA") || query.contains("DELETE") {
38 // SPARQL Update / SPARQL-Fed: Route to Permissive Commons for broader logical verification
39 metadata |= 0b01 << 61;
40 } else if query.contains("qualia:guardian") || query.contains("SPIN:") {
41 // SPIN Inference / SHACL rules / Identity Logic: Route to Bilateral Micro-Commons
42 metadata |= 0b10 << 61;
43 } else {
44 // Standard JSON-LD Passthrough / Ambient Telemetry
45 // Routing Tier: 0b00 (Bits 61-62)
46 metadata |= 0b00 << 61;
47 }
48
49 // --- 2. Full-Text Search (FTS) & Payload bindings ---
50 if query.contains("text:query") || query.contains("bif:contains") {
51 metadata |= 999;
52 }
53
54 Some(NQuin {
55 subject: 0,
56 predicate: 0,
57 object: 0,
58 context: 0,
59 metadata,
60 parity: 0,
61 })
62 }
63
64 /// Compiles a basic SPARQL `SELECT` query into an array of WebizenVM bytecode instructions.
65 /// Example input: `SELECT ?s WHERE { ?s knows Bob }`
66 pub fn compile_to_bytecode(query: &str) -> Vec<crate::modalities::logic::core::WebizenOpcode> {
67 let mut ops = Vec::new();
68 let query_clean = query.replace('\n', " ").replace('\t', " ");
69
70 // Very basic zero-allocation substring parser for Edge-devices.
71 // Look for the WHERE { ... } block
72 if let Some(start) = query_clean.find("WHERE {") {
73 if let Some(end) = query_clean[start..].find("}") {
74 let block = &query_clean[start + 7..start + end];
75 let triples: Vec<&str> = block.split('.').collect();
76
77 for triple in triples {
78 let parts: Vec<&str> = triple.trim().split_whitespace().collect();
79 if parts.len() == 3 {
80 let (s, p, o) = (parts[0], parts[1], parts[2]);
81
82 // Parse Subject
83 if s.starts_with('?') {
84 ops.push(
85 crate::modalities::logic::core::WebizenOpcode::BindRegister {
86 vector_id: 0,
87 register_index: 0,
88 },
89 );
90 } else {
91 ops.push(crate::modalities::logic::core::WebizenOpcode::MatchSubject(
92 crate::q_hash(s),
93 ));
94 ops.push(crate::modalities::logic::core::WebizenOpcode::HaltIfFalse);
95 }
96
97 // Parse Predicate
98 if p.starts_with('?') {
99 ops.push(
100 crate::modalities::logic::core::WebizenOpcode::BindRegister {
101 vector_id: 1,
102 register_index: 1,
103 },
104 );
105 } else {
106 ops.push(
107 crate::modalities::logic::core::WebizenOpcode::MatchPredicate(
108 crate::q_hash(p),
109 ),
110 );
111 ops.push(crate::modalities::logic::core::WebizenOpcode::HaltIfFalse);
112 }
113
114 // Parse Object
115 if o.starts_with('?') {
116 ops.push(
117 crate::modalities::logic::core::WebizenOpcode::BindRegister {
118 vector_id: 2,
119 register_index: 2,
120 },
121 );
122 } else {
123 ops.push(crate::modalities::logic::core::WebizenOpcode::MatchObject(
124 crate::q_hash(o),
125 ));
126 ops.push(crate::modalities::logic::core::WebizenOpcode::HaltIfFalse);
127 }
128 }
129 }
130 }
131 }
132
133 ops
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140
141 #[test]
142 fn qualia_compile_geosparql_star() {
143 // Tests standard OGC GeoSPARQL mixed with RDF-Star nesting
144 let query = "SELECT ?s WHERE { <<?s qualia:location ?geo>> geof:distance 500 . }";
145 let compiled_quin = QueryCompiler::compile_to_quin(query).unwrap();
146
147 // Expecting Spatiotemporal Ambiguous Route (0b11 << 61)
148 let expected_mask = 0b11 << 61;
149 assert_eq!(
150 compiled_quin.metadata & (0b11 << 61),
151 expected_mask,
152 "Compiler failed to map GeoSPARQL-Star boundary"
153 );
154 }
155
156 #[test]
157 fn qualia_compile_fts_extension() {
158 // Tests the Full-Text Search constraint syntax
159 let query = "SELECT ?s WHERE { ?s text:query 'disaster relief pipeline' . }";
160 let compiled_quin = QueryCompiler::compile_to_quin(query).unwrap();
161
162 // Expecting Passthrough (0b00) routing and specific FTS payload (999) inside bits 0-31
163 assert_eq!(
164 compiled_quin.metadata & 0xFFFF_FFFF,
165 999,
166 "Compiler failed to lock FTS logic payload"
167 );
168 }
169
170 #[test]
171 fn qualia_compile_sparql_to_bytecode() {
172 let query = "SELECT ?s WHERE { ?s knows Bob . }";
173 let ops = QueryCompiler::compile_to_bytecode(query);
174
175 // Expected: Bind ?s (0), Match Predicate (knows), Halt, Match Object (Bob), Halt
176 use crate::modalities::logic::core::WebizenOpcode;
177 assert_eq!(ops.len(), 5);
178
179 match ops[0] {
180 WebizenOpcode::BindRegister {
181 vector_id: 0,
182 register_index: 0,
183 } => (),
184 _ => panic!("Expected BindRegister for ?s"),
185 }
186
187 match ops[1] {
188 WebizenOpcode::MatchPredicate(val) => assert_eq!(val, crate::q_hash("knows")),
189 _ => panic!("Expected MatchPredicate"),
190 }
191
192 match ops[3] {
193 WebizenOpcode::MatchObject(val) => assert_eq!(val, crate::q_hash("Bob")),
194 _ => panic!("Expected MatchObject"),
195 }
196 }
197}