1use indexmap::IndexMap;
2use indexmap::IndexSet;
3use itertools::*;
4use std::collections::HashMap;
5use std::fmt::Debug;
6use std::fmt::Display;
7use std::vec::IntoIter;
8use tracing::debug;
9
10use crate::Bag;
11use crate::Key;
12use crate::MatchCond;
13use crate::Pending;
14use crate::RbeError;
15use crate::Ref;
16use crate::Value;
17use crate::rbe::Rbe;
19use crate::rbe1::Rbe as Rbe1;
20use crate::rbe_error;
21use crate::values::Values;
22use crate::Component;
23
24#[derive(Default, PartialEq, Eq, Clone)]
25pub struct RbeTable<K, V, R>
26where
27 K: Key,
28 V: Value,
29 R: Ref,
30{
31 rbe: Rbe<Component>,
33
34 key_components: IndexMap<K, IndexSet<Component>>,
36
37 component_cond: IndexMap<Component, MatchCond<K, V, R>>,
39 component_key: HashMap<Component, K>,
40
41 open: bool,
43
44 component_counter: usize,
46}
47
48impl<K, V, R> RbeTable<K, V, R>
49where
50 K: Key,
51 V: Value,
52 R: Ref,
53{
54 pub fn new() -> RbeTable<K, V, R> {
55 RbeTable::default()
56 }
57
58 pub fn add_component(&mut self, k: K, cond: &MatchCond<K, V, R>) -> Component {
59 let c = Component::from(self.component_counter);
60 let key = k.clone();
61 self.key_components
62 .entry(k)
63 .and_modify(|vs| {
64 (*vs).insert(c);
65 })
66 .or_insert_with(|| {
67 let mut hs = IndexSet::new();
68 hs.insert(c);
69 hs
70 });
71 self.component_cond.insert(c, cond.clone());
72 self.component_key.insert(c, key);
73 self.component_counter += 1;
74 c
75 }
76
77 pub fn with_rbe(&mut self, rbe: Rbe<Component>) {
78 self.rbe = rbe;
79 }
80
81 pub fn matches(
82 &self,
83 values: Vec<(K, V)>,
84 ) -> Result<MatchTableIter<K, V, R>, RbeError<K, V, R>> {
85 let mut pairs_found = 0;
86 let mut candidates = Vec::new();
87 let cs_empty = IndexSet::new();
88 for (key, value) in &values {
89 let components = self.key_components.get(key).unwrap_or(&cs_empty);
90 let mut pairs = Vec::new();
91 for component in components {
92 let cond = self.component_cond.get(component).unwrap();
95 pairs_found += 1;
96 pairs.push((key.clone(), value.clone(), *component, cond.clone()));
97 }
98 candidates.push(pairs);
99 }
100
101 if candidates.is_empty() || pairs_found == 0 {
102 debug!(
103 "No candidates for rbe: {:?}, candidates: {:?}, pairs_found: {pairs_found}",
104 self.rbe, candidates,
105 );
106 Ok(MatchTableIter::Empty(EmptyIter {
107 is_first: true,
108 rbe: cnv_rbe(&self.rbe, self),
109 values: Values::from(&values),
110 }))
111 } else {
112 debug!("Candidates not empty rbe: {:?}", self.rbe);
113 let _: Vec<_> = candidates
114 .iter()
115 .zip(0..)
116 .map(|(candidate, n)| {
117 debug!("Candidate {n}: {}", show_candidate(candidate));
118 })
119 .collect();
120 let mp = candidates.into_iter().multi_cartesian_product();
121 Ok(MatchTableIter::NonEmpty(IterCartesianProduct {
122 is_first: true,
123 state: mp,
124 rbe: self.rbe.clone(),
125 open: self.open,
126 }))
128 }
129 }
130
131 pub fn components(&self) -> ComponentsIter<K, V, R> {
132 ComponentsIter {
133 current: 0,
134 table: self,
135 }
136 }
137}
138
139pub struct ComponentsIter<'a, K, V, R>
140where
141 K: Key,
142 V: Value,
143 R: Ref,
144{
145 current: usize,
146 table: &'a RbeTable<K, V, R>,
147}
148
149impl<K, V, R> Iterator for ComponentsIter<'_, K, V, R>
150where
151 K: Key,
152 V: Value,
153 R: Ref,
154{
155 type Item = (Component, K, MatchCond<K, V, R>);
156
157 fn next(&mut self) -> Option<Self::Item> {
158 if self.current < self.table.component_counter {
159 let c = Component::from(self.current);
160 let cond = self.table.component_cond.get(&c).unwrap().clone();
161 let key = self.table.component_key.get(&c).unwrap().clone();
162 self.current += 1;
163 Some((c, key, cond))
164 } else {
165 None
166 }
167 }
168}
169
170impl<K, V, R> Debug for ComponentsIter<'_, K, V, R>
171where
172 K: Key,
173 V: Value,
174 R: Ref,
175{
176 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
177 f.debug_struct("ComponentsIter")
178 .field("current", &self.current)
179 .field("table", &self.table)
180 .finish()
181 }
182}
183
184impl<K, V, R> Debug for RbeTable<K, V, R>
185where
186 K: Key,
187 V: Value,
188 R: Ref,
189{
190 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
191 f.debug_struct("RbeTable")
192 .field("rbe", &self.rbe)
193 .field("key_components", &self.key_components)
194 .field("component_cond", &self.component_cond)
195 .field("component_key", &self.component_key)
196 .field("open", &self.open)
197 .field("component_counter", &self.component_counter)
198 .finish()
199 }
200}
201
202#[derive(Debug, Clone)]
203pub enum MatchTableIter<K, V, R>
204where
205 K: Key,
206 V: Value,
207 R: Ref,
208{
209 Empty(EmptyIter<K, V, R>),
210 NonEmpty(IterCartesianProduct<K, V, R>),
211}
212
213impl<K, V, R> Iterator for MatchTableIter<K, V, R>
214where
215 K: Key,
216 V: Value,
217 R: Ref,
218{
219 type Item = Result<Pending<V, R>, rbe_error::RbeError<K, V, R>>;
220
221 fn next(&mut self) -> Option<Self::Item> {
222 match self {
223 MatchTableIter::Empty(ref mut e) => e.next(),
224 MatchTableIter::NonEmpty(ref mut cp) => cp.next(),
225 }
226 }
227}
228
229type State<K, V, R> = MultiProduct<IntoIter<(K, V, Component, MatchCond<K, V, R>)>>;
230
231#[derive(Debug, Clone)]
232pub struct IterCartesianProduct<K, V, R>
233where
234 K: Key,
235 V: Value,
236 R: Ref,
237{
238 is_first: bool,
239 state: State<K, V, R>,
240 rbe: Rbe<Component>,
241 open: bool,
242 }
244
245impl<K, V, R> Iterator for IterCartesianProduct<K, V, R>
246where
247 K: Key,
248 V: Value,
249 R: Ref,
250{
251 type Item = Result<Pending<V, R>, rbe_error::RbeError<K, V, R>>;
252
253 fn next(&mut self) -> Option<Self::Item> {
254 let next_state = self.state.next();
255 match next_state {
257 None => {
258 if self.is_first {
259 debug!("Should be internal error? No more candidates");
260 debug!("RBE: {}", self.rbe);
261 None
262 } else {
263 debug!("No more candidates");
264 None
265 }
266 }
267 Some(vs) => {
268 for (k, v, c, cond) in &vs {
269 debug!("Next state: ({k} {v}) should match component {c} with cond: {cond})");
270 }
271 let mut pending: Pending<V, R> = Pending::new();
272 for (_k, v, _, cond) in &vs {
273 match cond.matches(v) {
274 Ok(new_pending) => {
275 debug!("Condition passed: {cond} with value: {v}, new pending: {new_pending}");
276 pending.merge(new_pending);
277 debug!("Pending merged: {pending}");
278 }
279 Err(err) => {
280 debug!("Failed condition: {cond} with value: {v}");
281 return Some(Err(err));
282 }
283 }
284 }
285 debug!("Pending after checking conditions: {pending}");
286 let bag = Bag::from_iter(vs.into_iter().map(|(_, _, c, _)| c));
287 match self.rbe.match_bag(&bag, self.open) {
288 Ok(()) => {
289 debug!("Rbe {} matches bag {}", self.rbe, bag);
290 self.is_first = false;
291 Some(Ok(pending))
292 }
293 Err(err) => {
294 debug!("### Skipped error: {err}!!!!\n");
295 self.next()
296 }
297 }
298 }
299 }
300 }
301}
302
303#[derive(Debug, Clone)]
304pub struct EmptyIter<K, V, R>
305where
306 K: Key,
307 V: Value,
308 R: Ref,
309{
310 is_first: bool,
311 rbe: Rbe1<K, V, R>,
312 values: Values<K, V>,
313}
314
315impl<K, V, R> Iterator for EmptyIter<K, V, R>
316where
317 K: Key,
318 V: Value,
319 R: Ref,
320{
321 type Item = Result<Pending<V, R>, rbe_error::RbeError<K, V, R>>;
322
323 fn next(&mut self) -> Option<Self::Item> {
324 if self.is_first {
325 self.is_first = false;
326 Some(Err(RbeError::EmptyCandidates {
327 rbe: Box::new(self.rbe.clone()),
328 values: self.values.clone(),
329 }))
330 } else {
331 None
332 }
333 }
334}
335
336fn cnv_rbe<K, V, R>(rbe: &Rbe<Component>, table: &RbeTable<K, V, R>) -> Rbe1<K, V, R>
337where
338 K: Key,
339 V: Value,
340 R: Ref,
341{
342 match rbe {
343 Rbe::Empty => Rbe1::Empty,
344 Rbe::And { values } => {
345 let values1 = values.iter().map(|c| cnv_rbe(c, table)).collect();
346 Rbe1::And { exprs: values1 }
347 }
348 Rbe::Or { values } => {
349 let values1 = values.iter().map(|c| cnv_rbe(c, table)).collect();
350 Rbe1::Or { exprs: values1 }
351 }
352 Rbe::Symbol { value, card } => {
353 let key = cnv_key(value, table);
354 let cond = cnv_cond(value, table);
355 Rbe1::Symbol {
356 key,
357 cond,
358 card: (*card).clone(),
359 }
360 }
361 _ => todo!(),
362 }
363}
364
365fn cnv_cond<K, V, R>(c: &Component, table: &RbeTable<K, V, R>) -> MatchCond<K, V, R>
366where
367 K: Key,
368 V: Value,
369 R: Ref,
370{
371 table.component_cond.get(c).unwrap().clone()
372}
373
374fn cnv_key<K, V, R>(c: &Component, table: &RbeTable<K, V, R>) -> K
375where
376 K: Key,
377 V: Value,
378 R: Ref,
379{
380 table.component_key.get(c).unwrap().clone()
381}
382
383impl<K, V, R> Display for RbeTable<K, V, R>
384where
385 K: Key + Display,
386 V: Value + Display,
387 R: Ref + Display,
388{
389 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
390 writeln!(f, "RBE: {}", self.rbe)?;
391 writeln!(f, "Keys:")?;
392 for (k, c) in self.key_components.iter() {
393 write!(f, " {k} -> [")?;
394 for c in c.iter() {
395 write!(f, " {c}")?;
396 }
397 writeln!(f, " ]")?;
398 }
399 writeln!(f, "Components:")?;
400 for (c, cond) in self.component_cond.iter() {
401 let k = self.component_key.get(c).unwrap();
402 writeln!(f, " {c} -> {k} {cond}")?;
403 }
404 Ok(())
405 }
406}
407
408#[allow(clippy::type_complexity)]
409fn show_candidate<K, V, R>(candidate: &[(K, V, Component, MatchCond<K, V, R>)]) -> String
410where
411 K: Key + Display,
412 V: Value + Display,
413 R: Ref + Display,
414{
415 candidate
416 .iter()
417 .map(|(k, v, c, cond)| format!("({k} {v})@{c} {cond}"))
418 .collect::<Vec<_>>()
419 .join(", ")
420}
421
422#[cfg(test)]
423mod tests {
424 use crate::{Max, SingleCond};
425
426 use super::*;
427
428 impl Key for char {}
429 impl Value for char {}
430 impl Ref for char {}
431
432 #[test]
433 fn test_rbe_table_1() {
434 let is_a: MatchCond<char, char, char> =
437 MatchCond::single(SingleCond::new().with_name("is_a").with_cond(move |v| {
438 if *v == 'a' {
439 Ok(Pending::new())
440 } else {
441 Err(rbe_error::RbeError::MsgError {
442 msg: format!("Value {v}!='a'"),
443 })
444 }
445 }));
446
447 let ref_t: MatchCond<char, char, char> =
448 MatchCond::single(SingleCond::new().with_name("ref_t").with_cond(move |v| {
449 let mut pending = Pending::new();
450 pending.insert(*v, 't');
451 Ok(pending)
452 }));
453
454 let ref_u: MatchCond<char, char, char> =
455 MatchCond::single(SingleCond::new().with_name("ref_u").with_cond(move |v| {
456 let mut pending = Pending::new();
457 pending.insert(*v, 'u');
458 Ok(pending)
459 }));
460
461 let vs = vec![('p', 'a'), ('q', 'y'), ('q', 'z')];
462
463 let mut rbe_table = RbeTable::new();
465 let c1 = rbe_table.add_component('p', &is_a);
466 let c2 = rbe_table.add_component('q', &ref_t);
467 let c3 = rbe_table.add_component('q', &ref_u);
468 rbe_table.with_rbe(Rbe::and(vec![
469 Rbe::symbol(c1, 1, Max::IntMax(1)),
470 Rbe::symbol(c2, 1, Max::IntMax(1)),
471 Rbe::symbol(c3, 1, Max::Unbounded),
472 ]));
473
474 let mut iter = rbe_table.matches(vs).unwrap();
475
476 assert_eq!(
477 iter.next(),
478 Some(Ok(Pending::from(
479 vec![('y', vec!['t']), ('z', vec!['u'])].into_iter()
480 )))
481 );
482 assert_eq!(
483 iter.next(),
484 Some(Ok(Pending::from(
485 vec![('y', vec!['u']), ('z', vec!['t'])].into_iter()
486 )))
487 );
488 assert_eq!(iter.next(), None);
489 }
490
491 #[test]
492 fn test_rbe_table_2_fail() {
493 let is_a: MatchCond<char, char, char> =
496 MatchCond::single(SingleCond::new().with_name("is_a").with_cond(move |v| {
497 if *v == 'a' {
498 Ok(Pending::new())
499 } else {
500 Err(rbe_error::RbeError::MsgError {
501 msg: format!("Value {v}!='a'"),
502 })
503 }
504 }));
505
506 let ref_t: MatchCond<char, char, char> =
507 MatchCond::single(SingleCond::new().with_name("ref_t").with_cond(move |v| {
508 let mut pending = Pending::new();
509 pending.insert(*v, 't');
510 Ok(pending)
511 }));
512
513 let ref_u: MatchCond<char, char, char> =
514 MatchCond::single(SingleCond::new().with_name("ref_u").with_cond(move |v| {
515 let mut pending = Pending::new();
516 pending.insert(*v, 'u');
517 Ok(pending)
518 }));
519
520 let vs = vec![('p', 'a'), ('q', 'y')];
521
522 let mut rbe_table = RbeTable::new();
524 let c1 = rbe_table.add_component('p', &is_a);
525 let c2 = rbe_table.add_component('q', &ref_t);
526 let c3 = rbe_table.add_component('q', &ref_u);
527 rbe_table.with_rbe(Rbe::and(vec![
528 Rbe::symbol(c1, 1, Max::IntMax(1)),
529 Rbe::symbol(c2, 1, Max::IntMax(1)),
530 Rbe::symbol(c3, 1, Max::Unbounded),
531 ]));
532
533 let mut iter = rbe_table.matches(vs).unwrap();
534
535 assert_eq!(iter.next(), None);
536 }
537
538 #[test]
539 fn test_rbe_table_3_basic() {
540 let is_a: MatchCond<char, char, char> =
543 MatchCond::single(SingleCond::new().with_name("is_a").with_cond(move |v| {
544 if *v == 'a' {
545 Ok(Pending::new())
546 } else {
547 Err(rbe_error::RbeError::MsgError {
548 msg: format!("Value {v}!='a'"),
549 })
550 }
551 }));
552
553 let vs = vec![('p', 'a'), ('q', 'a')];
554
555 let mut rbe_table = RbeTable::new();
557 let c1 = rbe_table.add_component('p', &is_a);
558 let c2 = rbe_table.add_component('q', &is_a);
559 rbe_table.with_rbe(Rbe::and(vec![
560 Rbe::symbol(c1, 1, Max::IntMax(1)),
561 Rbe::symbol(c2, 1, Max::IntMax(1)),
562 ]));
563
564 let mut iter = rbe_table.matches(vs).unwrap();
565
566 assert_eq!(iter.next(), Some(Ok(Pending::new())));
567 assert_eq!(iter.next(), None);
568 }
569
570 #[test]
571 fn test_rbe_table_4_basic_fail() {
572 let is_a: MatchCond<char, char, char> =
575 MatchCond::single(SingleCond::new().with_name("is_a").with_cond(move |v| {
576 if *v == 'a' {
577 Ok(Pending::new())
578 } else {
579 Err(rbe_error::RbeError::MsgError {
580 msg: format!("Value {v}!='a'"),
581 })
582 }
583 }));
584
585 let vs = vec![('p', 'a'), ('q', 'b')];
586
587 let mut rbe_table = RbeTable::new();
589 let c1 = rbe_table.add_component('p', &is_a);
590 let c2 = rbe_table.add_component('q', &is_a);
591 rbe_table.with_rbe(Rbe::and(vec![
592 Rbe::symbol(c1, 1, Max::IntMax(1)),
593 Rbe::symbol(c2, 1, Max::IntMax(1)),
594 ]));
595
596 let mut iter = rbe_table.matches(vs).unwrap();
597
598 assert_eq!(
599 iter.next(),
600 Some(Err(rbe_error::RbeError::MsgError {
601 msg: "Value b!='a'".to_string()
602 }))
603 );
604 }
605}