Skip to main content

rust_lstar/eqtest/
multiple_eqtests.rs

1use crate::automata::Automata;
2use crate::eqtest::{Counterexample, EquivalenceTest};
3use std::sync::Arc;
4
5/// Compose multiple equivalence strategies and return the first counterexample.
6pub struct MultipleEqtests {
7    pub eqtests: Vec<Arc<dyn EquivalenceTest>>,
8}
9
10impl MultipleEqtests {
11    pub fn new(eqtests: Vec<Arc<dyn EquivalenceTest>>) -> Self {
12        Self { eqtests }
13    }
14}
15
16impl EquivalenceTest for MultipleEqtests {
17    fn find_counterexample(&self, hypothesis: &mut Automata) -> Option<Counterexample> {
18        for eqtest in &self.eqtests {
19            if let Some(counterexample) = eqtest.find_counterexample(hypothesis) {
20                return Some(counterexample);
21            }
22        }
23        None
24    }
25}
26
27#[cfg(test)]
28mod tests {
29    use super::*;
30    use crate::automata::{Automata, State};
31    use crate::eqtest::EquivalenceTest;
32    use crate::letter::Letter;
33    use crate::word::Word;
34
35    struct AlwaysNone;
36    impl EquivalenceTest for AlwaysNone {
37        fn find_counterexample(&self, _hypothesis: &mut Automata) -> Option<Counterexample> {
38            None
39        }
40    }
41
42    struct AlwaysSome;
43    impl EquivalenceTest for AlwaysSome {
44        fn find_counterexample(&self, _hypothesis: &mut Automata) -> Option<Counterexample> {
45            Some(Counterexample {
46                input_word: Word::from_letters(vec![Letter::new("a")]),
47                output_word: Word::from_letters(vec![Letter::new("1")]),
48            })
49        }
50    }
51
52    #[test]
53    fn multiple_eqtests_returns_none_when_all_none() {
54        let mut hypothesis = Automata::new(State::new("S0".to_string()), "H".to_string());
55        let eq = MultipleEqtests::new(vec![Arc::new(AlwaysNone), Arc::new(AlwaysNone)]);
56        assert!(eq.find_counterexample(&mut hypothesis).is_none());
57    }
58
59    #[test]
60    fn multiple_eqtests_returns_first_counterexample() {
61        let mut hypothesis = Automata::new(State::new("S0".to_string()), "H".to_string());
62        let eq = MultipleEqtests::new(vec![
63            Arc::new(AlwaysNone),
64            Arc::new(AlwaysSome),
65            Arc::new(AlwaysNone),
66        ]);
67        assert!(eq.find_counterexample(&mut hypothesis).is_some());
68    }
69}