automatic_relations/convolution/aligned/
automaton.rs1use 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 add_to_convolution(&mut aut, &initial_state, env);
75 aut.set_final(initial_state);
76 aut
77}