Skip to main content

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}