1#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3pub enum DataflowFailure {
4 Transfer,
6 Join,
8}
9#[derive(Clone, Debug, Eq, Hash, PartialEq)]
11pub enum DataflowEvent<N, E, C> {
12 Visit(N),
14 Propagate {
16 edge: E,
18 class: EdgeClass<C>,
20 },
21}
22
23#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
25pub struct DataflowUsage {
26 pub work: usize,
28 pub observations: usize,
30 pub depth: usize,
32 pub output: usize,
34}
35
36#[derive(Clone, Debug, Eq, PartialEq)]
38pub enum DataflowError<N, E, L> {
39 UnknownSeed(N),
41 ContinuationMismatch {
43 changed: ContinuationFingerprint,
45 expected: ValueFingerprint,
47 actual: ValueFingerprint,
49 },
50 BudgetExceeded {
52 kind: BudgetKind,
54 limit: usize,
56 attempted: usize,
58 node: Option<N>,
60 edge: Option<E>,
62 location: L,
64 target_location: Option<L>,
66 },
67 NodeFailure {
69 failure: DataflowFailure,
71 node: N,
73 location: L,
75 },
76 EdgeFailure {
78 failure: DataflowFailure,
80 edge: E,
82 location: L,
84 target_location: L,
86 },
87}
88
89#[derive(Clone, Copy, Debug, Eq, PartialEq)]
91pub enum ContinuationFingerprint {
92 Graph,
94 Policy,
96 Dependencies,
98}
99
100#[derive(Clone, Debug, Eq, Hash, PartialEq)]
102pub struct CausalPredecessor<N, E> {
103 pub node: N,
105 pub edge: Option<E>,
107}
108
109#[derive(Clone, Debug, Eq, PartialEq)]
111pub struct DataflowExplanation<N, E> {
112 predecessors: Box<[CausalPredecessor<N, E>]>,
113 omitted: usize,
114}
115
116#[derive(Clone, Debug, Eq, Hash, PartialEq)]
117struct CausalRecord<N, E> {
118 retained: Vec<CausalPredecessor<N, E>>,
119 omitted: usize,
120}
121
122impl<N, E> DataflowExplanation<N, E> {
123 pub fn predecessors(&self) -> &[CausalPredecessor<N, E>] {
125 &self.predecessors
126 }
127
128 pub const fn truncated(&self) -> bool {
130 self.omitted != 0
131 }
132
133 pub const fn omitted(&self) -> usize {
135 self.omitted
136 }
137}
138
139#[derive(Clone, Debug, Eq, PartialEq)]
141pub struct DataflowContinuation<N, E, C, S> {
142 token: ContinuationToken,
143 graph: ValueFingerprint,
144 policy: ValueFingerprint,
145 dependencies: ValueFingerprint,
146 states: BTreeMap<N, S>,
147 pending: BTreeSet<N>,
148 events: Vec<DataflowEvent<N, E, C>>,
149 causes: BTreeMap<N, CausalRecord<N, E>>,
150 cause_limit: usize,
151 usage: DataflowUsage,
152}
153
154impl<N, E, C, S> DataflowContinuation<N, E, C, S> {
155 pub const fn token(&self) -> ContinuationToken {
157 self.token
158 }
159
160 pub const fn graph_fingerprint(&self) -> ValueFingerprint {
162 self.graph
163 }
164}
165
166#[derive(Clone, Debug, Eq, PartialEq)]
168pub enum DataflowProgress<N, E, C, S> {
169 Complete(DataflowSolution<N, E, C, S>),
171 Suspended(DataflowContinuation<N, E, C, S>),
173}
174
175pub type DataflowProgressResult<N, E, L, C, S> =
177 Result<DataflowProgress<N, E, C, S>, DataflowError<N, E, L>>;
178
179#[derive(Clone, Copy)]
180struct ContinuationIdentity {
181 graph: ValueFingerprint,
182 policy: ValueFingerprint,
183 dependencies: ValueFingerprint,
184}
185
186pub type DataflowResult<N, E, L, C, S> =
188 Result<DataflowSolution<N, E, C, S>, DataflowError<N, E, L>>;
189
190pub type CompletionProofResult<N, E, L, C, S> =
192 Result<DataflowCompletionProof<N, E, C, S>, DataflowError<N, E, L>>;
193
194struct ChargeLocation<N, E, L> {
195 node: Option<N>,
196 edge: Option<E>,
197 location: L,
198 target_location: Option<L>,
199}
200
201#[derive(Clone, Debug, Eq, PartialEq)]
203pub struct DataflowSolution<N, E, C, S> {
204 states: BTreeMap<N, S>,
205 events: Vec<DataflowEvent<N, E, C>>,
206 usage: DataflowUsage,
207 causes: BTreeMap<N, CausalRecord<N, E>>,
208}
209
210pub const DATAFLOW_PROOF_SCHEMA_REVISION: u64 = 1;
212
213#[derive(Clone, Debug, Eq, PartialEq)]
219pub struct DataflowCompletionProof<N, E, C, S> {
220 identity: ValueFingerprint,
221 graph: ValueFingerprint,
222 lattice: ValueFingerprint,
223 policy: ValueFingerprint,
224 boundaries: ValueFingerprint,
225 limits: ValueFingerprint,
226 dependencies: ValueFingerprint,
227 seed_fingerprints: BTreeMap<N, ValueFingerprint>,
228 observations: Box<[(N, E, N)]>,
229 node_fingerprints: BTreeMap<N, ValueFingerprint>,
230 solution: DataflowSolution<N, E, C, S>,
231}
232
233impl<N: Ord, E, C, S> DataflowCompletionProof<N, E, C, S> {
234 pub const fn identity(&self) -> ValueFingerprint {
236 self.identity
237 }
238
239 pub fn observations(&self) -> &[(N, E, N)] {
241 &self.observations
242 }
243
244 pub fn node_fingerprints(&self) -> &BTreeMap<N, ValueFingerprint> {
246 &self.node_fingerprints
247 }
248
249 pub const fn solution(&self) -> &DataflowSolution<N, E, C, S> {
251 &self.solution
252 }
253}
254
255#[derive(Clone, Copy, Debug, Eq, PartialEq)]
257pub enum CompletionProofMismatch {
258 Graph,
260 Lattice,
262 Policy,
264 Limits,
266 Dependencies,
268}
269
270impl<N: Ord, E, C, S> DataflowSolution<N, E, C, S> {
271 pub fn state(&self, node: &N) -> Option<&S> {
273 self.states.get(node)
274 }
275 pub fn states(&self) -> impl ExactSizeIterator<Item = (&N, &S)> {
277 self.states.iter()
278 }
279 pub fn events(&self) -> &[DataflowEvent<N, E, C>] {
281 &self.events
282 }
283 pub const fn usage(&self) -> DataflowUsage {
285 self.usage
286 }
287
288 pub fn explain(&self, node: &N, limit: usize) -> Option<DataflowExplanation<N, E>>
290 where
291 N: Clone,
292 E: Clone,
293 {
294 let causes = self.causes.get(node)?;
295 let retained = causes
296 .retained
297 .iter()
298 .take(limit)
299 .cloned()
300 .collect::<Vec<_>>();
301 Some(DataflowExplanation {
302 omitted: causes
303 .omitted
304 .saturating_add(causes.retained.len().saturating_sub(retained.len())),
305 predecessors: retained.into_boxed_slice(),
306 })
307 }
308}
309
310#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
312pub struct FixpointEngine;