1use serde::{Deserialize, Serialize};
4use std::collections::{BTreeMap, HashMap};
5
6pub const HOSTCALL_SUPERINSTRUCTION_SCHEMA_VERSION: &str = "pi.ext.hostcall_superinstruction.v1";
8pub const HOSTCALL_SUPERINSTRUCTION_PLAN_VERSION: u16 = 1;
10
11const DEFAULT_MIN_SUPPORT: u32 = 3;
12const DEFAULT_MAX_WINDOW: usize = 4;
13const BASE_OPCODE_COST_UNITS: i64 = 10;
14const FUSED_OPCODE_FIXED_COST_UNITS: i64 = 6;
15const FUSED_OPCODE_STEP_COST_UNITS: i64 = 2;
16
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19pub struct HostcallSuperinstructionPlan {
20 pub schema: String,
21 pub version: u16,
22 pub plan_id: String,
23 pub trace_signature: String,
24 pub opcode_window: Vec<String>,
25 pub support_count: u32,
26 pub estimated_cost_baseline: i64,
27 pub estimated_cost_fused: i64,
28 pub expected_cost_delta: i64,
29}
30
31impl HostcallSuperinstructionPlan {
32 #[must_use]
33 pub fn width(&self) -> usize {
34 self.opcode_window.len()
35 }
36
37 #[must_use]
38 pub fn matches_trace_prefix(&self, trace: &[String]) -> bool {
39 trace.len() >= self.opcode_window.len()
40 && trace
41 .iter()
42 .zip(self.opcode_window.iter())
43 .all(|(left, right)| left == right)
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq)]
49pub struct HostcallSuperinstructionCompiler {
50 enabled: bool,
51 min_support: u32,
52 max_window: usize,
53}
54
55impl Default for HostcallSuperinstructionCompiler {
56 fn default() -> Self {
57 Self::from_env()
58 }
59}
60
61impl HostcallSuperinstructionCompiler {
62 #[must_use]
63 pub const fn new(enabled: bool, min_support: u32, max_window: usize) -> Self {
64 Self {
65 enabled,
66 min_support,
67 max_window,
68 }
69 }
70
71 #[must_use]
72 pub fn from_env() -> Self {
73 let enabled = bool_from_env("PI_HOSTCALL_SUPERINSTRUCTIONS", true);
74 let min_support = std::env::var("PI_HOSTCALL_SUPERINSTRUCTION_MIN_SUPPORT")
75 .ok()
76 .and_then(|raw| raw.trim().parse::<u32>().ok())
77 .map_or(DEFAULT_MIN_SUPPORT, |value| value.max(2));
78 let max_window = std::env::var("PI_HOSTCALL_SUPERINSTRUCTION_MAX_WINDOW")
79 .ok()
80 .and_then(|raw| raw.trim().parse::<usize>().ok())
81 .map_or(DEFAULT_MAX_WINDOW, |value| value.max(2));
82 Self::new(enabled, min_support, max_window)
83 }
84
85 #[must_use]
86 pub const fn enabled(&self) -> bool {
87 self.enabled
88 }
89
90 #[must_use]
91 pub const fn min_support(&self) -> u32 {
92 self.min_support
93 }
94
95 #[must_use]
96 pub const fn max_window(&self) -> usize {
97 self.max_window
98 }
99
100 #[must_use]
102 pub fn compile_plans(&self, traces: &[Vec<String>]) -> Vec<HostcallSuperinstructionPlan> {
103 if !self.enabled {
104 return Vec::new();
105 }
106 let mut windows: BTreeMap<Vec<String>, u32> = BTreeMap::new();
107 for trace in traces {
108 let trace_len = trace.len();
109 if trace_len < 2 {
110 continue;
111 }
112 let max_width = self.max_window.min(trace_len);
113 for width in 2..=max_width {
114 let mut next_valid: HashMap<&[String], usize> = HashMap::new();
115 for start in 0..=trace_len - width {
116 let window_slice = &trace[start..start + width];
117 if window_slice.iter().any(|opcode| opcode.trim().is_empty()) {
118 continue;
119 }
120
121 let min_start = *next_valid.get(window_slice).unwrap_or(&0);
122 if start >= min_start {
123 let entry = windows.entry(window_slice.to_vec()).or_insert(0);
124 *entry = entry.saturating_add(1);
125 next_valid.insert(window_slice, start + width);
126 }
127 }
128 }
129 }
130
131 let mut plans = windows
132 .into_iter()
133 .filter_map(|(opcode_window, support_count)| {
134 if support_count < self.min_support {
135 return None;
136 }
137 let estimated_cost_baseline = estimated_baseline_cost(opcode_window.len());
138 let estimated_cost_fused = estimated_fused_cost(opcode_window.len());
139 let expected_cost_delta =
140 estimated_cost_baseline.saturating_sub(estimated_cost_fused);
141 if expected_cost_delta <= 0 {
142 return None;
143 }
144
145 let trace_signature = opcode_window_signature(&opcode_window);
146 let plan_id = format!("fuse_{trace_signature}");
147 Some(HostcallSuperinstructionPlan {
148 schema: HOSTCALL_SUPERINSTRUCTION_SCHEMA_VERSION.to_string(),
149 version: HOSTCALL_SUPERINSTRUCTION_PLAN_VERSION,
150 plan_id,
151 trace_signature,
152 opcode_window,
153 support_count,
154 estimated_cost_baseline,
155 estimated_cost_fused,
156 expected_cost_delta,
157 })
158 })
159 .collect::<Vec<_>>();
160
161 plans.sort_by(|left, right| {
162 right
163 .expected_cost_delta
164 .cmp(&left.expected_cost_delta)
165 .then_with(|| right.support_count.cmp(&left.support_count))
166 .then_with(|| right.width().cmp(&left.width()))
167 .then_with(|| left.opcode_window.cmp(&right.opcode_window))
168 .then_with(|| left.plan_id.cmp(&right.plan_id))
169 });
170 plans
171 }
172}
173
174#[derive(Debug, Clone, PartialEq, Eq)]
176pub struct HostcallSuperinstructionSelection {
177 pub trace_signature: String,
178 pub selected_plan_id: Option<String>,
179 pub selected_window: Option<Vec<String>>,
180 pub expected_cost_delta: i64,
181 pub deopt_reason: Option<&'static str>,
182}
183
184impl HostcallSuperinstructionSelection {
185 #[must_use]
186 pub const fn hit(&self) -> bool {
187 self.selected_plan_id.is_some()
188 }
189}
190
191#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct HostcallSuperinstructionExecution {
194 pub canonical_trace: Vec<String>,
195 pub fused_trace: Vec<String>,
196 pub selection: HostcallSuperinstructionSelection,
197}
198
199#[must_use]
201pub fn select_plan_for_trace(
202 trace: &[String],
203 plans: &[HostcallSuperinstructionPlan],
204) -> HostcallSuperinstructionSelection {
205 let trace_signature = opcode_window_signature(trace);
206 if trace.is_empty() {
207 return HostcallSuperinstructionSelection {
208 trace_signature,
209 selected_plan_id: None,
210 selected_window: None,
211 expected_cost_delta: 0,
212 deopt_reason: Some("empty_trace"),
213 };
214 }
215
216 let mut matching = plans
217 .iter()
218 .filter(|plan| plan.matches_trace_prefix(trace))
219 .collect::<Vec<_>>();
220 if matching.is_empty() {
221 return HostcallSuperinstructionSelection {
222 trace_signature,
223 selected_plan_id: None,
224 selected_window: None,
225 expected_cost_delta: 0,
226 deopt_reason: Some("no_matching_plan"),
227 };
228 }
229
230 matching.sort_by(|left, right| {
231 right
232 .expected_cost_delta
233 .cmp(&left.expected_cost_delta)
234 .then_with(|| right.support_count.cmp(&left.support_count))
235 .then_with(|| right.width().cmp(&left.width()))
236 .then_with(|| left.plan_id.cmp(&right.plan_id))
237 });
238
239 let best = matching[0];
240 if matching.iter().skip(1).any(|candidate| {
241 candidate.expected_cost_delta == best.expected_cost_delta
242 && candidate.support_count == best.support_count
243 && candidate.width() == best.width()
244 }) {
245 return HostcallSuperinstructionSelection {
246 trace_signature,
247 selected_plan_id: None,
248 selected_window: None,
249 expected_cost_delta: 0,
250 deopt_reason: Some("ambiguous_top_plan"),
251 };
252 }
253
254 HostcallSuperinstructionSelection {
255 trace_signature,
256 selected_plan_id: Some(best.plan_id.clone()),
257 selected_window: Some(best.opcode_window.clone()),
258 expected_cost_delta: best.expected_cost_delta,
259 deopt_reason: None,
260 }
261}
262
263#[must_use]
267pub fn execute_with_superinstruction(
268 trace: &[String],
269 plans: &[HostcallSuperinstructionPlan],
270) -> HostcallSuperinstructionExecution {
271 let canonical_trace = trace.to_vec();
272 let selection = select_plan_for_trace(trace, plans);
273 if !selection.hit() {
274 return HostcallSuperinstructionExecution {
275 canonical_trace: canonical_trace.clone(),
276 fused_trace: canonical_trace,
277 selection,
278 };
279 }
280
281 let mut fused_trace = Vec::new();
282 if let Some(plan_id) = selection.selected_plan_id.as_ref() {
283 fused_trace.push(format!("@{plan_id}"));
284 }
285 let consumed = selection
286 .selected_window
287 .as_ref()
288 .map_or(0, std::vec::Vec::len)
289 .min(trace.len());
290 fused_trace.extend_from_slice(&trace[consumed..]);
291
292 HostcallSuperinstructionExecution {
293 canonical_trace,
294 fused_trace,
295 selection,
296 }
297}
298
299fn estimated_baseline_cost(width: usize) -> i64 {
300 let width_units = i64::try_from(width).unwrap_or(i64::MAX);
301 width_units.saturating_mul(BASE_OPCODE_COST_UNITS)
302}
303
304fn estimated_fused_cost(width: usize) -> i64 {
305 let width_units = i64::try_from(width).unwrap_or(i64::MAX);
306 FUSED_OPCODE_FIXED_COST_UNITS
307 .saturating_add(width_units.saturating_mul(FUSED_OPCODE_STEP_COST_UNITS))
308}
309
310fn opcode_window_signature(window: &[String]) -> String {
311 let mut hash = 0xcbf2_9ce4_8422_2325_u64;
312 for opcode in window {
313 for byte in opcode.as_bytes() {
314 hash ^= u64::from(*byte);
315 hash = hash.wrapping_mul(0x0100_0000_01b3_u64);
316 }
317 hash ^= u64::from(b'|');
318 hash = hash.wrapping_mul(0x0100_0000_01b3_u64);
319 }
320 format!("{hash:016x}")
321}
322
323fn bool_from_env(var: &str, default: bool) -> bool {
324 std::env::var(var).ok().as_deref().map_or(default, |value| {
325 match value.trim().to_ascii_lowercase().as_str() {
326 "1" | "true" | "on" | "enabled" | "yes" => true,
327 "0" | "false" | "off" | "disabled" | "no" => false,
328 _ => default,
329 }
330 })
331}
332
333#[cfg(test)]
334mod tests {
335 use super::*;
336
337 fn opcode_trace(values: &[&str]) -> Vec<String> {
338 values.iter().map(ToString::to_string).collect()
339 }
340
341 fn plan(
342 plan_id: &str,
343 window: &[&str],
344 support_count: u32,
345 expected_cost_delta: i64,
346 ) -> HostcallSuperinstructionPlan {
347 HostcallSuperinstructionPlan {
348 schema: HOSTCALL_SUPERINSTRUCTION_SCHEMA_VERSION.to_string(),
349 version: HOSTCALL_SUPERINSTRUCTION_PLAN_VERSION,
350 plan_id: plan_id.to_string(),
351 trace_signature: opcode_window_signature(&opcode_trace(window)),
352 opcode_window: opcode_trace(window),
353 support_count,
354 estimated_cost_baseline: 0,
355 estimated_cost_fused: 0,
356 expected_cost_delta,
357 }
358 }
359
360 #[test]
361 fn compiler_extracts_hot_windows_deterministically() {
362 let compiler = HostcallSuperinstructionCompiler::new(true, 2, 4);
363 let traces = vec![
364 opcode_trace(&[
365 "session.get_state",
366 "session.get_messages",
367 "session.get_entries",
368 "events.list_flags",
369 ]),
370 opcode_trace(&[
371 "session.get_state",
372 "session.get_messages",
373 "session.get_entries",
374 "events.emit",
375 ]),
376 opcode_trace(&[
377 "session.get_state",
378 "session.get_messages",
379 "session.get_entries",
380 "events.get_model",
381 ]),
382 ];
383
384 let plans = compiler.compile_plans(&traces);
385 assert!(!plans.is_empty());
386 assert!(plans.iter().any(|entry| {
387 entry.opcode_window
388 == opcode_trace(&[
389 "session.get_state",
390 "session.get_messages",
391 "session.get_entries",
392 ])
393 }));
394
395 let reversed = traces.iter().rev().cloned().collect::<Vec<_>>();
396 let plans_reversed = compiler.compile_plans(&reversed);
397 assert_eq!(plans, plans_reversed);
398 }
399
400 #[test]
401 fn selection_prefers_higher_delta_then_support_then_width() {
402 let trace = opcode_trace(&["tool.read", "events.list", "events.get_model"]);
403 let plans = vec![
404 plan("p_low_delta", &["tool.read", "events.list"], 8, 10),
405 plan(
406 "p_best",
407 &["tool.read", "events.list", "events.get_model"],
408 7,
409 14,
410 ),
411 plan(
412 "p_low_support",
413 &["tool.read", "events.list", "events.get_model"],
414 4,
415 14,
416 ),
417 ];
418
419 let selected = select_plan_for_trace(&trace, &plans);
420 assert_eq!(selected.selected_plan_id.as_deref(), Some("p_best"));
421 assert!(selected.deopt_reason.is_none());
422 assert!(selected.hit());
423 }
424
425 #[test]
426 fn selection_deopts_on_ambiguous_top_plan() {
427 let trace = opcode_trace(&["session.get_state", "session.get_entries"]);
428 let plans = vec![
429 plan("p_a", &["session.get_state", "session.get_entries"], 5, 11),
430 plan("p_b", &["session.get_state", "session.get_entries"], 5, 11),
431 ];
432
433 let selected = select_plan_for_trace(&trace, &plans);
434 assert!(!selected.hit());
435 assert_eq!(selected.deopt_reason, Some("ambiguous_top_plan"));
436 }
437
438 #[test]
439 fn execution_preserves_canonical_semantics_with_fused_projection() {
440 let trace = opcode_trace(&[
441 "session.get_state",
442 "session.get_messages",
443 "session.get_entries",
444 "events.list",
445 ]);
446 let plans = vec![plan(
447 "p_fuse",
448 &[
449 "session.get_state",
450 "session.get_messages",
451 "session.get_entries",
452 ],
453 6,
454 18,
455 )];
456
457 let execution = execute_with_superinstruction(&trace, &plans);
458 assert_eq!(execution.canonical_trace, trace);
459 assert_eq!(execution.fused_trace.len(), 2);
460 assert_eq!(execution.fused_trace[0], "@p_fuse");
461 assert_eq!(execution.fused_trace[1], "events.list");
462 assert!(execution.selection.hit());
463 }
464
465 #[test]
466 fn execution_deopts_immediately_on_guard_mismatch() {
467 let trace = opcode_trace(&["events.get_model", "events.set_model"]);
468 let plans = vec![plan("p_tool", &["tool.read", "tool.write"], 9, 12)];
469
470 let execution = execute_with_superinstruction(&trace, &plans);
471 assert_eq!(execution.canonical_trace, trace);
472 assert_eq!(execution.fused_trace, execution.canonical_trace);
473 assert!(!execution.selection.hit());
474 assert_eq!(execution.selection.deopt_reason, Some("no_matching_plan"));
475 }
476
477 #[test]
480 fn estimated_baseline_cost_is_linear_in_width() {
481 assert_eq!(estimated_baseline_cost(1), BASE_OPCODE_COST_UNITS);
482 assert_eq!(estimated_baseline_cost(2), 2 * BASE_OPCODE_COST_UNITS);
483 assert_eq!(estimated_baseline_cost(4), 4 * BASE_OPCODE_COST_UNITS);
484 assert_eq!(estimated_baseline_cost(0), 0);
485 }
486
487 #[test]
488 fn estimated_fused_cost_is_fixed_plus_step() {
489 assert_eq!(
490 estimated_fused_cost(2),
491 FUSED_OPCODE_FIXED_COST_UNITS + 2 * FUSED_OPCODE_STEP_COST_UNITS
492 );
493 assert_eq!(
494 estimated_fused_cost(4),
495 FUSED_OPCODE_FIXED_COST_UNITS + 4 * FUSED_OPCODE_STEP_COST_UNITS
496 );
497 assert_eq!(estimated_fused_cost(0), FUSED_OPCODE_FIXED_COST_UNITS);
498 }
499
500 #[test]
501 fn fused_cost_always_less_than_baseline_for_width_ge_2() {
502 for width in 2..=32 {
503 let baseline = estimated_baseline_cost(width);
504 let fused = estimated_fused_cost(width);
505 assert!(
506 fused < baseline,
507 "fused ({fused}) should be less than baseline ({baseline}) at width {width}"
508 );
509 }
510 }
511
512 #[test]
515 fn compiler_disabled_returns_empty_plans() {
516 let compiler = HostcallSuperinstructionCompiler::new(false, 2, 4);
517 let traces = vec![
518 opcode_trace(&["a", "b", "c"]),
519 opcode_trace(&["a", "b", "c"]),
520 opcode_trace(&["a", "b", "c"]),
521 ];
522 let plans = compiler.compile_plans(&traces);
523 assert!(plans.is_empty());
524 }
525
526 #[test]
529 fn compiler_ignores_single_opcode_traces() {
530 let compiler = HostcallSuperinstructionCompiler::new(true, 1, 4);
531 let traces = vec![
532 opcode_trace(&["single"]),
533 opcode_trace(&["single"]),
534 opcode_trace(&["single"]),
535 ];
536 let plans = compiler.compile_plans(&traces);
537 assert!(plans.is_empty());
538 }
539
540 #[test]
541 fn compiler_ignores_empty_traces() {
542 let compiler = HostcallSuperinstructionCompiler::new(true, 1, 4);
543 let plans = compiler.compile_plans(&[Vec::new(), Vec::new()]);
544 assert!(plans.is_empty());
545 }
546
547 #[test]
548 fn compiler_skips_windows_with_empty_opcodes() {
549 let compiler = HostcallSuperinstructionCompiler::new(true, 1, 4);
550 let traces = vec![opcode_trace(&["a", "", "c"]), opcode_trace(&["a", "", "c"])];
551 let plans = compiler.compile_plans(&traces);
552 assert!(
554 plans
555 .iter()
556 .all(|p| p.opcode_window.iter().all(|op| !op.trim().is_empty())),
557 "no plan should contain empty opcodes"
558 );
559 }
560
561 #[test]
562 fn compiler_respects_min_support_threshold() {
563 let compiler = HostcallSuperinstructionCompiler::new(true, 5, 4);
564 let traces = vec![
566 opcode_trace(&["a", "b"]),
567 opcode_trace(&["a", "b"]),
568 opcode_trace(&["a", "b"]),
569 ];
570 let plans = compiler.compile_plans(&traces);
571 assert!(plans.is_empty(), "support 3 < min_support 5");
572 }
573
574 #[test]
575 fn compiler_respects_max_window_size() {
576 let compiler = HostcallSuperinstructionCompiler::new(true, 2, 2);
577 let traces = vec![
578 opcode_trace(&["a", "b", "c", "d"]),
579 opcode_trace(&["a", "b", "c", "d"]),
580 opcode_trace(&["a", "b", "c", "d"]),
581 ];
582 let plans = compiler.compile_plans(&traces);
583 assert!(
584 plans.iter().all(|p| p.width() <= 2),
585 "max_window=2 should cap window width"
586 );
587 }
588
589 #[test]
590 fn compiler_plans_sorted_by_cost_delta_descending() {
591 let compiler = HostcallSuperinstructionCompiler::new(true, 2, 4);
592 let traces = vec![
593 opcode_trace(&["a", "b", "c", "d"]),
594 opcode_trace(&["a", "b", "c", "d"]),
595 opcode_trace(&["a", "b", "c", "d"]),
596 ];
597 let plans = compiler.compile_plans(&traces);
598 for pair in plans.windows(2) {
599 assert!(
600 pair[0].expected_cost_delta >= pair[1].expected_cost_delta,
601 "plans should be sorted by cost delta descending"
602 );
603 }
604 }
605
606 #[test]
609 fn plan_serde_roundtrip() {
610 let compiler = HostcallSuperinstructionCompiler::new(true, 2, 4);
611 let traces = vec![
612 opcode_trace(&["x", "y", "z"]),
613 opcode_trace(&["x", "y", "z"]),
614 opcode_trace(&["x", "y", "z"]),
615 ];
616 let plans = compiler.compile_plans(&traces);
617 assert!(!plans.is_empty());
618 for p in &plans {
619 let json = serde_json::to_string(p).expect("serialize");
620 let roundtrip: HostcallSuperinstructionPlan =
621 serde_json::from_str(&json).expect("deserialize");
622 assert_eq!(*p, roundtrip);
623 assert_eq!(p.schema, HOSTCALL_SUPERINSTRUCTION_SCHEMA_VERSION);
624 assert_eq!(p.version, HOSTCALL_SUPERINSTRUCTION_PLAN_VERSION);
625 }
626 }
627
628 #[test]
631 fn matches_trace_prefix_exact() {
632 let p = plan("test", &["a", "b"], 3, 10);
633 assert!(p.matches_trace_prefix(&opcode_trace(&["a", "b"])));
634 assert!(p.matches_trace_prefix(&opcode_trace(&["a", "b", "c"])));
635 assert!(!p.matches_trace_prefix(&opcode_trace(&["a"])));
636 assert!(!p.matches_trace_prefix(&opcode_trace(&["b", "a"])));
637 assert!(!p.matches_trace_prefix(&[]));
638 }
639
640 #[test]
643 fn selection_on_empty_trace_returns_empty_trace_deopt() {
644 let plans = vec![plan("p", &["a", "b"], 3, 10)];
645 let selected = select_plan_for_trace(&[], &plans);
646 assert!(!selected.hit());
647 assert_eq!(selected.deopt_reason, Some("empty_trace"));
648 }
649
650 #[test]
651 fn selection_on_empty_plans_returns_no_matching_plan() {
652 let trace = opcode_trace(&["a", "b"]);
653 let selected = select_plan_for_trace(&trace, &[]);
654 assert!(!selected.hit());
655 assert_eq!(selected.deopt_reason, Some("no_matching_plan"));
656 }
657
658 #[test]
661 fn opcode_window_signature_is_deterministic() {
662 let window = opcode_trace(&["session.get_state", "session.get_messages"]);
663 let sig1 = opcode_window_signature(&window);
664 let sig2 = opcode_window_signature(&window);
665 assert_eq!(sig1, sig2);
666 assert_eq!(sig1.len(), 16, "signature should be 16 hex chars");
667 }
668
669 #[test]
670 fn opcode_window_signature_differs_for_different_windows() {
671 let sig_ab = opcode_window_signature(&opcode_trace(&["a", "b"]));
672 let sig_ba = opcode_window_signature(&opcode_trace(&["b", "a"]));
673 let sig_abc = opcode_window_signature(&opcode_trace(&["a", "b", "c"]));
674 assert_ne!(sig_ab, sig_ba, "order matters");
675 assert_ne!(sig_ab, sig_abc, "different length windows differ");
676 }
677
678 #[test]
681 fn execution_fuses_entire_trace() {
682 let trace = opcode_trace(&["a", "b"]);
683 let plans = vec![plan("p_full", &["a", "b"], 5, 14)];
684 let execution = execute_with_superinstruction(&trace, &plans);
685 assert!(execution.selection.hit());
686 assert_eq!(execution.fused_trace, vec!["@p_full"]);
687 assert!(execution.fused_trace.len() < execution.canonical_trace.len());
688 }
689
690 #[test]
693 fn compiler_accessors_match_constructor() {
694 let compiler = HostcallSuperinstructionCompiler::new(true, 7, 5);
695 assert!(compiler.enabled());
696 assert_eq!(compiler.min_support(), 7);
697 assert_eq!(compiler.max_window(), 5);
698
699 let disabled = HostcallSuperinstructionCompiler::new(false, 2, 3);
700 assert!(!disabled.enabled());
701 }
702
703 mod proptest_superinstructions {
706 use super::*;
707 use proptest::prelude::*;
708
709 fn arb_opcode() -> impl Strategy<Value = String> {
710 prop::sample::select(vec![
711 "session.get_state".to_string(),
712 "session.get_messages".to_string(),
713 "events.list".to_string(),
714 "events.emit".to_string(),
715 "tool.read".to_string(),
716 "tool.write".to_string(),
717 "events.get_model".to_string(),
718 "session.set_label".to_string(),
719 ])
720 }
721
722 fn arb_trace() -> impl Strategy<Value = Vec<String>> {
723 prop::collection::vec(arb_opcode(), 0..6)
724 }
725
726 fn arb_compiler() -> impl Strategy<Value = HostcallSuperinstructionCompiler> {
727 (2..8u32, 2..6usize).prop_map(|(min_support, max_window)| {
728 HostcallSuperinstructionCompiler::new(true, min_support, max_window)
729 })
730 }
731
732 proptest! {
733 #[test]
734 fn compile_plans_is_deterministic(
735 compiler in arb_compiler(),
736 traces in prop::collection::vec(arb_trace(), 0..8),
737 ) {
738 let plans1 = compiler.compile_plans(&traces);
739 let plans2 = compiler.compile_plans(&traces);
740 assert!(plans1 == plans2, "compile_plans must be deterministic");
741 }
742
743 #[test]
744 fn all_plans_have_positive_cost_delta(
745 compiler in arb_compiler(),
746 traces in prop::collection::vec(arb_trace(), 1..8),
747 ) {
748 let plans = compiler.compile_plans(&traces);
749 for plan in &plans {
750 assert!(
751 plan.expected_cost_delta > 0,
752 "plan {} has non-positive delta {}",
753 plan.plan_id,
754 plan.expected_cost_delta,
755 );
756 }
757 }
758
759 #[test]
760 fn plans_sorted_by_cost_delta_descending(
761 compiler in arb_compiler(),
762 traces in prop::collection::vec(arb_trace(), 1..8),
763 ) {
764 let plans = compiler.compile_plans(&traces);
765 for pair in plans.windows(2) {
766 assert!(
767 pair[0].expected_cost_delta >= pair[1].expected_cost_delta,
768 "plans must be sorted by cost delta descending: {} vs {}",
769 pair[0].expected_cost_delta,
770 pair[1].expected_cost_delta,
771 );
772 }
773 }
774
775 #[test]
776 fn cost_delta_equals_baseline_minus_fused(
777 width in 2..64usize,
778 ) {
779 let baseline = estimated_baseline_cost(width);
780 let fused = estimated_fused_cost(width);
781 let delta = baseline.saturating_sub(fused);
782 assert!(
783 delta > 0,
784 "fused cost must be less than baseline for width {width}"
785 );
786 assert!(
787 delta == baseline - fused,
788 "delta must equal baseline - fused"
789 );
790 }
791
792 #[test]
793 fn fused_cost_strictly_less_than_baseline_for_width_ge_2(
794 width in 2..1000usize,
795 ) {
796 let baseline = estimated_baseline_cost(width);
797 let fused = estimated_fused_cost(width);
798 assert!(
799 fused < baseline,
800 "fused ({fused}) must be < baseline ({baseline}) at width {width}"
801 );
802 }
803
804 #[test]
805 fn opcode_window_signature_is_deterministic(
806 window in prop::collection::vec(arb_opcode(), 1..6),
807 ) {
808 let sig1 = opcode_window_signature(&window);
809 let sig2 = opcode_window_signature(&window);
810 assert!(sig1 == sig2, "signature must be deterministic");
811 assert!(sig1.len() == 16, "signature must be 16 hex chars");
812 }
813
814 #[test]
815 fn disabled_compiler_always_returns_empty(
816 min_support in 1..10u32,
817 max_window in 2..8usize,
818 traces in prop::collection::vec(arb_trace(), 0..8),
819 ) {
820 let compiler = HostcallSuperinstructionCompiler::new(false, min_support, max_window);
821 let plans = compiler.compile_plans(&traces);
822 assert!(plans.is_empty(), "disabled compiler must return no plans");
823 }
824
825 #[test]
826 fn plan_width_never_exceeds_max_window(
827 compiler in arb_compiler(),
828 traces in prop::collection::vec(arb_trace(), 1..8),
829 ) {
830 let plans = compiler.compile_plans(&traces);
831 for plan in &plans {
832 assert!(
833 plan.width() <= compiler.max_window(),
834 "plan width {} exceeds max_window {}",
835 plan.width(),
836 compiler.max_window(),
837 );
838 }
839 }
840
841 #[test]
842 fn plan_support_count_meets_min_support(
843 compiler in arb_compiler(),
844 traces in prop::collection::vec(arb_trace(), 1..10),
845 ) {
846 let plans = compiler.compile_plans(&traces);
847 for plan in &plans {
848 assert!(
849 plan.support_count >= compiler.min_support(),
850 "plan {} has support {} < min_support {}",
851 plan.plan_id,
852 plan.support_count,
853 compiler.min_support(),
854 );
855 }
856 }
857 }
858 }
859}