1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// Copyright 2024-2026 Jonathan Shook
// SPDX-License-Identifier: Apache-2.0
//! Scope-iteration driver — the GK-side primitive both the
//! runtime executor and the pre-map walker consume.
//!
//! ## What this owns
//!
//! Given a comprehension scope's canonical and parent kernels
//! plus the clause list, [`iterate_scope`] enumerates the
//! dependent-tuple space, applies any `order:` permutation, and
//! yields a stream of [`IterationStep`]s. Each step is a fully-
//! prepared iteration position: the typed bindings, a per-
//! iteration kernel constructed via
//! [`GkKernel::for_iteration`], and the root-first scope-
//! coordinate path including this iteration.
//!
//! ## Why this lives here
//!
//! Pre-map (scene-tree builder) and runtime (phase dispatcher)
//! both walk the same scenario tree in the same DFS order. The
//! historical pattern was each path running its own
//! `TupleComprehension` + per-iteration kernel construction
//! loop, with the two implementations drifting (different empty-
//! tuple handling, different label-string formatting,
//! optimize_for vs. optimize_for_values cascade quirks). Putting
//! the iteration engine here — alongside the kernel, the program,
//! the scope-coordinate model — makes the GK side the single
//! source of truth for "what does one iteration of this
//! comprehension look like?". Consumers only decide what to *do*
//! with each step.
//!
//! ## Streaming, not Vec
//!
//! [`ScopeIterations`] implements [`Iterator`]. The underlying
//! tuple list is enumerated eagerly by [`enumerate_tuples`] (the
//! dependent-tuple walk needs all earlier branches resolved
//! before later clauses can evaluate), but kernel construction
//! and coord-path extension happen lazily per `next()`. Runtime
//! consumers that spawn concurrent `JoinSet` tasks per step keep
//! their existing shape — just `.collect()` to materialize, then
//! distribute. Pre-map consumes serially.
use Arc;
use crate;
use crateValue;
use TraversalOrder;
use enumerate_tuples;
use apply_order;
/// One iteration position of a comprehension scope, ready for
/// downstream consumption.
///
/// All three fields are derived from the same source data
/// (a typed tuple drained out of the dependent-tuple walk),
/// so the runtime and pre-map walkers see identical content
/// for identical iteration positions.
/// Streaming iterator over a scope's prepared iteration steps.
///
/// Construct via [`iterate_scope`]; consume via the standard
/// [`Iterator`] surface. `collect()` to materialise for
/// concurrent fan-out (`tokio::JoinSet`); iterate directly for
/// serial / pre-map walks.
/// Per-iteration kernel constructor — closes over whatever
/// context the caller needs (typically the per-iteration
/// synthesizer's parent_manifest / workload_params / lib
/// paths / etc.). When `None`, falls back to the legacy
/// `GkKernel::for_iteration` path that reuses the
/// canonical's compiled program and sets iter-var values
/// via `set_input`.
///
/// SRD-13f Gate 2: the activity layer wires the per-fiber
/// closure to call [`super::synthesize_for_each_iteration`],
/// which emits source with `final <var> := <literal>` for
/// each iter-var so the matter-AST classification matches
/// the design ("named coordinates *are* inner scope matter
/// as const and final values").
pub type IterationKernelFn =
;
/// Build a [`ScopeIterations`] driver for one comprehension
/// scope.
///
/// Mirrors [`enumerate_tuples`]'s argument list (canonical /
/// parent kernels, clause list, optional filter, empty-clause
/// callback) and adds:
///
/// - `parent_coords` — root-first scope-coordinate chain of the
/// enclosing iteration. Each yielded [`IterationStep`]'s
/// `coord_path` is `parent_coords ++ [own]`.
/// - `order` — optional [`TraversalOrder`] permutation applied
/// to the dependent-tuple list before iteration begins.
/// - `clause_sizes` — per-clause cardinality hints used by some
/// `order:` permutations (e.g. interleaved). Pass `&[]` to
/// skip.
///
/// Empty-clause policy is delegated to the caller (same shape
/// as [`enumerate_tuples`]) so the activity layer's
/// strict-vs-warn lifting stays out of GK.