cvx_query/types.rs
1//! Query type definitions.
2
3use cvx_core::types::{ChangePoint, TemporalFilter, TemporalPoint};
4use serde::{Deserialize, Serialize};
5
6/// A temporal query request.
7#[derive(Debug, Clone, Serialize, Deserialize)]
8#[serde(tag = "type", rename_all = "snake_case")]
9pub enum TemporalQuery {
10 /// k-nearest neighbors at a specific timestamp.
11 SnapshotKnn {
12 /// Query vector.
13 vector: Vec<f32>,
14 /// Exact timestamp.
15 timestamp: i64,
16 /// Number of results.
17 k: usize,
18 },
19 /// k-nearest neighbors over a time range.
20 RangeKnn {
21 /// Query vector.
22 vector: Vec<f32>,
23 /// Start timestamp (inclusive).
24 start: i64,
25 /// End timestamp (inclusive).
26 end: i64,
27 /// Number of results.
28 k: usize,
29 /// Semantic vs temporal weight.
30 alpha: f32,
31 },
32 /// Full trajectory for an entity.
33 Trajectory {
34 /// Entity identifier.
35 entity_id: u64,
36 /// Temporal filter.
37 filter: TemporalFilter,
38 },
39 /// Velocity at a given timestamp.
40 Velocity {
41 /// Entity identifier.
42 entity_id: u64,
43 /// Timestamp to compute velocity at.
44 timestamp: i64,
45 },
46 /// Predict future vector state.
47 Prediction {
48 /// Entity identifier.
49 entity_id: u64,
50 /// Target timestamp for prediction.
51 target_timestamp: i64,
52 },
53 /// Detect change points in a time window.
54 ChangePointDetect {
55 /// Entity identifier.
56 entity_id: u64,
57 /// Start timestamp.
58 start: i64,
59 /// End timestamp.
60 end: i64,
61 },
62 /// Drift magnitude between two timestamps.
63 DriftQuant {
64 /// Entity identifier.
65 entity_id: u64,
66 /// Start timestamp.
67 t1: i64,
68 /// End timestamp.
69 t2: i64,
70 /// Number of top dimensions to report.
71 top_n: usize,
72 },
73 /// Temporal analogy: "entity A at t1 is to A at t2 as B at t3 is to ?"
74 Analogy {
75 /// Source entity.
76 entity_a: u64,
77 /// Source timestamp 1.
78 t1: i64,
79 /// Source timestamp 2.
80 t2: i64,
81 /// Target entity.
82 entity_b: u64,
83 /// Target timestamp.
84 t3: i64,
85 },
86 /// Counterfactual trajectory analysis.
87 Counterfactual {
88 /// Entity identifier.
89 entity_id: u64,
90 /// Change point timestamp.
91 change_point: i64,
92 },
93 /// Granger causality test between two entities.
94 GrangerCausality {
95 /// First entity (potential cause).
96 entity_a: u64,
97 /// Second entity (potential effect).
98 entity_b: u64,
99 /// Maximum lag to test.
100 max_lag: usize,
101 /// Significance threshold (e.g., 0.05).
102 significance: f64,
103 },
104 /// Discover recurring motifs in an entity's trajectory.
105 DiscoverMotifs {
106 /// Entity identifier.
107 entity_id: u64,
108 /// Subsequence window size (number of time steps).
109 window: usize,
110 /// Maximum number of motifs to return.
111 max_motifs: usize,
112 },
113 /// Discover anomalous subsequences (discords) in an entity's trajectory.
114 DiscoverDiscords {
115 /// Entity identifier.
116 entity_id: u64,
117 /// Subsequence window size (number of time steps).
118 window: usize,
119 /// Maximum number of discords to return.
120 max_discords: usize,
121 },
122 /// Temporal join: find convergence windows between two entities.
123 TemporalJoin {
124 /// First entity.
125 entity_a: u64,
126 /// Second entity.
127 entity_b: u64,
128 /// Distance threshold for convergence.
129 epsilon: f32,
130 /// Window size in microseconds.
131 window_us: i64,
132 },
133 /// Causal search: semantic kNN + temporal edge context (RFC-010).
134 CausalSearch {
135 /// Query vector.
136 vector: Vec<f32>,
137 /// Number of results.
138 k: usize,
139 /// Temporal filter.
140 filter: TemporalFilter,
141 /// Semantic vs temporal weight.
142 alpha: f32,
143 /// Reference timestamp.
144 query_timestamp: i64,
145 /// Steps of temporal context (forward and backward).
146 temporal_context: usize,
147 },
148 /// Cohort drift analysis across multiple entities.
149 CohortDrift {
150 /// Entity identifiers in the cohort.
151 entity_ids: Vec<u64>,
152 /// Start timestamp.
153 t1: i64,
154 /// End timestamp.
155 t2: i64,
156 /// Number of top dimensions to report.
157 top_n: usize,
158 },
159}
160
161/// Query result types.
162#[derive(Debug, Clone)]
163pub enum QueryResult {
164 /// kNN results with scores.
165 Knn(Vec<KnnResult>),
166 /// Trajectory points.
167 Trajectory(Vec<TemporalPoint>),
168 /// Velocity vector.
169 Velocity(Vec<f32>),
170 /// Predicted vector.
171 Prediction(PredictionResult),
172 /// Detected change points.
173 ChangePoints(Vec<ChangePoint>),
174 /// Drift report.
175 Drift(DriftResult),
176 /// Analogy result.
177 Analogy(Vec<f32>),
178 /// Counterfactual result.
179 Counterfactual(CounterfactualQueryResult),
180 /// Granger causality result.
181 Granger(GrangerCausalityResult),
182 /// Discovered motifs.
183 Motifs(Vec<MotifResult>),
184 /// Discovered discords.
185 Discords(Vec<DiscordResult>),
186 /// Temporal join results.
187 TemporalJoin(Vec<TemporalJoinResultEntry>),
188 /// Cohort drift report.
189 CohortDrift(CohortDriftResult),
190 /// Causal search results.
191 CausalSearch(Vec<CausalSearchResultEntry>),
192}
193
194/// A causal search result with temporal context.
195#[derive(Debug, Clone)]
196pub struct CausalSearchResultEntry {
197 /// Node ID.
198 pub node_id: u32,
199 /// Distance score.
200 pub score: f32,
201 /// Entity ID.
202 pub entity_id: u64,
203 /// Temporal successors: (node_id, timestamp).
204 pub successors: Vec<(u32, i64)>,
205 /// Temporal predecessors: (node_id, timestamp).
206 pub predecessors: Vec<(u32, i64)>,
207}
208
209/// A convergence window from a temporal join query.
210#[derive(Debug, Clone)]
211pub struct TemporalJoinResultEntry {
212 /// Start of the convergence window.
213 pub start: i64,
214 /// End of the convergence window.
215 pub end: i64,
216 /// Mean distance during convergence.
217 pub mean_distance: f32,
218 /// Minimum distance during convergence.
219 pub min_distance: f32,
220 /// Points from entity A in window.
221 pub points_a: usize,
222 /// Points from entity B in window.
223 pub points_b: usize,
224}
225
226/// Counterfactual analysis result for query layer.
227#[derive(Debug, Clone)]
228pub struct CounterfactualQueryResult {
229 /// Change point timestamp.
230 pub change_point: i64,
231 /// Total divergence (area under curve).
232 pub total_divergence: f64,
233 /// Timestamp of maximum divergence.
234 pub max_divergence_time: i64,
235 /// Maximum divergence value.
236 pub max_divergence_value: f32,
237 /// Divergence curve: `(timestamp, distance)`.
238 pub divergence_curve: Vec<(i64, f32)>,
239 /// Method used.
240 pub method: String,
241}
242
243/// Granger causality test result.
244#[derive(Debug, Clone)]
245pub struct GrangerCausalityResult {
246 /// Detected direction.
247 pub direction: String,
248 /// Optimal lag.
249 pub optimal_lag: usize,
250 /// F-statistic.
251 pub f_statistic: f64,
252 /// Combined p-value.
253 pub p_value: f64,
254 /// Effect size (partial R²).
255 pub effect_size: f64,
256 /// Per-dimension F-statistics for A→B.
257 pub per_dimension_a_to_b: Vec<f64>,
258 /// Per-dimension F-statistics for B→A.
259 pub per_dimension_b_to_a: Vec<f64>,
260}
261
262/// A discovered motif result.
263#[derive(Debug, Clone)]
264pub struct MotifResult {
265 /// Index of the canonical occurrence.
266 pub canonical_index: usize,
267 /// All occurrences with timestamps and distances.
268 pub occurrences: Vec<MotifOccurrenceResult>,
269 /// Detected period (None if aperiodic).
270 pub period: Option<usize>,
271 /// Mean match distance.
272 pub mean_match_distance: f32,
273}
274
275/// A single motif occurrence.
276#[derive(Debug, Clone)]
277pub struct MotifOccurrenceResult {
278 /// Start index in trajectory.
279 pub start_index: usize,
280 /// Timestamp.
281 pub timestamp: i64,
282 /// Distance to canonical.
283 pub distance: f32,
284}
285
286/// A discovered discord result.
287#[derive(Debug, Clone)]
288pub struct DiscordResult {
289 /// Start index in trajectory.
290 pub start_index: usize,
291 /// Timestamp.
292 pub timestamp: i64,
293 /// Nearest-neighbor distance (higher = more anomalous).
294 pub nn_distance: f32,
295}
296
297/// Cohort drift analysis result.
298#[derive(Debug, Clone)]
299pub struct CohortDriftResult {
300 /// Number of entities analyzed.
301 pub n_entities: usize,
302 /// Mean L2 drift across the cohort.
303 pub mean_drift_l2: f32,
304 /// Median L2 drift.
305 pub median_drift_l2: f32,
306 /// Standard deviation of drift magnitudes.
307 pub std_drift_l2: f32,
308 /// Centroid L2 drift magnitude.
309 pub centroid_l2_magnitude: f32,
310 /// Centroid cosine drift.
311 pub centroid_cosine_drift: f32,
312 /// Dispersion at t1.
313 pub dispersion_t1: f32,
314 /// Dispersion at t2.
315 pub dispersion_t2: f32,
316 /// Dispersion change (positive = diverging).
317 pub dispersion_change: f32,
318 /// Convergence score (0 = random, 1 = same direction).
319 pub convergence_score: f32,
320 /// Top changed dimensions: (index, absolute_change).
321 pub top_dimensions: Vec<(usize, f32)>,
322 /// Outlier entities.
323 pub outliers: Vec<CohortOutlierResult>,
324}
325
326/// An outlier entity in cohort drift analysis.
327#[derive(Debug, Clone)]
328pub struct CohortOutlierResult {
329 /// Entity identifier.
330 pub entity_id: u64,
331 /// Individual drift magnitude.
332 pub drift_magnitude: f32,
333 /// Z-score relative to cohort.
334 pub z_score: f32,
335 /// Alignment with cohort mean drift direction.
336 pub drift_direction_alignment: f32,
337}
338
339/// A single kNN result.
340#[derive(Debug, Clone)]
341pub struct KnnResult {
342 /// Entity identifier.
343 pub entity_id: u64,
344 /// Timestamp of the matched point.
345 pub timestamp: i64,
346 /// Combined spatiotemporal score.
347 pub score: f32,
348}
349
350/// Prediction result with confidence.
351#[derive(Debug, Clone)]
352pub struct PredictionResult {
353 /// Predicted vector.
354 pub vector: Vec<f32>,
355 /// Target timestamp.
356 pub timestamp: i64,
357 /// Prediction method used.
358 pub method: PredictionMethod,
359}
360
361/// Method used for prediction.
362#[derive(Debug, Clone, Copy)]
363pub enum PredictionMethod {
364 /// Linear extrapolation from last two points.
365 Linear,
366 /// Neural ODE integration.
367 NeuralOde,
368}
369
370/// Drift quantification result.
371#[derive(Debug, Clone)]
372pub struct DriftResult {
373 /// L2 drift magnitude.
374 pub l2_magnitude: f32,
375 /// Cosine drift.
376 pub cosine_drift: f32,
377 /// Top changed dimensions: (index, absolute_change).
378 pub top_dimensions: Vec<(usize, f32)>,
379}