1use crate::NQuin;
6
7#[derive(Debug, Clone, Copy, PartialEq)]
9pub enum WebizenOpcode {
10 MatchSubject(u64),
12 MatchPredicate(u64),
14 MatchObject(u64),
16 EvalMetadataMask(u32),
18 BindRegister {
20 vector_id: u8,
21 register_index: usize,
22 },
23 MatchRegister {
25 vector_id: u8,
26 register_index: usize,
27 },
28 HaltIfFalse,
30 EmitQuin {
32 subject_reg: usize,
33 predicate: u64,
34 object: u64,
35 context_reg: usize,
36 },
37 LessThan { vector_id: u8, value: f32 },
39 GreaterThan { vector_id: u8, value: f32 },
41 LessOrEqual { vector_id: u8, value: f32 },
43 GreaterOrEqual { vector_id: u8, value: f32 },
45 Always(u64),
47 Eventually(u64),
49 Next(u64),
51 EmitCalculatedQuin {
53 subject_reg: usize,
54 predicate: u64,
55 object_calc_op: u8,
56 context_reg: usize,
57 },
58 YieldConfidence(f32),
60 LoadModel(u64),
62 EvictModel(u64),
64}
65
66pub struct WebizenVM {
68 pub registers: [Option<u64>; 16],
70 pub bytecode_buffer: [Option<WebizenOpcode>; 64],
72 pub scrubbing_lock: Option<std::sync::Arc<std::sync::atomic::AtomicBool>>,
74 pub yielded_op: Option<WebizenOpcode>,
76}
77
78impl WebizenVM {
79 pub fn new() -> Self {
80 Self {
81 registers: [None; 16],
82 bytecode_buffer: [None; 64],
83 scrubbing_lock: None,
84 yielded_op: None,
85 }
86 }
87
88 pub fn with_scrubbing_lock(lock: std::sync::Arc<std::sync::atomic::AtomicBool>) -> Self {
89 let mut vm = Self::new();
90 vm.scrubbing_lock = Some(lock);
91 vm
92 }
93
94 pub fn load_bytecode(&mut self, instructions: &[WebizenOpcode]) {
95 self.bytecode_buffer.fill(None);
96 for (i, &op) in instructions.iter().enumerate().take(64) {
97 self.bytecode_buffer[i] = Some(op);
98 }
99 }
100
101 pub fn flatten_to_suspended(
104 &self,
105 agreement_id: u64,
106 threshold: u8,
107 current_quin: crate::NQuin,
108 ) -> crate::crdt::SuspendedTransaction {
109 crate::crdt::SuspendedTransaction {
110 agreement_id,
111 threshold,
112 collected_signatures: 0,
113 registers: self.registers,
114 bytecode_buffer: self.bytecode_buffer,
115 yielded_op: self.yielded_op,
116 suspended_quin: current_quin,
117 }
118 }
119
120 pub fn execute_constraint(&mut self, quin: &NQuin) -> bool {
122 let mut condition_flag = true;
123
124 let _stochastic_weight = crate::frame_layout::truth_degree(quin.metadata);
127
128 for op in self.bytecode_buffer.iter().flatten() {
129 crate::telemetry::VM_CYCLES_COUNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
130
131 match op {
132 WebizenOpcode::MatchSubject(val) => {
133 condition_flag = quin.subject == *val;
134 }
135 WebizenOpcode::MatchPredicate(val) => {
136 condition_flag = quin.predicate == *val;
137 }
138 WebizenOpcode::MatchObject(val) => {
139 condition_flag = quin.object == *val;
140 }
141 WebizenOpcode::EvalMetadataMask(mask) => {
142 let quin_mask = (quin.metadata & 0xFFFF) as u32;
143 condition_flag = (quin_mask & mask) == *mask;
144 }
145 WebizenOpcode::BindRegister {
146 vector_id,
147 register_index,
148 } => {
149 let value = match vector_id {
150 0 => quin.subject,
151 1 => quin.predicate,
152 2 => quin.object,
153 3 => quin.context,
154 _ => 0,
155 };
156 self.registers[*register_index] = Some(value);
157 condition_flag = true;
158 }
159 WebizenOpcode::MatchRegister {
160 vector_id,
161 register_index,
162 } => {
163 if let Some(bound_val) = self.registers[*register_index] {
164 let value = match vector_id {
165 0 => quin.subject,
166 1 => quin.predicate,
167 2 => quin.object,
168 3 => quin.context,
169 _ => 0,
170 };
171 condition_flag = value == bound_val;
172 } else {
173 condition_flag = false;
175 }
176 }
177 WebizenOpcode::HaltIfFalse => {
178 if !condition_flag {
179 return false;
180 }
181 }
182 WebizenOpcode::LessThan { vector_id, value } => {
183 condition_flag =
184 Self::extract_float(quin, *vector_id).map_or(false, |v| v < *value);
185 }
186 WebizenOpcode::GreaterThan { vector_id, value } => {
187 condition_flag =
188 Self::extract_float(quin, *vector_id).map_or(false, |v| v > *value);
189 }
190 WebizenOpcode::LessOrEqual { vector_id, value } => {
191 condition_flag =
192 Self::extract_float(quin, *vector_id).map_or(false, |v| v <= *value);
193 }
194 WebizenOpcode::GreaterOrEqual { vector_id, value } => {
195 condition_flag =
196 Self::extract_float(quin, *vector_id).map_or(false, |v| v >= *value);
197 }
198 WebizenOpcode::Always(stress_threshold) => {
199 crate::telemetry::ATOMIC_INTEGRATION_STEPS
200 .fetch_add(50, std::sync::atomic::Ordering::Relaxed);
201 condition_flag = Self::extract_float(quin, 2)
202 .map_or(false, |stress| stress < *stress_threshold as f32);
203 }
204 WebizenOpcode::Eventually(stress_threshold) => {
205 crate::telemetry::ATOMIC_INTEGRATION_STEPS
206 .fetch_add(50, std::sync::atomic::Ordering::Relaxed);
207 condition_flag = Self::extract_float(quin, 2)
208 .map_or(false, |stress| stress >= *stress_threshold as f32);
209 }
210 WebizenOpcode::Next(stress_threshold) => {
211 crate::telemetry::ATOMIC_INTEGRATION_STEPS
212 .fetch_add(50, std::sync::atomic::Ordering::Relaxed);
213 condition_flag = Self::extract_float(quin, 2)
214 .map_or(false, |stress| stress == *stress_threshold as f32);
215 }
216 WebizenOpcode::YieldConfidence(threshold) => {
217 let stochastic_weight = crate::frame_layout::truth_degree(quin.metadata);
218 if stochastic_weight < *threshold {
219 condition_flag = false; }
221 }
222 WebizenOpcode::LoadModel(model_id) => {
223 if let Some(ref lock) = self.scrubbing_lock {
224 if lock.load(std::sync::atomic::Ordering::Acquire) {
225 self.yielded_op = Some(WebizenOpcode::LoadModel(*model_id));
226 return false; }
228 }
229 }
230 WebizenOpcode::EvictModel(_) => {}
231 WebizenOpcode::EmitQuin { .. } | WebizenOpcode::EmitCalculatedQuin { .. } => {
232 }
234 }
235 }
236
237 condition_flag
238 }
239
240 pub fn execute_implication(&mut self, quin: &NQuin) -> Option<NQuin> {
243 let mut condition_flag = true;
244 let mut emitted_quin = None;
245 let mut defeasible_tag = false;
246
247 for op in self.bytecode_buffer.iter().flatten() {
248 crate::telemetry::VM_CYCLES_COUNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
249
250 match op {
251 WebizenOpcode::MatchSubject(val) => condition_flag = quin.subject == *val,
252 WebizenOpcode::MatchPredicate(val) => condition_flag = quin.predicate == *val,
253 WebizenOpcode::MatchObject(val) => condition_flag = quin.object == *val,
254 WebizenOpcode::EvalMetadataMask(mask) => {
255 let quin_mask = (quin.metadata & 0xFFFF) as u32;
256 condition_flag = (quin_mask & mask) == *mask;
257 }
258 WebizenOpcode::BindRegister {
259 vector_id,
260 register_index,
261 } => {
262 let value = match vector_id {
263 0 => quin.subject,
264 1 => quin.predicate,
265 2 => quin.object,
266 3 => quin.context,
267 _ => 0,
268 };
269 self.registers[*register_index] = Some(value);
270 condition_flag = true;
271 }
272 WebizenOpcode::MatchRegister {
273 vector_id,
274 register_index,
275 } => {
276 if let Some(bound_val) = self.registers[*register_index] {
277 let value = match vector_id {
278 0 => quin.subject,
279 1 => quin.predicate,
280 2 => quin.object,
281 3 => quin.context,
282 _ => 0,
283 };
284 condition_flag = value == bound_val;
285 } else {
286 condition_flag = false;
287 }
288 }
289 WebizenOpcode::HaltIfFalse => {
290 if !condition_flag {
291 return None;
292 }
293 }
294 WebizenOpcode::EmitQuin {
295 subject_reg,
296 predicate,
297 object,
298 context_reg,
299 } => {
300 if condition_flag {
301 let s = self.registers[*subject_reg].unwrap_or(0);
302 let c = self.registers[*context_reg].unwrap_or(0);
303
304 let mut resulting_quin = NQuin {
305 subject: s,
306 predicate: *predicate,
307 object: *object,
308 context: c,
309 metadata: quin.metadata,
310 parity: 0,
311 };
312
313 let clock = quin.extract_lamport_clock();
314 if clock < 0x1FFF_FFFF {
315 resulting_quin.set_lamport_clock(clock + 1);
316 }
317 if defeasible_tag {
318 resulting_quin.metadata |= 1 << 60;
319 }
320 emitted_quin = Some(resulting_quin);
321 }
322 }
323 WebizenOpcode::LessThan { vector_id, value } => {
324 condition_flag =
325 Self::extract_float(quin, *vector_id).map_or(false, |v| v < *value);
326 }
327 WebizenOpcode::GreaterThan { vector_id, value } => {
328 condition_flag =
329 Self::extract_float(quin, *vector_id).map_or(false, |v| v > *value);
330 }
331 WebizenOpcode::LessOrEqual { vector_id, value } => {
332 condition_flag =
333 Self::extract_float(quin, *vector_id).map_or(false, |v| v <= *value);
334 }
335 WebizenOpcode::GreaterOrEqual { vector_id, value } => {
336 condition_flag =
337 Self::extract_float(quin, *vector_id).map_or(false, |v| v >= *value);
338 }
339 WebizenOpcode::Always(stress_threshold) => {
340 crate::telemetry::ATOMIC_INTEGRATION_STEPS
341 .fetch_add(50, std::sync::atomic::Ordering::Relaxed);
342 condition_flag = Self::extract_float(quin, 2)
343 .map_or(false, |stress| stress < *stress_threshold as f32);
344 }
345 WebizenOpcode::Eventually(stress_threshold) => {
346 crate::telemetry::ATOMIC_INTEGRATION_STEPS
347 .fetch_add(50, std::sync::atomic::Ordering::Relaxed);
348 condition_flag = Self::extract_float(quin, 2)
349 .map_or(false, |stress| stress >= *stress_threshold as f32);
350 }
351 WebizenOpcode::Next(stress_threshold) => {
352 crate::telemetry::ATOMIC_INTEGRATION_STEPS
353 .fetch_add(50, std::sync::atomic::Ordering::Relaxed);
354 condition_flag = Self::extract_float(quin, 2)
355 .map_or(false, |stress| stress == *stress_threshold as f32);
356 }
357 WebizenOpcode::EmitCalculatedQuin {
358 subject_reg,
359 predicate,
360 object_calc_op,
361 context_reg,
362 } => {
363 if condition_flag {
364 let s = self.registers[*subject_reg].unwrap_or(0);
365 let c = self.registers[*context_reg].unwrap_or(0);
366
367 let calc_val = match object_calc_op {
369 1 => 42.0_f32, _ => 0.0_f32,
371 };
372
373 let mut resulting_quin = NQuin {
374 subject: s,
375 predicate: *predicate,
376 object: crate::frame_layout::pack_float_object(calc_val),
378 context: c,
379 metadata: quin.metadata,
380 parity: 0,
381 };
382
383 let clock = quin.extract_lamport_clock();
384 if clock < 0x1FFF_FFFF {
385 resulting_quin.set_lamport_clock(clock + 1);
386 }
387 if defeasible_tag {
388 resulting_quin.metadata |= 1 << 60;
389 }
390 emitted_quin = Some(resulting_quin);
391 }
392 }
393 WebizenOpcode::YieldConfidence(threshold) => {
394 let stochastic_weight = crate::frame_layout::truth_degree(quin.metadata);
395 if stochastic_weight < *threshold {
396 defeasible_tag = true;
397 }
398 }
399 WebizenOpcode::LoadModel(model_id) => {
400 if let Some(ref lock) = self.scrubbing_lock {
401 if lock.load(std::sync::atomic::Ordering::Acquire) {
402 self.yielded_op = Some(WebizenOpcode::LoadModel(*model_id));
403 return None; }
405 }
406 }
407 WebizenOpcode::EvictModel(_) => {}
408 }
409 }
410
411 emitted_quin
412 }
413
414 #[inline(always)]
422 fn extract_float(quin: &NQuin, vector_id: u8) -> Option<f32> {
423 let val = match vector_id {
424 0 => quin.subject,
425 1 => quin.predicate,
426 2 => quin.object,
427 3 => quin.context,
428 _ => return None,
429 };
430
431 if val & crate::frame_layout::INLINE_TAG_MASK == crate::frame_layout::INLINE_TAG_FLOAT {
432 Some(extract_inline_float(val))
433 } else {
434 None
435 }
436 }
437
438 pub fn prune_defeasible_claims(qualia_graph: &mut [NQuin]) -> usize {
440 let mut retained = 0;
441
442 for read_idx in 0..qualia_graph.len() {
443 let quin = qualia_graph[read_idx];
444 let is_defeasible = (quin.metadata & (1 << 60)) != 0;
445 let has_hard_fact_for_subject = qualia_graph.iter().any(|candidate| {
446 candidate.subject == quin.subject && (candidate.metadata & (1 << 60)) == 0
447 });
448
449 if is_defeasible && has_hard_fact_for_subject {
450 continue;
451 }
452
453 qualia_graph[retained] = quin;
454 retained += 1;
455 }
456
457 for slot in &mut qualia_graph[retained..] {
458 *slot = NQuin::default();
459 }
460
461 retained
462 }
463}
464
465#[inline(always)]
468pub fn extract_inline_float(object_vector: u64) -> f32 {
469 let raw_bits = (object_vector & 0x0000_0000_FFFF_FFFF) as u32;
471 f32::from_bits(raw_bits)
472}
473
474pub struct WebizenCompiler;
476
477impl WebizenCompiler {
478 const MOCK_CONSTRAINT: [WebizenOpcode; 4] = [
479 WebizenOpcode::MatchPredicate(100), WebizenOpcode::HaltIfFalse,
481 WebizenOpcode::MatchObject(18),
483 WebizenOpcode::HaltIfFalse,
484 ];
485
486 const DIAGNOSTIC_CONSTRAINT: [WebizenOpcode; 6] = [
487 WebizenOpcode::MatchPredicate(100), WebizenOpcode::MatchObject(200), WebizenOpcode::HaltIfFalse,
490 WebizenOpcode::BindRegister {
491 vector_id: 0,
492 register_index: 0,
493 },
494 WebizenOpcode::BindRegister {
495 vector_id: 3,
496 register_index: 1,
497 },
498 WebizenOpcode::EmitQuin {
500 subject_reg: 0,
501 predicate: 300,
502 object: 400,
503 context_reg: 1,
504 },
505 ];
506
507 pub fn compile_mock_constraint() -> &'static [WebizenOpcode] {
510 &Self::MOCK_CONSTRAINT
511 }
512
513 pub fn compile_diagnostic_constraint() -> &'static [WebizenOpcode] {
516 &Self::DIAGNOSTIC_CONSTRAINT
517 }
518}
519
520#[derive(Debug, Clone, Copy, PartialEq, Eq)]
521pub enum DiagnosticError {
522 OutputBufferFull,
523}
524
525pub fn execute_differential_diagnostics(
529 qualia_graph: &[NQuin],
530 out: &mut [NQuin],
531) -> Result<usize, DiagnosticError> {
532 let mut written = 0;
533 let mut vm = WebizenVM::new();
534 let diagnostic_rules = WebizenCompiler::compile_diagnostic_constraint();
535 vm.load_bytecode(diagnostic_rules);
536
537 for quin in qualia_graph {
538 if let Some(inferred_quin) = vm.execute_implication(quin) {
539 if written >= out.len() {
540 return Err(DiagnosticError::OutputBufferFull);
541 }
542
543 out[written] = inferred_quin;
544 written += 1;
545 }
546 }
547
548 Ok(written)
549}
550
551#[cfg(test)]
552mod tests {
553 use super::*;
554
555 #[test]
556 fn test_webizen_vm_execution() {
557 let mut vm = WebizenVM::new();
558 let bytecode = vec![
559 WebizenOpcode::MatchPredicate(42),
560 WebizenOpcode::HaltIfFalse,
561 WebizenOpcode::BindRegister {
562 vector_id: 0,
563 register_index: 0,
564 },
565 WebizenOpcode::HaltIfFalse,
566 ];
567 vm.load_bytecode(&bytecode);
568
569 let valid_quin = NQuin {
571 subject: 999,
572 predicate: 42,
573 object: 0,
574 context: 0,
575 metadata: 0,
576 parity: 0,
577 };
578
579 let invalid_quin = NQuin {
581 subject: 999,
582 predicate: 99,
583 object: 0,
584 context: 0,
585 metadata: 0,
586 parity: 0,
587 };
588
589 assert_eq!(
590 vm.execute_constraint(&valid_quin),
591 true,
592 "VM failed to execute valid bytecode constraint"
593 );
594 assert_eq!(
595 vm.registers[0],
596 Some(999),
597 "VM failed to bind Subject to Register 0"
598 );
599
600 assert_eq!(
601 vm.execute_constraint(&invalid_quin),
602 false,
603 "VM erroneously passed invalid quin constraint"
604 );
605 }
606
607 #[test]
608 fn test_qualia_n3_implication() {
609 let mut vm = WebizenVM::new();
610 let bytecode = vec![
612 WebizenOpcode::MatchPredicate(42),
613 WebizenOpcode::HaltIfFalse,
614 WebizenOpcode::BindRegister {
615 vector_id: 0,
616 register_index: 0,
617 }, WebizenOpcode::BindRegister {
619 vector_id: 3,
620 register_index: 1,
621 }, WebizenOpcode::EmitQuin {
623 subject_reg: 0,
624 predicate: 100,
625 object: 999,
626 context_reg: 1,
627 },
628 ];
629 vm.load_bytecode(&bytecode);
630
631 let _input_quin = crate::q_turtle!("Alice", "knows", "Bob");
633 let trigger_quin = NQuin {
635 subject: 123,
636 predicate: 42,
637 object: 456,
638 context: 789,
639 metadata: 0b01 << 61,
640 parity: 0,
641 };
642
643 let result = vm.execute_implication(&trigger_quin);
644 assert!(
645 result.is_some(),
646 "Implication should have yielded a consequent Quin"
647 );
648
649 let output = result.unwrap();
650 assert_eq!(output.subject, 123, "Subject was not bound properly");
651 assert_eq!(
652 output.predicate, 100,
653 "Consequent predicate not emitted properly"
654 );
655 assert_eq!(output.object, 999, "Consequent object not emitted properly");
656 assert_eq!(output.context, 789, "Context was not carried over");
657 assert_eq!(
658 output.identify_routing_lane(),
659 crate::PermissiveRoutingLane::EnforcePermissiveCommons,
660 "Routing lane was not inherited"
661 );
662 assert_eq!(
663 output.extract_lamport_clock(),
664 1,
665 "Lamport clock did not advance"
666 );
667
668 let qt = crate::q_turtle!("Alice", "knows", "Bob");
670 assert_eq!(qt.subject, crate::q_hash("Alice"));
671 assert_eq!(qt.predicate, crate::q_hash("knows"));
672 assert_eq!(qt.object, crate::q_hash("Bob"));
673 assert_eq!(
674 qt.identify_routing_lane(),
675 crate::PermissiveRoutingLane::EnforcePermissiveCommons
676 );
677 }
678
679 #[test]
680 fn test_webizen_float_logic() {
681 let mut vm = WebizenVM::new();
682 let float_val = 3.14_f32;
684 let tagged_object = crate::frame_layout::pack_float_object(float_val);
685
686 let q = NQuin {
687 subject: 0,
688 predicate: 0,
689 object: tagged_object,
690 context: 0,
691 metadata: 0,
692 parity: 0,
693 };
694
695 let bytecode = vec![
696 WebizenOpcode::LessThan {
697 vector_id: 2,
698 value: 4.0,
699 }, WebizenOpcode::HaltIfFalse,
701 WebizenOpcode::GreaterThan {
702 vector_id: 2,
703 value: 3.0,
704 }, WebizenOpcode::HaltIfFalse,
706 ];
707
708 vm.load_bytecode(&bytecode);
709 assert_eq!(
710 vm.execute_constraint(&q),
711 true,
712 "VM failed to execute continuous float bounds"
713 );
714 }
715
716 #[test]
717 fn test_prune_defeasible_claims_partitions_in_place() {
718 let hard_fact = NQuin {
719 subject: 1,
720 predicate: 10,
721 object: 100,
722 context: 7,
723 metadata: 0,
724 parity: 0,
725 };
726 let defeasible_same_subject = NQuin {
727 subject: 1,
728 predicate: 11,
729 object: 101,
730 context: 7,
731 metadata: 1 << 60,
732 parity: 0,
733 };
734 let defeasible_other_subject = NQuin {
735 subject: 2,
736 predicate: 12,
737 object: 102,
738 context: 7,
739 metadata: 1 << 60,
740 parity: 0,
741 };
742
743 let mut graph = [hard_fact, defeasible_same_subject, defeasible_other_subject];
744 let retained = WebizenVM::prune_defeasible_claims(&mut graph);
745
746 assert_eq!(retained, 2);
747 assert_eq!(graph[0], hard_fact);
748 assert_eq!(graph[1], defeasible_other_subject);
749 assert_eq!(graph[2], NQuin::default());
750 }
751
752 #[test]
753 fn test_execute_differential_diagnostics_writes_to_output_buffer() {
754 let trigger_quin = NQuin {
755 subject: 123,
756 predicate: 100,
757 object: 200,
758 context: 789,
759 metadata: 0b01 << 61,
760 parity: 0,
761 };
762 let mut out = [NQuin::default(); 1];
763
764 let written = execute_differential_diagnostics(&[trigger_quin], &mut out).unwrap();
765
766 assert_eq!(written, 1);
767 assert_eq!(out[0].subject, 123);
768 assert_eq!(out[0].predicate, 300);
769 assert_eq!(out[0].object, 400);
770 assert_eq!(out[0].context, 789);
771 }
772
773 #[test]
774 fn test_execute_differential_diagnostics_reports_output_overflow() {
775 let trigger = NQuin {
776 subject: 123,
777 predicate: 100,
778 object: 200,
779 context: 789,
780 metadata: 0,
781 parity: 0,
782 };
783 let inputs = [
784 trigger,
785 NQuin {
786 subject: 456,
787 ..trigger
788 },
789 ];
790 let mut out = [NQuin::default(); 1];
791
792 let result = execute_differential_diagnostics(&inputs, &mut out);
793
794 assert_eq!(result, Err(DiagnosticError::OutputBufferFull));
795 }
796}