Skip to main content

nexus_rt/codegen_audit/
dag.rs

1//! DAG codegen audit cases.
2//!
3//! Categories 13-20 from the assembly audit plan.
4//!
5//! Key difference from pipeline: `root()` takes by-value step, all subsequent
6//! `.then()` calls take by-reference steps (`ref_*` helpers). DAGs produce
7//! `Handler<E>` where `run()` returns `()`, so chains end with a sink step.
8
9#![allow(clippy::type_complexity)]
10#![allow(unused_variables)]
11
12use super::helpers::*;
13use crate::dag::{DagArmSeed, DagBuilder};
14use crate::{Handler, IntoHandler, ResMut, World, fan_out, resolve_arm};
15
16// ═══════════════════════════════════════════════════════════════════
17// 13. DAG linear chains
18// ═══════════════════════════════════════════════════════════════════
19
20#[inline(never)]
21pub fn dag_linear_1(world: &mut World, input: u64) {
22    let reg = world.registry();
23    let mut d = DagBuilder::<u64>::new()
24        .root(add_one, &reg)
25        .then(ref_consume, &reg)
26        .build();
27    d.run(world, input);
28}
29
30#[inline(never)]
31pub fn dag_linear_3(world: &mut World, input: u64) {
32    let reg = world.registry();
33    let mut d = DagBuilder::<u64>::new()
34        .root(add_one, &reg)
35        .then(ref_double, &reg)
36        .then(ref_add_three, &reg)
37        .then(ref_consume, &reg)
38        .build();
39    d.run(world, input);
40}
41
42#[inline(never)]
43pub fn dag_linear_5(world: &mut World, input: u64) {
44    let reg = world.registry();
45    let mut d = DagBuilder::<u64>::new()
46        .root(add_one, &reg)
47        .then(ref_double, &reg)
48        .then(ref_add_three, &reg)
49        .then(ref_square, &reg)
50        .then(ref_sub_ten, &reg)
51        .then(ref_consume, &reg)
52        .build();
53    d.run(world, input);
54}
55
56#[inline(never)]
57pub fn dag_linear_10(world: &mut World, input: u64) {
58    let reg = world.registry();
59    let mut d = DagBuilder::<u64>::new()
60        .root(add_one, &reg)
61        .then(ref_double, &reg)
62        .then(ref_add_three, &reg)
63        .then(ref_square, &reg)
64        .then(ref_sub_ten, &reg)
65        .then(ref_shr_one, &reg)
66        .then(ref_xor_mask, &reg)
67        .then(ref_add_seven, &reg)
68        .then(ref_triple, &reg)
69        .then(ref_add_forty_two, &reg)
70        .then(ref_consume, &reg)
71        .build();
72    d.run(world, input);
73}
74
75#[inline(never)]
76pub fn dag_linear_20(world: &mut World, input: u64) {
77    let reg = world.registry();
78    let mut d = DagBuilder::<u64>::new()
79        .root(add_one, &reg)
80        .then(ref_double, &reg)
81        .then(ref_add_three, &reg)
82        .then(ref_square, &reg)
83        .then(ref_sub_ten, &reg)
84        .then(ref_shr_one, &reg)
85        .then(ref_xor_mask, &reg)
86        .then(ref_add_seven, &reg)
87        .then(ref_triple, &reg)
88        .then(ref_add_forty_two, &reg)
89        .then(ref_add_one, &reg)
90        .then(ref_double, &reg)
91        .then(ref_add_three, &reg)
92        .then(ref_square, &reg)
93        .then(ref_sub_ten, &reg)
94        .then(ref_shr_one, &reg)
95        .then(ref_xor_mask, &reg)
96        .then(ref_add_seven, &reg)
97        .then(ref_triple, &reg)
98        .then(ref_add_forty_two, &reg)
99        .then(ref_consume, &reg)
100        .build();
101    d.run(world, input);
102}
103
104#[inline(never)]
105pub fn dag_linear_mixed_arity(world: &mut World, input: u64) {
106    let reg = world.registry();
107    let mut d = DagBuilder::<u64>::new()
108        .root(add_one, &reg)
109        .then(ref_add_res_a, &reg)
110        .then(ref_write_res_a, &reg)
111        .then(ref_add_both, &reg)
112        .then(ref_three_params, &reg)
113        .then(ref_consume, &reg)
114        .build();
115    d.run(world, input);
116}
117
118// ═══════════════════════════════════════════════════════════════════
119// 14. DAG fork & merge
120// ═══════════════════════════════════════════════════════════════════
121
122#[inline(never)]
123pub fn dag_fork2_merge(world: &mut World, input: u64) {
124    let reg = world.registry();
125    let mut d = DagBuilder::<u64>::new()
126        .root(add_one, &reg)
127        .fork()
128        .arm(|a| a.then(ref_double, &reg))
129        .arm(|a| a.then(ref_triple, &reg))
130        .merge(merge_add, &reg)
131        .then(ref_consume, &reg)
132        .build();
133    d.run(world, input);
134}
135
136#[inline(never)]
137pub fn dag_fork3_merge(world: &mut World, input: u64) {
138    let reg = world.registry();
139    let mut d = DagBuilder::<u64>::new()
140        .root(add_one, &reg)
141        .fork()
142        .arm(|a| a.then(ref_double, &reg))
143        .arm(|a| a.then(ref_triple, &reg))
144        .arm(|a| a.then(ref_add_seven, &reg))
145        .merge(merge_3, &reg)
146        .then(ref_consume, &reg)
147        .build();
148    d.run(world, input);
149}
150
151#[inline(never)]
152pub fn dag_fork4_merge(world: &mut World, input: u64) {
153    let reg = world.registry();
154    let mut d = DagBuilder::<u64>::new()
155        .root(add_one, &reg)
156        .fork()
157        .arm(|a| a.then(ref_double, &reg))
158        .arm(|a| a.then(ref_triple, &reg))
159        .arm(|a| a.then(ref_add_seven, &reg))
160        .arm(|a| a.then(ref_xor_mask, &reg))
161        .merge(merge_4, &reg)
162        .then(ref_consume, &reg)
163        .build();
164    d.run(world, input);
165}
166
167#[inline(never)]
168pub fn dag_fork2_join(world: &mut World, input: u64) {
169    let reg = world.registry();
170    let mut d = DagBuilder::<u64>::new()
171        .root(add_one, &reg)
172        .fork()
173        .arm(|a| a.then(ref_consume, &reg))
174        .arm(|a| a.then(ref_consume, &reg))
175        .join()
176        .build();
177    d.run(world, input);
178}
179
180#[inline(never)]
181pub fn dag_fork3_join(world: &mut World, input: u64) {
182    let reg = world.registry();
183    let mut d = DagBuilder::<u64>::new()
184        .root(add_one, &reg)
185        .fork()
186        .arm(|a| a.then(ref_consume, &reg))
187        .arm(|a| a.then(ref_consume, &reg))
188        .arm(|a| a.then(ref_consume, &reg))
189        .join()
190        .build();
191    d.run(world, input);
192}
193
194#[inline(never)]
195pub fn dag_fork2_merge_consume(world: &mut World, input: u64) {
196    let reg = world.registry();
197    let mut d = DagBuilder::<u64>::new()
198        .root(add_one, &reg)
199        .fork()
200        .arm(|a| a.then(ref_double, &reg))
201        .arm(|a| a.then(ref_triple, &reg))
202        .merge(merge_consume, &reg)
203        .build();
204    d.run(world, input);
205}
206
207#[inline(never)]
208pub fn dag_fork3_merge_consume(world: &mut World, input: u64) {
209    let reg = world.registry();
210    let mut d = DagBuilder::<u64>::new()
211        .root(add_one, &reg)
212        .fork()
213        .arm(|a| a.then(ref_double, &reg))
214        .arm(|a| a.then(ref_triple, &reg))
215        .arm(|a| a.then(ref_add_seven, &reg))
216        .merge(merge_3_consume, &reg)
217        .build();
218    d.run(world, input);
219}
220
221#[inline(never)]
222pub fn dag_fork_heavy_arms(world: &mut World, input: u64) {
223    let reg = world.registry();
224    let mut d = DagBuilder::<u64>::new()
225        .root(add_one, &reg)
226        .fork()
227        .arm(|a| {
228            a.then(ref_double, &reg)
229                .then(ref_add_three, &reg)
230                .then(ref_square, &reg)
231                .then(ref_sub_ten, &reg)
232                .then(ref_shr_one, &reg)
233        })
234        .arm(|a| {
235            a.then(ref_add_one, &reg)
236                .then(ref_triple, &reg)
237                .then(ref_xor_mask, &reg)
238                .then(ref_add_seven, &reg)
239                .then(ref_add_forty_two, &reg)
240        })
241        .merge(merge_add, &reg)
242        .then(ref_consume, &reg)
243        .build();
244    d.run(world, input);
245}
246
247#[inline(never)]
248pub fn dag_nested_fork(world: &mut World, input: u64) {
249    let reg = world.registry();
250    let mut d = DagBuilder::<u64>::new()
251        .root(add_one, &reg)
252        .fork()
253        .arm(|a| {
254            a.then(ref_double, &reg)
255                .fork()
256                .arm(|b| b.then(ref_add_one, &reg))
257                .arm(|b| b.then(ref_triple, &reg))
258                .merge(merge_add, &reg)
259        })
260        .arm(|a| a.then(ref_add_seven, &reg))
261        .merge(merge_add, &reg)
262        .then(ref_consume, &reg)
263        .build();
264    d.run(world, input);
265}
266
267#[inline(never)]
268pub fn dag_diamond(world: &mut World, input: u64) {
269    let reg = world.registry();
270    // Diamond: root → fork(A, B) → merge → fork(C, D) → merge → sink
271    let mut d = DagBuilder::<u64>::new()
272        .root(add_one, &reg)
273        .fork()
274        .arm(|a| a.then(ref_double, &reg))
275        .arm(|a| a.then(ref_triple, &reg))
276        .merge(merge_add, &reg)
277        .fork()
278        .arm(|a| a.then(ref_square, &reg))
279        .arm(|a| a.then(ref_shr_one, &reg))
280        .merge(merge_mul, &reg)
281        .then(ref_consume, &reg)
282        .build();
283    d.run(world, input);
284}
285
286// -- Early termination stress: guard/result → long dead chain --
287
288#[inline(never)]
289pub fn dag_guard_skip_10(world: &mut World, input: u64) {
290    let reg = world.registry();
291    // Guard at step 1 → 10 maps on the Some path. If guard returns
292    // None, all 10 maps should be skipped — single branch?
293    let mut d = DagBuilder::<u64>::new()
294        .root(add_one, &reg)
295        .guard(|x: &u64| *x > 100, &reg)
296        .map(ref_double, &reg)
297        .map(ref_add_three, &reg)
298        .map(ref_square, &reg)
299        .map(ref_sub_ten, &reg)
300        .map(ref_shr_one, &reg)
301        .map(ref_xor_mask, &reg)
302        .map(ref_add_seven, &reg)
303        .map(ref_triple, &reg)
304        .map(ref_add_forty_two, &reg)
305        .map(ref_add_one, &reg)
306        .unwrap_or(0)
307        .then(ref_consume, &reg)
308        .build();
309    d.run(world, input);
310}
311
312#[inline(never)]
313pub fn dag_res_err_skip_10(world: &mut World, input: u64) {
314    let reg = world.registry();
315    // try_parse returns Err for large inputs. 10 result maps should
316    // be dead code on the Err path.
317    let mut d = DagBuilder::<u64>::new()
318        .root(try_parse, &reg)
319        .map(ref_add_one, &reg)
320        .map(ref_double, &reg)
321        .map(ref_add_three, &reg)
322        .map(ref_square, &reg)
323        .map(ref_sub_ten, &reg)
324        .map(ref_shr_one, &reg)
325        .map(ref_xor_mask, &reg)
326        .map(ref_add_seven, &reg)
327        .map(ref_triple, &reg)
328        .map(ref_add_forty_two, &reg)
329        .unwrap_or(0)
330        .then(ref_consume, &reg)
331        .build();
332    d.run(world, input);
333}
334
335// ═══════════════════════════════════════════════════════════════════
336// 15. DAG combinators (guard, filter, dedup, option, result, bool)
337// ═══════════════════════════════════════════════════════════════════
338
339#[inline(never)]
340pub fn dag_guard(world: &mut World, input: u64) {
341    let reg = world.registry();
342    let mut d = DagBuilder::<u64>::new()
343        .root(add_one, &reg)
344        .guard(|x: &u64| *x > 10, &reg)
345        .unwrap_or(0)
346        .then(ref_consume, &reg)
347        .build();
348    d.run(world, input);
349}
350
351#[inline(never)]
352pub fn dag_filter(world: &mut World, input: u64) {
353    let reg = world.registry();
354    let mut d = DagBuilder::<u64>::new()
355        .root(add_one, &reg)
356        .guard(|x: &u64| *x > 0, &reg)
357        .filter(|x: &u64| *x < 1000, &reg)
358        .unwrap_or(0)
359        .then(ref_consume, &reg)
360        .build();
361    d.run(world, input);
362}
363
364#[inline(never)]
365pub fn dag_dedup(world: &mut World, input: u64) {
366    let reg = world.registry();
367    let mut d = DagBuilder::<u64>::new()
368        .root(add_one, &reg)
369        .dedup()
370        .unwrap_or(0)
371        .then(ref_consume, &reg)
372        .build();
373    d.run(world, input);
374}
375
376#[inline(never)]
377pub fn dag_opt_map(world: &mut World, input: u64) {
378    let reg = world.registry();
379    let mut d = DagBuilder::<u64>::new()
380        .root(maybe_positive, &reg)
381        .map(ref_double, &reg)
382        .unwrap_or(0)
383        .then(ref_consume, &reg)
384        .build();
385    d.run(world, input);
386}
387
388#[inline(never)]
389pub fn dag_opt_and_then(world: &mut World, input: u64) {
390    let reg = world.registry();
391    let mut d = DagBuilder::<u64>::new()
392        .root(maybe_positive, &reg)
393        .and_then(ref_maybe_positive, &reg)
394        .unwrap_or(0)
395        .then(ref_consume, &reg)
396        .build();
397    d.run(world, input);
398}
399
400#[inline(never)]
401pub fn dag_opt_chain(world: &mut World, input: u64) {
402    let reg = world.registry();
403    let mut d = DagBuilder::<u64>::new()
404        .root(maybe_positive, &reg)
405        .map(ref_double, &reg)
406        .filter(|x: &u64| *x < 1000, &reg)
407        .inspect(|_x: &u64| {}, &reg)
408        .on_none(|| {}, &reg)
409        .unwrap_or_else(|| 0, &reg)
410        .then(ref_consume, &reg)
411        .build();
412    d.run(world, input);
413}
414
415#[inline(never)]
416pub fn dag_res_map(world: &mut World, input: u64) {
417    let reg = world.registry();
418    let mut d = DagBuilder::<u64>::new()
419        .root(try_parse, &reg)
420        .map(ref_double, &reg)
421        .unwrap_or(0)
422        .then(ref_consume, &reg)
423        .build();
424    d.run(world, input);
425}
426
427#[inline(never)]
428pub fn dag_res_and_then(world: &mut World, input: u64) {
429    let reg = world.registry();
430    let mut d = DagBuilder::<u64>::new()
431        .root(try_parse, &reg)
432        .and_then(ref_try_parse, &reg)
433        .unwrap_or(0)
434        .then(ref_consume, &reg)
435        .build();
436    d.run(world, input);
437}
438
439#[inline(never)]
440pub fn dag_res_chain(world: &mut World, input: u64) {
441    let reg = world.registry();
442    let mut d = DagBuilder::<u64>::new()
443        .root(try_parse, &reg)
444        .map(ref_double, &reg)
445        .and_then(ref_try_parse, &reg)
446        .inspect(|_v: &u64| {}, &reg)
447        .inspect_err(|_e: &u32| {}, &reg)
448        .map_err(|e: u32| e as u64, &reg)
449        .unwrap_or(0)
450        .then(ref_consume, &reg)
451        .build();
452    d.run(world, input);
453}
454
455#[inline(never)]
456pub fn dag_res_catch(world: &mut World, input: u64) {
457    let reg = world.registry();
458
459    fn log_error(_err: &u32) {}
460
461    let mut d = DagBuilder::<u64>::new()
462        .root(try_parse, &reg)
463        .catch(log_error, &reg)
464        .unwrap_or(0)
465        .then(ref_consume, &reg)
466        .build();
467    d.run(world, input);
468}
469
470#[inline(never)]
471pub fn dag_res_or_else(world: &mut World, input: u64) {
472    let reg = world.registry();
473    let mut d = DagBuilder::<u64>::new()
474        .root(try_parse, &reg)
475        .or_else(|e: u32| Ok::<u64, u32>(e as u64), &reg)
476        .unwrap_or(0)
477        .then(ref_consume, &reg)
478        .build();
479    d.run(world, input);
480}
481
482#[inline(never)]
483pub fn dag_bool_chain(world: &mut World, input: u64) {
484    let reg = world.registry();
485    let mut d = DagBuilder::<u64>::new()
486        .root(is_even, &reg)
487        .and(|| true, &reg)
488        .or(|| false, &reg)
489        .not()
490        .xor(|| true, &reg)
491        .then(|b: &bool| -> u64 { if *b { 1 } else { 0 } }, &reg)
492        .then(ref_consume, &reg)
493        .build();
494    d.run(world, input);
495}
496
497// ═══════════════════════════════════════════════════════════════════
498// 16. DAG route & switch
499// ═══════════════════════════════════════════════════════════════════
500
501#[inline(never)]
502pub fn dag_route_basic(world: &mut World, input: u64) {
503    let reg = world.registry();
504
505    let on_true = DagArmSeed::<u64>::new().then(ref_double, &reg);
506    let on_false = DagArmSeed::<u64>::new().then(ref_add_one, &reg);
507
508    let mut d = DagBuilder::<u64>::new()
509        .root(add_one, &reg)
510        .route(|x: &u64| *x > 100, &reg, on_true, on_false)
511        .then(ref_consume, &reg)
512        .build();
513    d.run(world, input);
514}
515
516#[inline(never)]
517pub fn dag_route_heavy_arms(world: &mut World, input: u64) {
518    let reg = world.registry();
519
520    let arm_t = DagArmSeed::<u64>::new()
521        .then(ref_double, &reg)
522        .then(ref_add_three, &reg)
523        .then(ref_square, &reg)
524        .then(ref_sub_ten, &reg)
525        .then(ref_shr_one, &reg);
526
527    let arm_f = DagArmSeed::<u64>::new()
528        .then(ref_add_one, &reg)
529        .then(ref_triple, &reg)
530        .then(ref_xor_mask, &reg)
531        .then(ref_add_seven, &reg)
532        .then(ref_add_forty_two, &reg);
533
534    let mut d = DagBuilder::<u64>::new()
535        .root(add_one, &reg)
536        .route(|x: &u64| *x > 100, &reg, arm_t, arm_f)
537        .then(ref_consume, &reg)
538        .build();
539    d.run(world, input);
540}
541
542#[inline(never)]
543pub fn dag_switch_basic(world: &mut World, input: u64) {
544    let reg = world.registry();
545    let mut d = DagBuilder::<u64>::new()
546        .root(add_one, &reg)
547        .then(
548            |x: &u64| {
549                if *x > 100 {
550                    x.wrapping_mul(2)
551                } else {
552                    x.wrapping_add(1)
553                }
554            },
555            &reg,
556        )
557        .then(ref_consume, &reg)
558        .build();
559    d.run(world, input);
560}
561
562#[inline(never)]
563pub fn dag_switch_3way(world: &mut World, input: u64) {
564    let reg = world.registry();
565    let mut d = DagBuilder::<u64>::new()
566        .root(add_one, &reg)
567        .then(
568            |x: &u64| match x % 3 {
569                0 => x.wrapping_mul(2),
570                1 => x.wrapping_add(10),
571                _ => x.wrapping_sub(5),
572            },
573            &reg,
574        )
575        .then(ref_consume, &reg)
576        .build();
577    d.run(world, input);
578}
579
580#[inline(never)]
581pub fn dag_switch_resolve_arm(world: &mut World, input: u64) {
582    let reg = world.registry();
583    let mut arm_big = resolve_arm(ref_double, &reg);
584    let mut arm_small = resolve_arm(ref_add_one, &reg);
585
586    let mut d = DagBuilder::<u64>::new()
587        .root(add_one, &reg)
588        .then(
589            move |world: &mut World, x: &u64| {
590                if *x > 100 {
591                    arm_big(world, x)
592                } else {
593                    arm_small(world, x)
594                }
595            },
596            &reg,
597        )
598        .then(ref_consume, &reg)
599        .build();
600    d.run(world, input);
601}
602
603// ═══════════════════════════════════════════════════════════════════
604// 17. DAG splat
605// ═══════════════════════════════════════════════════════════════════
606
607#[inline(never)]
608pub fn dag_splat2(world: &mut World, input: u64) {
609    let reg = world.registry();
610    let mut d = DagBuilder::<u64>::new()
611        .root(split_u64, &reg)
612        .splat()
613        .then(ref_splat_add, &reg)
614        .then(ref_consume, &reg)
615        .build();
616    d.run(world, input);
617}
618
619#[inline(never)]
620pub fn dag_splat3(world: &mut World, input: u64) {
621    let reg = world.registry();
622    let mut d = DagBuilder::<u64>::new()
623        .root(split_3, &reg)
624        .splat()
625        .then(ref_splat_3, &reg)
626        .then(ref_consume, &reg)
627        .build();
628    d.run(world, input);
629}
630
631#[inline(never)]
632pub fn dag_splat_in_arm(world: &mut World, input: u64) {
633    let reg = world.registry();
634    let mut d = DagBuilder::<u64>::new()
635        .root(add_one, &reg)
636        .fork()
637        .arm(|a| {
638            a.then(ref_split_u64, &reg)
639                .splat()
640                .then(ref_splat_add, &reg)
641        })
642        .arm(|a| a.then(ref_double, &reg))
643        .merge(merge_add, &reg)
644        .then(ref_consume, &reg)
645        .build();
646    d.run(world, input);
647}
648
649// ═══════════════════════════════════════════════════════════════════
650// 18. DAG tap, tee, dispatch
651// ═══════════════════════════════════════════════════════════════════
652
653#[inline(never)]
654pub fn dag_tap(world: &mut World, input: u64) {
655    let reg = world.registry();
656    let mut d = DagBuilder::<u64>::new()
657        .root(add_one, &reg)
658        .tap(|_x: &u64| {}, &reg)
659        .then(ref_double, &reg)
660        .then(ref_consume, &reg)
661        .build();
662    d.run(world, input);
663}
664
665#[inline(never)]
666pub fn dag_tee(world: &mut World, input: u64) {
667    let reg = world.registry();
668
669    let side = DagArmSeed::<u64>::new().then(ref_consume, &reg);
670
671    let mut d = DagBuilder::<u64>::new()
672        .root(add_one, &reg)
673        .tee(side)
674        .then(ref_double, &reg)
675        .then(ref_consume, &reg)
676        .build();
677    d.run(world, input);
678}
679
680#[inline(never)]
681pub fn dag_tee_heavy(world: &mut World, input: u64) {
682    let reg = world.registry();
683
684    let side = DagArmSeed::<u64>::new()
685        .then(ref_add_one, &reg)
686        .then(ref_double, &reg)
687        .then(ref_add_three, &reg)
688        .then(ref_square, &reg)
689        .then(ref_consume, &reg);
690
691    let mut d = DagBuilder::<u64>::new()
692        .root(add_one, &reg)
693        .tee(side)
694        .then(ref_double, &reg)
695        .then(ref_consume, &reg)
696        .build();
697    d.run(world, input);
698}
699
700#[inline(never)]
701pub fn dag_dispatch(world: &mut World, input: u64) {
702    let reg = world.registry();
703    let handler = consume_val.into_handler(&reg);
704    let mut d = DagBuilder::<u64>::new()
705        .root(add_one, &reg)
706        .dispatch(handler)
707        .build();
708    d.run(world, input);
709}
710
711// ═══════════════════════════════════════════════════════════════════
712// 19. DAG world interaction
713// ═══════════════════════════════════════════════════════════════════
714
715#[inline(never)]
716pub fn dag_world_res(world: &mut World, input: u64) {
717    let reg = world.registry();
718    let mut d = DagBuilder::<u64>::new()
719        .root(add_res_a, &reg)
720        .then(ref_consume, &reg)
721        .build();
722    d.run(world, input);
723}
724
725#[inline(never)]
726pub fn dag_world_res_mut(world: &mut World, input: u64) {
727    let reg = world.registry();
728    let mut d = DagBuilder::<u64>::new()
729        .root(write_res_a, &reg)
730        .then(ref_consume, &reg)
731        .build();
732    d.run(world, input);
733}
734
735#[inline(never)]
736pub fn dag_world_mixed_chain(world: &mut World, input: u64) {
737    let reg = world.registry();
738    let mut d = DagBuilder::<u64>::new()
739        .root(add_one, &reg)
740        .then(ref_add_res_a, &reg)
741        .then(ref_write_res_a, &reg)
742        .then(ref_double, &reg)
743        .then(ref_add_both, &reg)
744        .then(ref_consume, &reg)
745        .build();
746    d.run(world, input);
747}
748
749#[inline(never)]
750pub fn dag_world_3_params(world: &mut World, input: u64) {
751    let reg = world.registry();
752    let mut d = DagBuilder::<u64>::new()
753        .root(three_params, &reg)
754        .then(ref_consume, &reg)
755        .build();
756    d.run(world, input);
757}
758
759// ═══════════════════════════════════════════════════════════════════
760// 20. DAG complex topologies
761// ═══════════════════════════════════════════════════════════════════
762
763#[inline(never)]
764pub fn dag_wide_fan_out(world: &mut World, input: u64) {
765    let reg = world.registry();
766    // 4-way fan-out, all sinks
767    let mut d = DagBuilder::<u64>::new()
768        .root(add_one, &reg)
769        .fork()
770        .arm(|a| a.then(ref_consume, &reg))
771        .arm(|a| a.then(ref_consume, &reg))
772        .arm(|a| a.then(ref_consume, &reg))
773        .arm(|a| a.then(ref_consume, &reg))
774        .join()
775        .build();
776    d.run(world, input);
777}
778
779#[inline(never)]
780pub fn dag_sequential_forks(world: &mut World, input: u64) {
781    let reg = world.registry();
782    // Three sequential fork-merges
783    let mut d = DagBuilder::<u64>::new()
784        .root(add_one, &reg)
785        .fork()
786        .arm(|a| a.then(ref_double, &reg))
787        .arm(|a| a.then(ref_triple, &reg))
788        .merge(merge_add, &reg)
789        .fork()
790        .arm(|a| a.then(ref_square, &reg))
791        .arm(|a| a.then(ref_shr_one, &reg))
792        .merge(merge_mul, &reg)
793        .fork()
794        .arm(|a| a.then(ref_add_one, &reg))
795        .arm(|a| a.then(ref_xor_mask, &reg))
796        .merge(merge_add, &reg)
797        .then(ref_consume, &reg)
798        .build();
799    d.run(world, input);
800}
801
802#[inline(never)]
803pub fn dag_fork_with_guard(world: &mut World, input: u64) {
804    let reg = world.registry();
805    let mut d = DagBuilder::<u64>::new()
806        .root(add_one, &reg)
807        .guard(|x: &u64| *x > 10, &reg)
808        .unwrap_or(0)
809        .fork()
810        .arm(|a| a.then(ref_double, &reg))
811        .arm(|a| a.then(ref_triple, &reg))
812        .merge(merge_add, &reg)
813        .then(ref_consume, &reg)
814        .build();
815    d.run(world, input);
816}
817
818#[inline(never)]
819pub fn dag_fork_with_route(world: &mut World, input: u64) {
820    let reg = world.registry();
821
822    let on_true = DagArmSeed::<u64>::new().then(ref_double, &reg);
823    let on_false = DagArmSeed::<u64>::new().then(ref_triple, &reg);
824
825    let mut d = DagBuilder::<u64>::new()
826        .root(add_one, &reg)
827        .route(|x: &u64| *x > 100, &reg, on_true, on_false)
828        .fork()
829        .arm(|a| a.then(ref_square, &reg))
830        .arm(|a| a.then(ref_shr_one, &reg))
831        .merge(merge_add, &reg)
832        .then(ref_consume, &reg)
833        .build();
834    d.run(world, input);
835}
836
837#[inline(never)]
838pub fn dag_full_kitchen_sink(world: &mut World, input: u64) {
839    let reg = world.registry();
840
841    fn log_error(_err: &u32) {}
842
843    let tee_side = DagArmSeed::<u64>::new().then(ref_consume, &reg);
844
845    let route_true = DagArmSeed::<u64>::new().then(ref_double, &reg);
846    let route_false = DagArmSeed::<u64>::new().then(ref_triple, &reg);
847
848    let mut d = DagBuilder::<u64>::new()
849        .root(add_one, &reg)
850        .tap(|_x: &u64| {}, &reg)
851        .then(ref_add_res_a, &reg)
852        .guard(|x: &u64| *x > 0, &reg)
853        .map(ref_double, &reg)
854        .unwrap_or(0)
855        .tee(tee_side)
856        .then(ref_try_parse, &reg)
857        .map(ref_add_one, &reg)
858        .catch(log_error, &reg)
859        .unwrap_or(0)
860        .route(|x: &u64| *x > 100, &reg, route_true, route_false)
861        .fork()
862        .arm(|a| a.then(ref_square, &reg))
863        .arm(|a| a.then(ref_shr_one, &reg))
864        .merge(merge_add, &reg)
865        .dedup()
866        .unwrap_or(0)
867        .then(ref_consume, &reg)
868        .build();
869    d.run(world, input);
870}
871
872// ═══════════════════════════════════════════════════════════════════
873// Remaining gaps
874// ═══════════════════════════════════════════════════════════════════
875
876// ---- 13.2 ----
877
878#[inline(never)]
879pub fn dag_linear_2(world: &mut World, input: u64) {
880    let reg = world.registry();
881    let mut d = DagBuilder::<u64>::new()
882        .root(add_one, &reg)
883        .then(ref_double, &reg)
884        .then(ref_consume, &reg)
885        .build();
886    d.run(world, input);
887}
888
889// ---- 14.7: deep nested fork (3 levels) ----
890
891#[inline(never)]
892pub fn dag_deep_nested_fork(world: &mut World, input: u64) {
893    let reg = world.registry();
894    let mut d = DagBuilder::<u64>::new()
895        .root(add_one, &reg)
896        .fork()
897        .arm(|a| {
898            a.then(ref_double, &reg)
899                .fork()
900                .arm(|b| {
901                    b.then(ref_add_one, &reg)
902                        .fork()
903                        .arm(|c| c.then(ref_triple, &reg))
904                        .arm(|c| c.then(ref_add_seven, &reg))
905                        .merge(merge_add, &reg)
906                })
907                .arm(|b| b.then(ref_square, &reg))
908                .merge(merge_add, &reg)
909        })
910        .arm(|a| a.then(ref_xor_mask, &reg))
911        .merge(merge_add, &reg)
912        .then(ref_consume, &reg)
913        .build();
914    d.run(world, input);
915}
916
917// ---- 14.8: fork → merge → then → then (post-merge continuation) ----
918
919#[inline(never)]
920pub fn dag_fork_then_chain(world: &mut World, input: u64) {
921    let reg = world.registry();
922    let mut d = DagBuilder::<u64>::new()
923        .root(add_one, &reg)
924        .fork()
925        .arm(|a| a.then(ref_double, &reg))
926        .arm(|a| a.then(ref_triple, &reg))
927        .merge(merge_add, &reg)
928        .then(ref_add_three, &reg)
929        .then(ref_square, &reg)
930        .then(ref_consume, &reg)
931        .build();
932    d.run(world, input);
933}
934
935// ---- 14.10: asymmetric arms (1, 3, 5 steps) ----
936
937#[inline(never)]
938pub fn dag_asymmetric_arms(world: &mut World, input: u64) {
939    let reg = world.registry();
940    let mut d = DagBuilder::<u64>::new()
941        .root(add_one, &reg)
942        .fork()
943        .arm(|a| a.then(ref_double, &reg))
944        .arm(|a| {
945            a.then(ref_triple, &reg)
946                .then(ref_add_three, &reg)
947                .then(ref_square, &reg)
948        })
949        .arm(|a| {
950            a.then(ref_add_one, &reg)
951                .then(ref_shr_one, &reg)
952                .then(ref_xor_mask, &reg)
953                .then(ref_add_seven, &reg)
954                .then(ref_add_forty_two, &reg)
955        })
956        .merge(merge_3, &reg)
957        .then(ref_consume, &reg)
958        .build();
959    d.run(world, input);
960}
961
962// ---- 14.11: fork arms with combinators ----
963
964#[inline(never)]
965pub fn dag_fork_arm_combinators(world: &mut World, input: u64) {
966    let reg = world.registry();
967    let mut d = DagBuilder::<u64>::new()
968        .root(add_one, &reg)
969        .fork()
970        .arm(|a| {
971            a.then(ref_add_one, &reg)
972                .guard(|x: &u64| *x > 10, &reg)
973                .map(ref_double, &reg)
974                .unwrap_or(0)
975        })
976        .arm(|a| {
977            a.then(ref_triple, &reg)
978                .guard(|x: &u64| *x > 5, &reg)
979                .filter(|x: &u64| *x < 500, &reg)
980                .unwrap_or_else(|| 0, &reg)
981        })
982        .arm(|a| a.then(ref_add_seven, &reg))
983        .merge(merge_3, &reg)
984        .then(ref_consume, &reg)
985        .build();
986    d.run(world, input);
987}
988
989// ---- 15.2: filter inside a fork arm ----
990
991#[inline(never)]
992pub fn dag_filter_in_arm(world: &mut World, input: u64) {
993    let reg = world.registry();
994    let mut d = DagBuilder::<u64>::new()
995        .root(add_one, &reg)
996        .fork()
997        .arm(|a| {
998            a.then(ref_add_one, &reg)
999                .guard(|x: &u64| *x > 10, &reg)
1000                .filter(|x: &u64| *x < 1000, &reg)
1001                .unwrap_or(0)
1002        })
1003        .arm(|a| a.then(ref_double, &reg))
1004        .merge(merge_add, &reg)
1005        .then(ref_consume, &reg)
1006        .build();
1007    d.run(world, input);
1008}
1009
1010// ---- 16.7: transition guard → ok_or → catch → unwrap ----
1011
1012#[inline(never)]
1013pub fn dag_transition_guard_ok_or(world: &mut World, input: u64) {
1014    let reg = world.registry();
1015
1016    fn log_error(_err: &u32) {}
1017
1018    let mut d = DagBuilder::<u64>::new()
1019        .root(add_one, &reg)
1020        .guard(|x: &u64| *x > 0, &reg)
1021        .ok_or(0u32)
1022        .catch(log_error, &reg)
1023        .unwrap_or(0)
1024        .then(ref_consume, &reg)
1025        .build();
1026    d.run(world, input);
1027}
1028
1029// ---- 17.2: route inside a fork arm ----
1030
1031#[inline(never)]
1032pub fn dag_route_in_arm(world: &mut World, input: u64) {
1033    let reg = world.registry();
1034
1035    let on_true = DagArmSeed::<u64>::new().then(ref_double, &reg);
1036    let on_false = DagArmSeed::<u64>::new().then(ref_triple, &reg);
1037
1038    let mut d = DagBuilder::<u64>::new()
1039        .root(add_one, &reg)
1040        .fork()
1041        .arm(|a| {
1042            a.then(ref_add_one, &reg)
1043                .route(|x: &u64| *x > 50, &reg, on_true, on_false)
1044        })
1045        .arm(|a| a.then(ref_add_seven, &reg))
1046        .merge(merge_add, &reg)
1047        .then(ref_consume, &reg)
1048        .build();
1049    d.run(world, input);
1050}
1051
1052// ---- 17.3: nested route on DAG chain (3-way via resolve_arm) ----
1053
1054#[inline(never)]
1055pub fn dag_route_nested(world: &mut World, input: u64) {
1056    let reg = world.registry();
1057
1058    let mut big = resolve_arm(ref_double, &reg);
1059    let mut mid = resolve_arm(ref_triple, &reg);
1060    let mut small = resolve_arm(ref_add_one, &reg);
1061
1062    // 3-way branch via nested switch (same as pipe_route_nested_2 strategy)
1063    let mut d = DagBuilder::<u64>::new()
1064        .root(add_one, &reg)
1065        .then(
1066            move |world: &mut World, x: &u64| {
1067                if *x > 100 {
1068                    big(world, x)
1069                } else if *x > 50 {
1070                    mid(world, x)
1071                } else {
1072                    small(world, x)
1073                }
1074            },
1075            &reg,
1076        )
1077        .then(ref_consume, &reg)
1078        .build();
1079    d.run(world, input);
1080}
1081
1082// ---- 18.5: 5-element splat on DAG chain ----
1083
1084#[inline(never)]
1085pub fn dag_splat5(world: &mut World, input: u64) {
1086    let reg = world.registry();
1087    let mut d = DagBuilder::<u64>::new()
1088        .root(split_5, &reg)
1089        .splat()
1090        .then(ref_splat_5, &reg)
1091        .then(ref_consume, &reg)
1092        .build();
1093    d.run(world, input);
1094}
1095
1096// ---- 19.4: dispatch with fan_out ----
1097
1098#[inline(never)]
1099pub fn dag_dispatch_fanout(world: &mut World, input: u64) {
1100    let reg = world.registry();
1101
1102    fn sink_a(mut a: ResMut<ResA>, x: &u64) {
1103        a.0 = a.0.wrapping_add(*x);
1104    }
1105    fn sink_b(mut a: ResMut<ResB>, x: &u64) {
1106        a.0 = a.0.wrapping_add(*x as u32);
1107    }
1108
1109    let h1 = sink_a.into_handler(&reg);
1110    let h2 = sink_b.into_handler(&reg);
1111
1112    let mut d = DagBuilder::<u64>::new()
1113        .root(add_one, &reg)
1114        .then(ref_double, &reg)
1115        .dispatch(fan_out!(h1, h2))
1116        .build();
1117    d.run(world, input);
1118}
1119
1120// ---- 20.1-20.3: DAG clone transitions ----
1121// DAG .cloned() requires the chain output to be a reference type.
1122// Root steps must return &T for cloned() to apply.
1123
1124fn leak_u64(x: u64) -> &'static u64 {
1125    Box::leak(Box::new(x.wrapping_add(1)))
1126}
1127fn maybe_leak(x: u64) -> Option<&'static u64> {
1128    if x > 0 {
1129        Some(Box::leak(Box::new(x)))
1130    } else {
1131        None
1132    }
1133}
1134fn try_leak(x: u64) -> Result<&'static u64, u32> {
1135    if x < 10_000 {
1136        Ok(Box::leak(Box::new(x)))
1137    } else {
1138        Err(x as u32)
1139    }
1140}
1141
1142#[inline(never)]
1143pub fn dag_cloned_bare(world: &mut World, input: u64) {
1144    let reg = world.registry();
1145    // Root returns &'static u64, .cloned() converts to u64
1146    let mut d = DagBuilder::<u64>::new()
1147        .root(leak_u64, &reg)
1148        .cloned()
1149        .then(ref_consume, &reg)
1150        .build();
1151    d.run(world, input);
1152}
1153
1154#[inline(never)]
1155pub fn dag_cloned_option(world: &mut World, input: u64) {
1156    let reg = world.registry();
1157    // Root returns Option<&'static u64>, .cloned() → Option<u64>
1158    let mut d = DagBuilder::<u64>::new()
1159        .root(maybe_leak, &reg)
1160        .cloned()
1161        .unwrap_or(0)
1162        .then(ref_consume, &reg)
1163        .build();
1164    d.run(world, input);
1165}
1166
1167#[inline(never)]
1168pub fn dag_cloned_result(world: &mut World, input: u64) {
1169    let reg = world.registry();
1170    // Root returns Result<&'static u64, u32>, .cloned() → Result<u64, u32>
1171    let mut d = DagBuilder::<u64>::new()
1172        .root(try_leak, &reg)
1173        .cloned()
1174        .unwrap_or(0)
1175        .then(ref_consume, &reg)
1176        .build();
1177    d.run(world, input);
1178}