tree_automata/alternating/
mod.rs1use std::collections::{HashMap, HashSet};
2use crate::{Symbol, Label, State};
3use crate::bottom_up;
4
5pub type Conjuction<Q, I> = Vec<(I, Q)>;
7
8pub type Clause<Q, I> = Vec<Conjuction<Q, I>>;
10
11pub struct Automaton<F: Symbol, Q: State, I> {
13 dummy_clauses: HashMap<F, Clause<Q, I>>,
14
15 initial_states: HashSet<Q>,
17
18 state_clauses: HashMap<Q, HashMap<F, Clause<Q, I>>>
20}
21
22impl<F: Symbol, Q: State, I> Automaton<F, Q, I> {
23 pub fn new() -> Automaton<F, Q, I> {
25 Automaton {
26 dummy_clauses: HashMap::new(),
27 initial_states: HashSet::new(),
28 state_clauses: HashMap::new()
29 }
30 }
31
32 pub fn states(&self) -> std::collections::hash_map::Keys<Q, HashMap<F, Clause<Q, I>>> {
33 self.state_clauses.keys()
34 }
35
36 pub fn clauses_for_state(&self, q: &Q) -> std::collections::hash_map::Iter<F, Clause<Q, I>> {
37 match self.state_clauses.get(q) {
38 Some(clauses) => clauses.iter(),
39 None => self.dummy_clauses.iter()
40 }
41 }
42
43 pub fn add(&mut self, state: &Q, symbol: &F, conjuction: Conjuction<Q, I>) {
45 match self.state_clauses.get_mut(state) {
46 Some(ref mut symbol_clauses) => {
47 match symbol_clauses.get_mut(symbol) {
48 Some(ref mut clause) => {
49 clause.push(conjuction);
50 },
51 None => {
52 let clause = vec![conjuction];
53 symbol_clauses.insert(symbol.clone(), clause);
54 }
55 }
56 },
57 None => {
58 let mut symbol_clauses = HashMap::new();
59 let clause = vec![conjuction];
60 symbol_clauses.insert(symbol.clone(), clause);
61 self.state_clauses.insert(state.clone(), symbol_clauses);
62 }
63 }
64 }
65
66 pub fn is_initial(&self, q: &Q) -> bool {
67 self.initial_states.contains(q)
68 }
69
70 pub fn set_initial(&mut self, q: Q) -> bool {
74 self.initial_states.insert(q)
75 }
76
77 pub fn map_states<R: State, M>(&self, g: M) -> Automaton<F, R, I> where M: Fn(&Q) -> R, I: Clone {
78 let mut mapped = Automaton::new();
79
80 for (state, clauses) in self.state_clauses.iter() {
81 let state = g(state);
82
83 for (f, clause) in clauses.iter() {
84 for conjunction in clause.iter() {
85 let mapped_conjunction = conjunction.iter().map(|(index, q)| {
86 (index.clone(), g(q))
87 }).collect();
88
89 mapped.add(&state, f, mapped_conjunction);
90 }
91 }
92 }
93
94 for q in self.initial_states.iter() {
95 mapped.set_initial(g(q));
96 }
97
98 mapped
99 }
100}
101
102impl<F: Symbol, Q: State> Automaton<F, Q, u32> {
103 pub fn add_transition(&mut self, bottom_up::Configuration(f, states): &bottom_up::Configuration<F, Q>, state: &Q) {
106 let conjunction = states.iter().enumerate().map(|(i, q)| (i as u32, q.clone())).collect();
107 self.add(state, f, conjunction)
108 }
109}
110
111impl<'a, F: Symbol, Q: State, L: Label> From<&'a bottom_up::Automaton<F, Q, L>> for Automaton<F, Q, u32> {
112 fn from(bottom_up: &'a bottom_up::Automaton<F, Q, L>) -> Automaton<F, Q, u32> {
113 let mut alternating = Automaton::new();
114
115 for (conf, _, q) in bottom_up.transitions() {
117 alternating.add_transition(conf, q)
118 }
119
120 for q in bottom_up.final_states() {
122 alternating.set_initial(q.clone());
123 }
124
125 alternating
126 }
127}