rbe/
rbe_table.rs

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;
17// use crate::RbeError;
18use 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    // A regular bag expression of components
32    rbe: Rbe<Component>,
33
34    // Each key is associated with a set of components
35    key_components: IndexMap<K, IndexSet<Component>>,
36
37    // TODO: Unify in a single table component_cond and component_key
38    component_cond: IndexMap<Component, MatchCond<K, V, R>>,
39    component_key: HashMap<Component, K>,
40
41    // Indicates if the RBE is open or closed
42    open: bool,
43
44    // Counter for the number of components
45    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                // TODO: Add some better error control to replace unwrap()?
93                //  This should mark an internal error anyway
94                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                // controlled: self.controlled.clone()
127            }))
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    // controlled: HashSet<K>
243}
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        // debug!("state in IterCartesianProduct {:?}", self.state);
256        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        // { p a; q y; q z } == { p is_a; q @t ; q @u }
435        //     Pending y/@t, z/@u | y@u, z@t
436        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        // rbe_table = { p is_a ; q @t ; q @u+ }
464        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        // { p a; q y } != { p is_a; q @t ; q @u }
494        //     Pending y/@t, z/@u | y@u, z@t
495        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        // rbe_table = { p is_a ; q @t ; q @u+ }
523        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        // { p a; q a } == { p is_a; q is_a }
541        //     Ok
542        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        // rbe_table = { p is_a ; q is_a }
556        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        // { p a; q b } == { p is_a; q is_a }
573        //     Ok
574        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        // rbe_table = { p is_a ; q is_a }
588        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}