rbe/
rbe1.rs

1use crate::failures::Failures;
2use crate::{deriv_n, rbe_error::RbeError, Cardinality, MatchCond, Max, Min, Pending};
3use crate::{Key, Ref, Value};
4use core::hash::Hash;
5use itertools::cloned;
6use serde::{Deserialize, Serialize};
7use std::collections::HashSet;
8use std::fmt;
9use std::fmt::{Debug, Display};
10
11#[derive(Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
12pub enum Rbe<K, V, R>
13where
14    K: Key,
15    V: Value,
16    R: Ref,
17{
18    Fail {
19        error: RbeError<K, V, R>,
20    },
21    #[default]
22    Empty,
23
24    Symbol {
25        key: K,
26        cond: MatchCond<K, V, R>,
27        card: Cardinality,
28    },
29
30    And {
31        exprs: Vec<Rbe<K, V, R>>,
32    },
33    Or {
34        exprs: Vec<Rbe<K, V, R>>,
35    },
36    Star {
37        expr: Box<Rbe<K, V, R>>,
38    },
39    Plus {
40        expr: Box<Rbe<K, V, R>>,
41    },
42    Repeat {
43        expr: Box<Rbe<K, V, R>>,
44        card: Cardinality,
45    },
46}
47
48type NullableResult = bool;
49
50impl<K, V, R> Rbe<K, V, R>
51where
52    K: Key,
53    V: Value,
54    R: Ref,
55{
56    pub fn empty() -> Rbe<K, V, R> {
57        Rbe::Empty
58    }
59
60    pub fn symbol(key: K, min: usize, max: Max) -> Rbe<K, V, R> {
61        Rbe::Symbol {
62            key,
63            cond: MatchCond::default(),
64            card: Cardinality {
65                min: Min::from(min),
66                max,
67            },
68        }
69    }
70
71    pub fn symbol_cond(key: K, cond: MatchCond<K, V, R>, min: Min, max: Max) -> Rbe<K, V, R> {
72        Rbe::Symbol {
73            key,
74            cond,
75            card: Cardinality { min, max },
76        }
77    }
78
79    pub fn or<I>(exprs: I) -> Rbe<K, V, R>
80    where
81        I: IntoIterator<Item = Rbe<K, V, R>>,
82    {
83        let rs = exprs.into_iter().collect();
84        Rbe::Or { exprs: rs }
85    }
86
87    pub fn and<I>(exprs: I) -> Rbe<K, V, R>
88    where
89        I: IntoIterator<Item = Rbe<K, V, R>>,
90    {
91        let rs = exprs.into_iter().collect();
92        Rbe::And { exprs: rs }
93    }
94
95    pub fn opt(v: Rbe<K, V, R>) -> Rbe<K, V, R> {
96        Rbe::Or {
97            exprs: vec![v, Rbe::Empty],
98        }
99    }
100
101    pub fn plus(expr: Rbe<K, V, R>) -> Rbe<K, V, R> {
102        Rbe::Plus {
103            expr: Box::new(expr),
104        }
105    }
106
107    pub fn star(expr: Rbe<K, V, R>) -> Rbe<K, V, R> {
108        Rbe::Star {
109            expr: Box::new(expr),
110        }
111    }
112
113    pub fn repeat(expr: Rbe<K, V, R>, min: usize, max: Max) -> Rbe<K, V, R> {
114        Rbe::Repeat {
115            expr: Box::new(expr),
116            card: Cardinality::from(Min::from(min), max),
117        }
118    }
119
120    pub fn is_fail(&self) -> bool {
121        matches!(self, Rbe::Fail { .. })
122    }
123
124    pub fn symbols(&self) -> HashSet<K> {
125        let mut set = HashSet::new();
126        self.symbols_aux(&mut set);
127        set
128    }
129
130    fn symbols_aux(&self, set: &mut HashSet<K>) {
131        match &self {
132            Rbe::Fail { .. } => (),
133            Rbe::Empty => (),
134            Rbe::Symbol { key, .. } => {
135                set.insert(key.clone());
136            }
137            Rbe::And { exprs } => {
138                exprs.iter().for_each(|v| v.symbols_aux(set));
139            }
140            Rbe::Or { exprs } => {
141                exprs.iter().for_each(|v| v.symbols_aux(set));
142            }
143            Rbe::Plus { expr } => {
144                expr.symbols_aux(set);
145            }
146            Rbe::Star { expr } => {
147                expr.symbols_aux(set);
148            }
149            Rbe::Repeat { expr, card: _ } => {
150                expr.symbols_aux(set);
151            }
152        }
153    }
154
155    pub fn nullable(&self) -> NullableResult {
156        match &self {
157            Rbe::Fail { .. } => false,
158            Rbe::Empty => true,
159            Rbe::Symbol { card, .. } if card.nullable() => true,
160            Rbe::Symbol { .. } => false,
161            Rbe::And { exprs } => exprs.iter().all(|v| v.nullable()),
162            Rbe::Or { exprs } => exprs.iter().any(|v| v.nullable()),
163            Rbe::Star { .. } => true,
164            Rbe::Plus { expr } => expr.nullable(),
165            Rbe::Repeat { expr: _, card } if card.min.is_0() => true,
166            Rbe::Repeat { expr, card: _ } => expr.nullable(),
167        }
168    }
169
170    /// Calculates the derivative of a `rbe` for a `symbol` with `value`
171    /// open indicates if we allow extra symbols
172    /// `controlled` contains the list of symbols controlled by the `rbe` that should not be assumed as extra symbols
173    /// `pending`
174    pub fn deriv(
175        &self,
176        symbol: &K,
177        value: &V,
178        n: usize,
179        open: bool,
180        controlled: &HashSet<K>,
181        pending: &mut Pending<V, R>,
182    ) -> Rbe<K, V, R>
183    where
184        K: Eq + Hash + Clone,
185    {
186        match *self {
187            ref fail @ Rbe::Fail { .. } => fail.clone(),
188            Rbe::Empty => {
189                if open && !(controlled.contains(symbol)) {
190                    Rbe::Empty
191                } else {
192                    Rbe::Fail {
193                        error: RbeError::UnexpectedEmpty {
194                            x: (*symbol).clone(),
195                            open,
196                        },
197                    }
198                }
199            }
200            Rbe::Symbol {
201                ref key,
202                ref cond,
203                ref card,
204            } => {
205                if *key == *symbol {
206                    match cond.matches(value) {
207                        Err(err) => Rbe::Fail { error: err },
208                        Ok(new_pending) => {
209                            if card.max == Max::IntMax(0) {
210                                Rbe::Fail {
211                                    error: RbeError::MaxCardinalityZeroFoundValue {
212                                        x: (*symbol).clone(),
213                                    },
214                                }
215                            } else {
216                                let new_card = card.minus(n);
217                                (*pending).merge(new_pending);
218                                Self::mk_range_symbol(symbol, cond, &new_card)
219                            }
220                        }
221                    }
222                } else {
223                    // Symbol is different from symbols defined in Rbe
224                    // if the Rbe is open, we allow extra symbols
225                    // unless the controlled symbols
226                    if open && !(controlled.contains(symbol)) {
227                        self.clone()
228                    } else {
229                        Rbe::Fail {
230                            error: RbeError::UnexpectedSymbol {
231                                x: (*symbol).clone(),
232                                expected: key.clone(),
233                                open,
234                            },
235                        }
236                    }
237                }
238            }
239            Rbe::And { ref exprs } => {
240                Self::deriv_and(exprs, symbol, value, n, open, controlled, pending)
241            }
242            Rbe::Or { ref exprs } => Self::mk_or_values(
243                exprs
244                    .iter()
245                    .map(|rbe| rbe.deriv(symbol, value, n, open, controlled, pending)),
246            ),
247            Rbe::Plus { ref expr } => {
248                let d = expr.deriv(symbol, value, n, open, controlled, pending);
249                Self::mk_and(&d, &Rbe::Star { expr: expr.clone() })
250            }
251            Rbe::Repeat { ref expr, ref card } if card.is_0_0() => {
252                let d = expr.deriv(symbol, value, n, open, controlled, pending);
253                if d.nullable() {
254                    Rbe::Fail {
255                        error: RbeError::CardinalityZeroZeroDeriv {
256                            symbol: symbol.clone(),
257                        },
258                    }
259                } else {
260                    Rbe::Empty
261                }
262            }
263            Rbe::Repeat { ref expr, ref card } => {
264                let d = expr.deriv(symbol, value, n, open, controlled, pending);
265                let card = card.minus(n);
266                let rest = Self::mk_range(expr, &card);
267                Self::mk_and(&d, &rest)
268            }
269            Rbe::Star { ref expr } => {
270                let d = expr.deriv(symbol, value, n, open, controlled, pending);
271                Self::mk_and(&d, expr)
272            }
273        }
274    }
275
276    fn deriv_and(
277        values: &Vec<Rbe<K, V, R>>,
278        symbol: &K,
279        value: &V,
280        n: usize,
281        open: bool,
282        controlled: &HashSet<K>,
283        pending: &mut Pending<V, R>,
284    ) -> Rbe<K, V, R> {
285        let mut or_values: Vec<Rbe<K, V, R>> = Vec::new();
286        let mut failures = Failures::new();
287
288        for vs in deriv_n(cloned((*values).iter()).collect(), |expr: &Rbe<K, V, R>| {
289            let d = expr.deriv(symbol, value, n, open, controlled, pending);
290            match d {
291                Rbe::Fail { error } => {
292                    failures.push(expr.clone(), error);
293                    None
294                }
295                _ => Some(d),
296            }
297        }) {
298            or_values.push(Rbe::And { exprs: vs });
299        }
300        match or_values.len() {
301            0 => Rbe::Fail {
302                error: RbeError::OrValuesFail {
303                    e: Box::new(Rbe::And {
304                        exprs: cloned(values.iter()).collect(),
305                    }),
306                    failures,
307                },
308            },
309            1 => or_values[0].clone(),
310            _ => Rbe::Or { exprs: or_values },
311        }
312    }
313
314    fn mk_range(e: &Rbe<K, V, R>, card: &Cardinality) -> Rbe<K, V, R>
315    where
316        K: Clone,
317    {
318        if Self::bigger(card.min, &card.max) {
319            Rbe::Fail {
320                error: RbeError::RangeLowerBoundBiggerMaxExpr {
321                    expr: Box::new((*e).clone()),
322                    card: card.clone(),
323                },
324            }
325        } else {
326            match (e, card) {
327                (_, c) if c.is_0_0() => Rbe::Empty,
328                (e, c) if c.is_1_1() => e.clone(),
329                (fail @ Rbe::Fail { .. }, _) => fail.clone(),
330                (Rbe::Empty, _) => Rbe::Empty,
331                (e, c) => Rbe::Repeat {
332                    expr: Box::new(e.clone()),
333                    card: c.clone(),
334                },
335            }
336        }
337    }
338
339    fn mk_range_symbol(x: &K, cond: &MatchCond<K, V, R>, card: &Cardinality) -> Rbe<K, V, R>
340    where
341        K: Clone,
342    {
343        if Self::bigger(card.min, &card.max) {
344            Rbe::Fail {
345                error: RbeError::RangeLowerBoundBiggerMax {
346                    symbol: (*x).clone(),
347                    card: card.clone(),
348                },
349            }
350        } else {
351            Rbe::Symbol {
352                key: (*x).clone(),
353                cond: (*cond).clone(),
354                card: card.clone(),
355            }
356        }
357    }
358
359    fn mk_and(v1: &Rbe<K, V, R>, v2: &Rbe<K, V, R>) -> Rbe<K, V, R>
360    where
361        K: Clone,
362    {
363        match (v1, v2) {
364            (Rbe::Empty, _) => (*v2).clone(),
365            (_, Rbe::Empty) => (*v1).clone(),
366            (f @ Rbe::Fail { .. }, _) => f.clone(),
367            (_, f @ Rbe::Fail { .. }) => f.clone(),
368            (_, _) => Rbe::And {
369                exprs: vec![(*v1).clone(), (*v2).clone()],
370            },
371        }
372    }
373
374    fn mk_or_values<I>(values: I) -> Rbe<K, V, R>
375    where
376        I: IntoIterator<Item = Rbe<K, V, R>>,
377    {
378        let init = Rbe::Fail {
379            error: RbeError::MkOrValuesFail,
380        };
381
382        values
383            .into_iter()
384            .fold(init, |result, value| Self::mk_or(&result, &value))
385    }
386
387    fn mk_or(v1: &Rbe<K, V, R>, v2: &Rbe<K, V, R>) -> Rbe<K, V, R> {
388        match (v1, v2) {
389            (Rbe::Fail { .. }, _) => (*v2).clone(),
390            (_, Rbe::Fail { .. }) => (*v1).clone(),
391            (e1, e2) => {
392                if e1 == e2 {
393                    (*v1).clone()
394                } else {
395                    Rbe::Or {
396                        exprs: vec![(*v1).clone(), (*v2).clone()],
397                    }
398                }
399            }
400        }
401    }
402
403    fn bigger(min: Min, max: &Max) -> bool {
404        match max {
405            Max::Unbounded => false,
406            Max::IntMax(max) => min.value > *max,
407        }
408    }
409}
410
411impl<K, V, R> Debug for Rbe<K, V, R>
412where
413    K: Key,
414    V: Value,
415    R: Ref,
416{
417    fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
418        match &self {
419            Rbe::Fail { error } => write!(dest, "Fail {{{error:?}}}"),
420            Rbe::Empty => write!(dest, "Empty"),
421            Rbe::Symbol { key, cond, card } => write!(dest, "{key:?}|{cond:?}{card:?}"),
422            Rbe::And { exprs } => exprs
423                .iter()
424                .try_for_each(|value| write!(dest, "{value:?};")),
425            Rbe::Or { exprs } => exprs
426                .iter()
427                .try_for_each(|value| write!(dest, "{value:?}|")),
428            Rbe::Star { expr } => write!(dest, "{expr:?}*"),
429            Rbe::Plus { expr } => write!(dest, "{expr:?}+"),
430            Rbe::Repeat { expr, card } => write!(dest, "({expr:?}){card:?}"),
431        }
432    }
433}
434
435impl<K, V, R> Display for Rbe<K, V, R>
436where
437    K: Key,
438    V: Value,
439    R: Ref,
440{
441    fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
442        match &self {
443            Rbe::Fail { error } => write!(dest, "Fail {{{error}}}"),
444            Rbe::Empty => write!(dest, "Empty"),
445            Rbe::Symbol { key, cond, card } => write!(dest, "{key}|{cond}{card}"),
446            Rbe::And { exprs } => exprs.iter().try_for_each(|value| write!(dest, "{value};")),
447            Rbe::Or { exprs } => exprs.iter().try_for_each(|value| write!(dest, "{value}|")),
448            Rbe::Star { expr } => write!(dest, "{expr}*"),
449            Rbe::Plus { expr } => write!(dest, "{expr}+"),
450            Rbe::Repeat { expr, card } => write!(dest, "({expr}){card}"),
451        }
452    }
453}
454
455#[cfg(test)]
456mod tests {
457    use super::*;
458
459    impl Ref for i32 {}
460
461    impl Key for String {}
462
463    #[test]
464    fn deriv_a_1_1_and_b_opt_with_a() {
465        // a?|b? #= b/2
466
467        let rbe: Rbe<char, i32, i32> = Rbe::and(vec![
468            Rbe::symbol('a', 1, Max::IntMax(1)),
469            Rbe::symbol('b', 0, Max::IntMax(1)),
470        ]);
471        let mut pending = Pending::new();
472        let expected = Rbe::and(vec![
473            Rbe::symbol('a', 0, Max::IntMax(0)),
474            Rbe::symbol('b', 0, Max::IntMax(1)),
475        ]);
476        assert_eq!(
477            rbe.deriv(
478                &'a',
479                &23,
480                1,
481                false,
482                &HashSet::from(['a', 'b']),
483                &mut pending
484            ),
485            expected
486        );
487    }
488
489    #[test]
490    fn deriv_symbol() {
491        let rbe: Rbe<char, i32, i32> = Rbe::symbol('x', 1, Max::IntMax(1));
492        let mut pending = Pending::new();
493        let d = rbe.deriv(&'x', &2, 1, true, &HashSet::new(), &mut pending);
494        assert_eq!(d, Rbe::symbol('x', 0, Max::IntMax(0)));
495    }
496
497    #[test]
498    fn deriv_symbol_b_2_3() {
499        let rbe: Rbe<String, String, String> = Rbe::symbol("b".to_string(), 2, Max::IntMax(3));
500        let mut pending = Pending::new();
501        let d = rbe.deriv(
502            &"b".to_string(),
503            &"vb2".to_string(),
504            1,
505            true,
506            &HashSet::new(),
507            &mut pending,
508        );
509        assert_eq!(Rbe::symbol("b".to_string(), 1, Max::IntMax(2)), d);
510    }
511
512    #[test]
513    fn symbols() {
514        let rbe: Rbe<char, i32, i32> = Rbe::and(vec![
515            Rbe::symbol('x', 1, Max::IntMax(1)),
516            Rbe::symbol('y', 1, Max::IntMax(1)),
517        ]);
518        let expected = HashSet::from(['x', 'y']);
519        assert_eq!(rbe.symbols(), expected);
520    }
521
522    #[test]
523    fn symbols2() {
524        let rbe: Rbe<char, i32, i32> = Rbe::and(vec![
525            Rbe::or(vec![
526                Rbe::symbol('x', 1, Max::IntMax(1)),
527                Rbe::symbol('y', 2, Max::Unbounded),
528            ]),
529            Rbe::symbol('y', 1, Max::IntMax(1)),
530        ]);
531        let expected = HashSet::from(['x', 'y']);
532        assert_eq!(rbe.symbols(), expected);
533    }
534
535    /*#[test]
536    fn test_serialize_rbe() {
537        let rbe: Rbe<String, String, String> = Rbe::symbol("foo".to_string(), 1, Max::IntMax(2));
538        let expected = indoc! {
539        r#"!Symbol
540                 key: foo
541                 cond: {}
542                 card:
543                   min: 1
544                   max: 2
545              "# };
546        let rbe: String = serde_yml::to_string(&rbe).unwrap();
547        assert_eq!(rbe, expected);
548    }
549
550    #[test]
551    fn test_deserialize_rbe() {
552        let str = r#"{
553            "Symbol": {
554                "key": "foo",
555                "cond": {},
556                "card": {"min": 1, "max": 2 }
557            }
558        }"#;
559        let expected = Rbe::symbol("foo".to_string(), 1, Max::IntMax(2));
560        let rbe: Rbe<String, String, String> = serde_json::from_str(str).unwrap();
561        assert_eq!(rbe, expected);
562    } */
563}