|
8 | 8 | using namespace mata::nft; |
9 | 9 | using namespace mata::utils; |
10 | 10 |
|
11 | | -#ifdef MATA_NFT_NOT_IMPLEMENTED |
12 | | -Nft mata::nft::algorithms::complement_classical(const Nft& aut, const OrdVector<Symbol>& symbols, |
13 | | - const bool minimize_during_determinization) { |
| 11 | +Nft algorithms::complement_classical( |
| 12 | + const Nft& aut, const OrdVector<Symbol>& symbols, const OrdVector<Symbol>& epsilons, |
| 13 | + const bool minimize_during_determinization) { |
14 | 14 | Nft result; |
15 | | - State sink_state; |
16 | 15 | if (minimize_during_determinization) { |
17 | | - result = minimize_brzozowski(aut); // brzozowski minimization makes it deterministic |
18 | | - if (result.final.empty() && !result.initial.empty()) { |
19 | | - assert(result.initial.size() == 1); |
20 | | - // if automaton does not accept anything, then there is only one (initial) state |
21 | | - // which can be the sink state (so we do not create unnecessary one) |
22 | | - sink_state = *result.initial.begin(); |
23 | | - } else { |
24 | | - sink_state = result.num_of_states(); |
25 | | - } |
26 | | - } else { |
27 | | - std::unordered_map<StateSet, State> subset_map; |
28 | | - result = determinize(aut, &subset_map); |
29 | | - // check if a sink state was not created during determinization |
30 | | - if (const auto sink_state_iter = subset_map.find({}); sink_state_iter != subset_map.end()) { |
31 | | - sink_state = sink_state_iter->second; |
32 | | - } else { |
33 | | - sink_state = result.num_of_states(); |
34 | | - } |
35 | | - } |
36 | | - |
37 | | - result.make_complete(symbols, sink_state); |
38 | | - result.final.complement(result.num_of_states()); |
| 16 | + throw std::runtime_error( |
| 17 | + std::string(__func__) + |
| 18 | + ": unimplemented option 'minimize' = 'true' for the complementation algorithm on NFTs." |
| 19 | + ); |
| 20 | + // TODO(nft): implement minimization for NFTs. |
| 21 | + // result = determinize_and_minimize(aut); |
| 22 | + // result = minimize_brzozowski(aut); // brzozowski minimization makes it deterministic |
| 23 | + // if (result.final.empty() && !result.initial.empty()) { |
| 24 | + // assert(result.initial.size() == 1); |
| 25 | + // // if automaton does not accept anything, then there is only one (initial) state |
| 26 | + // // which can be the sink state (so we do not create unnecessary one) |
| 27 | + // sink_state = *result.initial.begin(); |
| 28 | + // } else { |
| 29 | + // sink_state = result.num_of_states(); |
| 30 | + // } |
| 31 | + } else { result = determinize(aut); } |
39 | 32 |
|
| 33 | + result.make_complete(symbols, epsilons); |
| 34 | + // TODO(nft): Should empty nft produce a complement with one initial and final state accepting { {epsilon}, {epsilon}, {epsilon} }? |
| 35 | + if (result.initial.empty()) { |
| 36 | + const State initial{ result.add_state() }; |
| 37 | + result.initial.insert(initial); |
| 38 | + } |
| 39 | + SparseSet<State> new_final_states{}; |
| 40 | + const size_t num_of_states{ result.num_of_states() }; |
| 41 | + for (State state{ 0 }; state < num_of_states; ++state) { |
| 42 | + if (result.levels[state] == 0 && !result.final.contains(state)) { new_final_states.insert(state); } |
| 43 | + } |
| 44 | + result.final = new_final_states; |
40 | 45 | return result; |
41 | 46 | } |
42 | 47 |
|
43 | | -Nft mata::nft::complement(const Nft& aut, const Alphabet& alphabet, const ParameterMap& params) { |
44 | | - return mata::nft::complement(aut, alphabet.get_alphabet_symbols(), params); |
| 48 | +Nft mata::nft::complement(const Nft& nft, const Alphabet& alphabet, const OrdVector<Symbol>& epsilons, const ParameterMap& params) { |
| 49 | + return complement(nft, alphabet.get_alphabet_symbols(), epsilons, params); |
45 | 50 | } |
46 | 51 |
|
47 | | -Nft mata::nft::complement(const Nft& aut, const mata::utils::OrdVector<mata::Symbol>& symbols, const ParameterMap& params) { |
48 | | - Nft result; |
| 52 | +Nft mata::nft::complement(const Nft& nft, const OrdVector<Symbol>& symbols, const OrdVector<Symbol>& epsilons, const ParameterMap& params) { |
49 | 53 | // Setting the requested algorithm. |
50 | 54 | decltype(algorithms::complement_classical)* algo = algorithms::complement_classical; |
51 | 55 | if (!haskey(params, "algorithm")) { |
52 | | - throw std::runtime_error(std::to_string(__func__) + |
53 | | - " requires setting the \"algorithm\" key in the \"params\" argument; " |
54 | | - "received: " + std::to_string(params)); |
| 56 | + throw std::runtime_error( |
| 57 | + std::to_string(__func__) + |
| 58 | + " requires setting the 'algorithm' key in the 'params' argument; " |
| 59 | + "received: " + std::to_string(params) |
| 60 | + ); |
55 | 61 | } |
56 | 62 |
|
57 | 63 | const std::string& str_algo = params.at("algorithm"); |
58 | | - if ("classical" == str_algo) { /* default */ } |
59 | | - else { |
60 | | - throw std::runtime_error(std::to_string(__func__) + |
61 | | - " received an unknown value of the \"algorithm\" key: " + str_algo); |
| 64 | + if ("classical" == str_algo) { /* default */ } else { |
| 65 | + throw std::runtime_error( |
| 66 | + std::to_string(__func__) + |
| 67 | + " received an unknown value of the 'algorithm' key: " + str_algo |
| 68 | + ); |
62 | 69 | } |
63 | 70 |
|
64 | | - bool minimize_during_determinization = false; |
| 71 | + bool minimize_during_determinization{ false }; |
65 | 72 | if (params.contains("minimize")) { |
66 | | - const std::string& minimize_arg = params.at("minimize"); |
67 | | - if ("true" == minimize_arg) { minimize_during_determinization = true; } |
68 | | - else if ("false" == minimize_arg) { minimize_during_determinization = false; } |
69 | | - else { |
70 | | - throw std::runtime_error(std::to_string(__func__) + |
71 | | - " received an unknown value of the \"minimize\" key: " + str_algo); |
| 73 | + if (const std::string& minimize_arg = params.at("minimize"); |
| 74 | + "true" == minimize_arg) { |
| 75 | + throw std::runtime_error( |
| 76 | + std::to_string(__func__) + |
| 77 | + " received unimplemented option 'minimize' = 'true' for the complementation algorithm on NFTs." |
| 78 | + ); |
| 79 | + // TODO(nft): implement minimization for NFTs. |
| 80 | + // minimize_during_determinization = true; |
| 81 | + } else if ("false" == minimize_arg) { minimize_during_determinization = false; } else { |
| 82 | + throw std::runtime_error( |
| 83 | + std::to_string(__func__) + " received an unknown value of the 'minimize' key: " + minimize_arg |
| 84 | + ); |
72 | 85 | } |
73 | 86 | } |
74 | | - |
75 | | - return algo(aut, symbols, minimize_during_determinization); |
| 87 | + return algo(nft, symbols, epsilons, minimize_during_determinization); |
76 | 88 | } |
77 | | -#endif |
|
0 commit comments