20 #ifndef LIMI_ANTICHAINALGO_IND_H
21 #define LIMI_ANTICHAINALGO_IND_H
23 #include "automaton.h"
32 #include "internal/antichain.h"
34 #include "internal/helpers.h"
35 #include "internal/meta_automaton.h"
66 template <
class ImplementationA,
class InnerImplementationB,
class Independence = independence<
typename ImplementationA::Symbol_>>
69 using StateA =
typename ImplementationA::State_;
70 using InnerStateB =
typename InnerImplementationB::State_;
71 using Symbol =
typename ImplementationA::Symbol_;
74 using StateB =
typename ImplementationB::StateI;
75 using StateA_vector = std::vector<StateA>;
76 using StateB_set = std::unordered_set<StateB>;
77 using StateBI_set = std::shared_ptr<const StateB_set>;
78 using Symbol_set = std::unordered_set<Symbol>;
79 using Symbol_vector = std::vector<Symbol>;
85 using pcounter_chain = std::shared_ptr<counter_chain>;
90 pair(StateA a, StateBI_set b) : a(a), b(b), cex_chain(
nullptr) {}
91 pair(StateA a, StateBI_set b,
const pcounter_chain& parent,
const Symbol& sym) : pair(a,b)
93 cex_chain = std::make_shared<counter_chain>(sym, parent);
97 pcounter_chain cex_chain;
102 void prune(std::shared_ptr<StateB_set>& b, StateBI_set& un_pruned,
unsigned k,
bool dirty) {
103 for(
auto it = b->begin(); it!=b->end(); ) {
104 if ((**it).size() > k) {
105 if (!un_pruned && !dirty) {
106 un_pruned = std::make_shared<StateB_set>(*b);
115 void remove_dirty(std::deque<pair>& frontier) {
116 std::deque<pair> newp;
117 while (!frontier.empty()) {
118 auto& e = frontier.front();
122 frontier.pop_front();
128 std::shared_ptr<StateB_set> states_b = std::make_shared<StateB_set>();
130 std::deque< pair > result;
132 pair p(state_a, states_b);
145 const Independence& independence_;
147 std::deque<pair> before_dirty;
148 std::deque<pair> frontier = initial_states(a,b);
179 if (new_bound < bound)
throw std::logic_error(
"New bound smaller than old bound.");
180 if (new_bound == bound)
return;
184 remove_dirty(frontier);
185 for (
auto& e : before_dirty) {
186 if (!antichain.
contains(e.a, e.b)) {
187 frontier.push_back(e);
188 antichain.
add(e.a, e.b,
false);
191 before_dirty.clear();
208 #ifdef DEBUG_PRINTING
209 unsigned loop_counter = 0;
210 unsigned transitions = 0;
212 while (frontier.size() > 0) {
213 #ifdef DEBUG_PRINTING
214 if (DEBUG_PRINTING>=2 && loop_counter % 1000 == 0) std::cout << loop_counter <<
" rounds; A states: " << antichain.
size() << std::endl;
216 pair current = frontier.front();
217 frontier.pop_front();
219 Symbol_vector next_symbols;
222 #ifdef DEBUG_PRINTING
233 #ifdef DEBUG_PRINTING
234 if (DEBUG_PRINTING>=3) {
235 std::cout <<
"Next pair: ";
237 internal::print_set(*current.b, std::cout, b.
state_printer());
238 std::cout << std::endl;
242 for (Symbol sigma : next_symbols) {
243 #ifdef DEBUG_PRINTING
245 if (DEBUG_PRINTING>=4) {
246 std::cout <<
"Symbol: ";
248 std::cout << std::endl;
251 StateA_vector states_a = a.
successors(current.a, sigma);
252 StateBI_set unpruned;
253 StateBI_set states_b;
254 if (a.
is_epsilon(sigma)) states_b=current.b;
else {
255 auto states_b1 = std::make_shared<StateB_set>();
257 prune(states_b1, unpruned, bound, current.dirty);
258 states_b = states_b1;
261 for (StateA state_a : states_a) {
262 antichain_algo_ind::pair next(state_a, states_b, current.cex_chain, sigma);
263 next.dirty = current.dirty || unpruned;
264 if (unpruned) before_dirty.push_back(antichain_algo_ind::pair(state_a, unpruned, current.cex_chain, sigma));
266 if (!antichain.
contains(next.a, next.b)) {
267 antichain.
add(next.a, next.b, next.dirty);
268 frontier.push_front(std::move(next));
275 #ifdef DEBUG_PRINTING
276 if (DEBUG_PRINTING>=1) std::cout << loop_counter <<
" rounds; seen states: " << antichain.
size() <<
"; transitions: " << transitions << std::endl;
278 if (DEBUG_PRINTING >= 4) {
291 #endif // LIMI_ANTICHAINALGO_IND_H
void next_symbols(const State &state, Symbol_vector &symbols) const
Returns possible successor symbols for a state.
Definition: automaton.h:256
The main namespace of the library.
Definition: antichain_algo.h:40
The result of the language inclusion test.
Definition: results.h:78
void clean_dirty()
Remove elements marked as dirty.
Definition: antichain.h:139
void print(std::ostream &out, const printer_base< A > &printerA=printer< A >(), const printer_base< B > &printerB=printer< B >()) const
Print the antichain on the screen.
Definition: antichain.h:153
void add_unchecked(const A &a, const pb_set &b, bool dirty=false)
Add to the antichain an element without checking if the invariant is preserved.
Definition: antichain.h:80
Represents a list of symbols.
Definition: results.h:41
unsigned max_bound
The maximum bound used to obtain this inclusion result.
Definition: results.h:128
The template for the independence relation.
Definition: generics.h:53
std::vector< Symbol > counter_example
A counter-example if applicable.
Definition: results.h:106
bool contains(const A &a, const pb_set &b) const
Tests if the element (a,b) or a smaller element is already contained in the antichain.
Definition: antichain.h:116
inclusion_result< Symbol > run()
Run the language inclusion.
Definition: antichain_algo_ind.h:201
void increase_bound(unsigned new_bound)
Incleases the bound of the language inclusion check.
Definition: antichain_algo_ind.h:178
antichain_algo_ind(const AutomatonA &a, const InnerAutomatonB &ib, unsigned initial_bound=2, const Independence &independence=Independence())
Constructor that initialises the language inclusion algorithm.
Definition: antichain_algo_ind.h:160
const printer_base< State > & state_printer() const
Returns a printer for states.
Definition: automaton.h:292
bool is_epsilon(const Symbol &symbol) const
Determines if a symbol should be considered an epsilon transition.
Definition: automaton.h:320
bool included
True if automaton A is included in automaton B.
Definition: results.h:86
bool is_final_state(const State &state) const
This function determines if a specific state is final.
Definition: automaton.h:160
void successors(const State &state, const Symbol &sigma, State_vector &successors1) const
Returns the successor for a specific state.
Definition: automaton.h:201
unsigned get_bound()
Returns the current bound.
Definition: antichain_algo_ind.h:168
const printer_base< Symbol > & symbol_printer() const
Returns a printer for symbols.
Definition: automaton.h:304
unsigned size() const
Returns the size of the antichain.
Definition: antichain.h:132
void initial_states(State_vector &states) const
Returns the initial states.
Definition: automaton.h:167
The antichain algorithm compares two automata for language inclusion module an independence relation...
Definition: antichain_algo_ind.h:67
Automata need to inherit from this class and implement certain methods.
Definition: automaton.h:49
bool bound_hit
Was the bound hit during automata exploration.
Definition: results.h:96
void add(const A &a, const pb_set &b, bool dirty=false)
Add element (a,b) to the antichain.
Definition: antichain.h:92