automatic_relations/convolution/aligned/
automaton.rs

1use ta::{
2    Symbol,
3    Rank,
4    NoLabel,
5    bottom_up::{
6        Automaton,
7        Configuration,
8        width_search::LanguageState
9    },
10    combinations
11};
12use crate::{
13    Convoluted,
14    MaybeBottom,
15};
16
17pub fn add_to_convolution<E, F: Symbol, Q: LanguageState<F, E>>(aut: &mut Automaton<Rank<Convoluted<F>>, Convoluted<Q>, NoLabel>, state: &Convoluted<Q>, env: &E) {
18    if !aut.includes(state) {
19        for configurations in combinations(&state.0, |q| {
20            if let MaybeBottom::Some(q) = q {
21                Box::new(q.configurations(env).map(|conf| MaybeBottom::Some(conf))) as Box<dyn Iterator<Item=MaybeBottom<Configuration<F, Q>>>>
22            } else {
23                Box::new(std::iter::once(MaybeBottom::Bottom)) as Box<dyn Iterator<Item=MaybeBottom<Configuration<F, Q>>>>
24            }
25        }) {
26            let mut convoluted_f = Vec::with_capacity(configurations.len());
27            let mut bottom = true;
28            let mut states = Vec::new();
29
30            for conf in &configurations {
31                if let MaybeBottom::Some(Configuration(f, subs)) = conf {
32                    bottom = false;
33
34                    if states.len() < subs.len() {
35                        let mut bottom_vec = Vec::new();
36                        bottom_vec.resize(convoluted_f.len(), MaybeBottom::Bottom);
37                        states.resize(subs.len(), bottom_vec);
38                    }
39
40                    convoluted_f.push(MaybeBottom::Some(f.clone()));
41
42                    for (i, sub) in subs.iter().enumerate() {
43                        states[i].push(MaybeBottom::Some(sub.clone()))
44                    }
45
46                    for i in subs.len()..states.len() {
47                        states[i].push(MaybeBottom::Bottom);
48                    }
49                } else {
50                    convoluted_f.push(MaybeBottom::Bottom);
51
52                    for i in 0..states.len() {
53                        states[i].push(MaybeBottom::Bottom);
54                    }
55                }
56            }
57
58            if !bottom {
59                let subs: Vec<Convoluted<Q>> = states.into_iter().map(|states| Convoluted(states)).collect();
60                let conf = Configuration(Rank(Convoluted(convoluted_f), subs.len()), subs.clone());
61                aut.add(conf, NoLabel, state.clone());
62
63                for sub in &subs {
64                    add_to_convolution(aut, &sub, env);
65                }
66            }
67        }
68    }
69}
70
71pub fn state_convolution<E, F: Symbol, Q: LanguageState<F, E>>(initial_state: Convoluted<Q>, env: &E) -> Automaton<Rank<Convoluted<F>>, Convoluted<Q>, NoLabel> {
72    let mut aut = Automaton::new();
73    //let initial_state = Convoluted(states.iter().map(|q| MaybeBottom::Some(q.clone())).collect());
74    add_to_convolution(&mut aut, &initial_state, env);
75    aut.set_final(initial_state);
76    aut
77}