From 12868528684961d39d9e208e9dbfacd6d28417d2 Mon Sep 17 00:00:00 2001 From: Lukas Holik Date: Fri, 21 Jul 2023 20:24:06 +0200 Subject: [PATCH 1/5] bitching in algorithms.hh --- include/mata/nfa/algorithms.hh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/mata/nfa/algorithms.hh b/include/mata/nfa/algorithms.hh index cf2cd942a..44faa0de4 100644 --- a/include/mata/nfa/algorithms.hh +++ b/include/mata/nfa/algorithms.hh @@ -68,6 +68,8 @@ Nfa complement_classical(const Nfa& aut, const Mata::Util::OrdVector& sy * i.e., if the final intersection of smaller complement of bigger is empty. */ bool is_included_naive(const Nfa& smaller, const Nfa& bigger, const Alphabet* alphabet = nullptr, Run* cex = nullptr); +//naive is not a good word, maybe textbook, or explicit, construct_first +//the alphabet parameter is useless in inclusion /** * Inclusion implemented by antichain algorithms. @@ -79,6 +81,7 @@ bool is_included_naive(const Nfa& smaller, const Nfa& bigger, const Alphabet* al * i.e., if the final intersection of smaller complement of bigger is empty. */ bool is_included_antichains(const Nfa& smaller, const Nfa& bigger, const Alphabet* alphabet = nullptr, Run* cex = nullptr); +//antichains -> antichain. Everywhere here. /** * Universality check implemented by checking emptiness of complemented automaton @@ -88,6 +91,7 @@ bool is_included_antichains(const Nfa& smaller, const Nfa& bigger, const Alphabe * @return True if the complemented automaton has non empty language, i.e., the original one is not universal */ bool is_universal_naive(const Nfa& aut, const Alphabet& alphabet, Run* cex); +//naive -> textbook/explicit /** * Universality checking based on subset construction with antichain. @@ -98,6 +102,21 @@ bool is_universal_naive(const Nfa& aut, const Alphabet& alphabet, Run* cex); */ bool is_universal_antichains(const Nfa& aut, const Alphabet& alphabet, Run* cex); +//the alphabet parameter should be optional? The automaton can have its alphabet too. Run should be optional. +//actually, what about to use this +//struct univ_params +//{ +// const Alphabet* alphabet = NULL, +// Run* cex = NULL, +//}; +// bool is_universal_antichains(const Nfa& aut, univ_params={NULL,NULL}); +// and call as +// bool is_universal_antichains(const Nfa& aut); +// bool is_universal_antichains(const Nfa& aut,{.alphabet = bla}); +// bool is_universal_antichains(const Nfa& aut,{.cex = bli}); +// bool is_universal_antichains(const Nfa& aut,{.alphabet = bla, .cex = bli}); + +//comment missing Simlib::Util::BinaryRelation compute_relation( const Nfa& aut, const StringMap& params = {{"relation", "simulation"}, {"direction", "forward"}}); @@ -112,6 +131,7 @@ Simlib::Util::BinaryRelation compute_relation( * @param[out] prod_map Mapping of pairs of the original states (lhs_state, rhs_state) to new product states. * @return NFA as a product of NFAs @p lhs and @p rhs with ε-transitions preserved. */ +// all parameters needed/used? Nfa intersection_eps(const Nfa& lhs, const Nfa& rhs, bool preserve_epsilon, const std::set& epsilons, std::unordered_map, State> *prod_map = nullptr); @@ -127,6 +147,7 @@ Nfa intersection_eps(const Nfa& lhs, const Nfa& rhs, bool preserve_epsilon, cons * @param[out] rhs_result_states_map Map mapping rhs states to result states. * @return Concatenated automaton. */ +//Are both maps needed? Nfa concatenate_eps(const Nfa& lhs, const Nfa& rhs, const Symbol& epsilon, bool use_epsilon = false, StateToStateMap* lhs_result_states_map = nullptr, StateToStateMap* rhs_result_states_map = nullptr); From b2301cf463682df7b55dfdc1c41eed02ff80576f Mon Sep 17 00:00:00 2001 From: Lukas Holik Date: Fri, 21 Jul 2023 20:31:09 +0200 Subject: [PATCH 2/5] bitching in delta.hh and bulder.hh --- include/mata/nfa/builder.hh | 3 +++ include/mata/nfa/delta.hh | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/include/mata/nfa/builder.hh b/include/mata/nfa/builder.hh index 5193f03de..2cb0291ca 100644 --- a/include/mata/nfa/builder.hh +++ b/include/mata/nfa/builder.hh @@ -17,6 +17,7 @@ namespace Mata::Nfa::Builder { /** * Create an automaton accepting only a single @p word. */ +//should we drop the create_ from all the names? Nfa create_single_word_nfa(const std::vector& word); /** @@ -45,10 +46,12 @@ Nfa create_sigma_star_nfa(Alphabet* alphabet = new OnTheFlyAlphabet{}); /** Loads an automaton from Parsed object */ // TODO this function should the same thing as the one taking IntermediateAut or be deleted Nfa construct(const Mata::Parser::ParsedSection& parsec, Alphabet* alphabet, StringToStateMap* state_map = nullptr); +//construct does not cary much info, what is better? In the comment, don't know what Parsed object is, overall I don't get what this function does. /** Loads an automaton from Parsed object */ Nfa construct(const Mata::IntermediateAut& inter_aut, Alphabet* alphabet, StringToStateMap* state_map = nullptr); +//comment missing template Nfa construct(const ParsedObject& parsed, Mata::StringToSymbolMap* symbol_map = nullptr, StringToStateMap* state_map = nullptr) { diff --git a/include/mata/nfa/delta.hh b/include/mata/nfa/delta.hh index 6f355f62c..268b1b391 100644 --- a/include/mata/nfa/delta.hh +++ b/include/mata/nfa/delta.hh @@ -8,6 +8,19 @@ namespace Mata::Nfa { /** * Structure represents a move which is a symbol and a set of target states of transitions. */ + //HOW TO RENAME STUFF + //delta/coniferation (a set/sequence of cones)/cone + //choice, + //iconary, + //lexicon, + //choice/fan/fanout/cone/fork + //symbolbrach, sourcebranch + //srcbranch, charbranch + //srcfork,symfork,tgtfork + //srctree,symtree + //srctree,symtree,tgttree + //delta,srcpost,sympost + //AND THE WINNER IS: delta, srcpost, sympost. Huraaa class Move { public: Symbol symbol{}; @@ -97,6 +110,10 @@ public: class Delta { private: std::vector posts; + //this internal vector of things is done in a different way in each of the structures, post, delta, move. + //would be nice to make it uniform + //the delta way is the cleanest, no? a private data member + //lets do it that way? public: inline static const Post empty_post; // When posts[q] is not allocated, then delta[q] returns this. @@ -125,6 +142,7 @@ public: // But it feels fragile, before doing something like that, better think and talk to people. Post& get_mutable_post(State q); + //Needs explanation. Maybe refactoring, replacing by several more sensible functions void defragment(const BoolVector& is_staying, const std::vector& renaming); // Get a constant reference to the post of a state. No side effects. @@ -134,6 +152,7 @@ public: void clear() { posts.clear(); } + //Still fishy, what do we mean by size here? Probably should be just the size of the vector. However, below we call it num_of_states. void increase_size(size_t n) { assert(n >= posts.size()); posts.resize(n); @@ -143,9 +162,12 @@ public: * @return Number of states in the whole Delta, including both source and target states. */ size_t num_of_states() const { return posts.size(); } + //should it just be size() ? + void add(State state_from, Symbol symbol, State state_to); void add(const Trans& trans) { add(trans.src, trans.symb, trans.tgt); } + //more add functions below, should be together? void remove(State src, Symbol symb, State tgt); void remove(const Trans& trans) { remove(trans.src, trans.symb, trans.tgt); } @@ -192,6 +214,7 @@ public: /** * Iterator over transitions. It iterates over triples (lhs, symbol, rhs) where lhs and rhs are states. */ + //So this should become the thing discussed, delta.transitions.begin() ..., with internal transition, * will return a const reference to it struct const_iterator { private: const std::vector& post; From e2fa50a91557cf5f7b41cf299e928e9e71ebc535 Mon Sep 17 00:00:00 2001 From: Lukas Holik Date: Fri, 21 Jul 2023 20:42:54 +0200 Subject: [PATCH 3/5] bitching in delta.hh and bulder.hh --- include/mata/nfa/algorithms.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mata/nfa/algorithms.hh b/include/mata/nfa/algorithms.hh index 44faa0de4..f9c3501bf 100644 --- a/include/mata/nfa/algorithms.hh +++ b/include/mata/nfa/algorithms.hh @@ -106,7 +106,7 @@ bool is_universal_antichains(const Nfa& aut, const Alphabet& alphabet, Run* cex) //actually, what about to use this //struct univ_params //{ -// const Alphabet* alphabet = NULL, +// Alphabet* alphabet = NULL, // Run* cex = NULL, //}; // bool is_universal_antichains(const Nfa& aut, univ_params={NULL,NULL}); From 2b071f934c604a90ca71706522637ded1a5c7b04 Mon Sep 17 00:00:00 2001 From: Lukas Holik Date: Fri, 21 Jul 2023 20:45:11 +0200 Subject: [PATCH 4/5] little change --- include/mata/nfa/algorithms.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mata/nfa/algorithms.hh b/include/mata/nfa/algorithms.hh index f9c3501bf..5428db867 100644 --- a/include/mata/nfa/algorithms.hh +++ b/include/mata/nfa/algorithms.hh @@ -103,7 +103,7 @@ bool is_universal_naive(const Nfa& aut, const Alphabet& alphabet, Run* cex); bool is_universal_antichains(const Nfa& aut, const Alphabet& alphabet, Run* cex); //the alphabet parameter should be optional? The automaton can have its alphabet too. Run should be optional. -//actually, what about to use this +//actually, what about to use this, with more optional parameters through structures //struct univ_params //{ // Alphabet* alphabet = NULL, From 0bdfd48dd87377cf539025e884a5236578594c2c Mon Sep 17 00:00:00 2001 From: Lukas Holik Date: Fri, 21 Jul 2023 23:18:52 +0200 Subject: [PATCH 5/5] comments in some more files --- include/mata/nfa/algorithms.hh | 1 + include/mata/nfa/nfa.hh | 35 ++++++++++++++++++++++++++++++++++ src/nfa/operations.cc | 33 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/include/mata/nfa/algorithms.hh b/include/mata/nfa/algorithms.hh index 5428db867..114cf3618 100644 --- a/include/mata/nfa/algorithms.hh +++ b/include/mata/nfa/algorithms.hh @@ -117,6 +117,7 @@ bool is_universal_antichains(const Nfa& aut, const Alphabet& alphabet, Run* cex) // bool is_universal_antichains(const Nfa& aut,{.alphabet = bla, .cex = bli}); //comment missing +//Do we really need this? Simlib::Util::BinaryRelation compute_relation( const Nfa& aut, const StringMap& params = {{"relation", "simulation"}, {"direction", "forward"}}); diff --git a/include/mata/nfa/nfa.hh b/include/mata/nfa/nfa.hh index a07518ccc..d9f89a5e6 100644 --- a/include/mata/nfa/nfa.hh +++ b/include/mata/nfa/nfa.hh @@ -106,18 +106,21 @@ public: /** * Clear transitions but keep the automata states. */ + //method of delta? void clear_transitions(); /** * Add a new (fresh) state to the automaton. * @return The newly created state. */ + //obsolete? State add_state(); /** * Add state @p state to @c delta if @p state is not in @c delta yet. * @return The requested @p state. */ + //obsolete? State add_state(State state); /** @@ -126,6 +129,7 @@ public: * This includes the initial and final states as well as states in the transition relation. * @return The number of states. */ + //rename, again, to num_of_states? size_t size() const; /** @@ -145,6 +149,7 @@ public: * * The whole NFA is cleared, each member is set to its zero value. */ + //used? void clear(); /** @@ -165,6 +170,8 @@ public: */ Util::OrdVector get_used_symbols() const; + //this is to be debordelized, the variants were here just to play with data structures + //should be a method of delta Mata::Util::OrdVector get_used_symbols_vec() const; std::set get_used_symbols_set() const; Mata::Util::SparseSet get_used_symbols_sps() const; @@ -201,6 +208,7 @@ public: * @return Set of useful states. * TODO: with the new get_useful_states, we can delete this probably. */ + //keep just the new one StateSet get_useful_states_old() const; BoolVector get_useful_states() const; @@ -215,6 +223,7 @@ public: * @param[out] state_map Mapping of trimmed states to new states. * TODO: we can probably keep just trim_reverting, much faster. But the speed difference and how it is achieved is interesting. Keeping as a demonstration for now. */ + //to be compared on some good data void trim_inplace(StateToStateMap* state_map = nullptr); void trim_reverting(StateToStateMap* state_map = nullptr); void trim(StateToStateMap* state_map = nullptr) { trim_inplace(state_map); } @@ -246,12 +255,14 @@ public: * * The operation has constant time complexity. */ + //remove get_ ? size_t get_num_of_trans() const { return static_cast(std::distance(delta.begin(), delta.end())); } /** * Get transitions as a sequence of @c Trans. * @return Sequence of transitions as @c Trans. */ + //this will become obsolete, we will have iterators in delta TransSequence get_trans_as_sequence() const; /** @@ -259,6 +270,7 @@ public: * @param state_from[in] Source state_from of transitions to get. * @return Sequence of transitions as @c Trans from @p state_from. */ + //this will become obsolete, we will have iterators in delta TransSequence get_trans_from_as_sequence(State state_from) const; /** @@ -269,6 +281,7 @@ public: * @param state_from[in] Source state for transitions to get. * @return List of transitions leading from @p state_from. */ + //this will become obsolete, we will have iterators in delta const Post& get_moves_from(const State state_from) const { assert(state_from < size()); return delta[state_from]; @@ -280,6 +293,7 @@ public: * @return Sequence of @c Trans transitions leading to @p state_to. * (!slow!, traverses the entire delta) */ + //this function somehow does not fit with the planned iterator interface, but I don't know what to do TransSequence get_transitions_to(State state_to) const; /** @@ -287,6 +301,7 @@ public: * @param[in] abstract_symbol Abstract symbol to use for transitions in digraph. * @return An automaton representing a directed graph. */ + //why the get_ everywhere? Nfa get_one_letter_aut(Symbol abstract_symbol = 'x') const; /** @@ -338,6 +353,7 @@ public: void print_to_mata(std::ostream &output) const; // TODO: Relict from VATA. What to do with inclusion/ universality/ this post function? Revise all of them. + // One usage in universality, should disappear and this function should be removed. StateSet post(const StateSet& states, const Symbol& symbol) const; struct const_iterator { @@ -374,6 +390,7 @@ public: * @return Returns reference element of transition list with epsilon transitions or end of transition list when * there are no epsilon transitions. */ + //These things should be methods of delta? Post::const_iterator get_epsilon_transitions(State state, Symbol epsilon = EPSILON) const; /** @@ -383,6 +400,7 @@ public: * @return Returns reference element of transition list with epsilon transitions or end of transition list when * there are no epsilon transitions. */ + //These things should be methods of delta? static Post::const_iterator get_epsilon_transitions(const Post& post, Symbol epsilon = EPSILON); /** @@ -390,6 +408,7 @@ public: * * The value of the already existing symbols will NOT be overwritten. */ + //A method of delta as well? void add_symbols_to(OnTheFlyAlphabet& target_alphabet) const; }; // struct Nfa. @@ -398,9 +417,11 @@ public: * @param[in] nfa NFA with symbols to fill @p alphabet with. * @param[out] alphabet Alphabet to be filled with symbols from @p nfa. */ + //A method of delta as well? void fill_alphabet(const Mata::Nfa::Nfa& nfa, Mata::OnTheFlyAlphabet& alphabet); // Adapted from: https://www.fluentcpp.com/2019/01/25/variadic-number-function-parameters-type/. +//Please explain in a comment here what this is. template struct bool_pack{}; /// Checks for all types in the pack. template using conjunction = std::is_same, bool_pack>; @@ -413,6 +434,7 @@ template using AreAllNfas = typename conjunction> inline OnTheFlyAlphabet create_alphabet(const Nfas&... nfas) { Mata::OnTheFlyAlphabet alphabet{}; @@ -428,6 +450,7 @@ inline OnTheFlyAlphabet create_alphabet(const Nfas&... nfas) { * @param[in] nfas Vector of NFAs to create alphabet from. * @return Created alphabet. */ + //We are to refactor alphabets, right? OnTheFlyAlphabet create_alphabet(const ConstAutRefSequence& nfas); /** @@ -449,6 +472,7 @@ OnTheFlyAlphabet create_alphabet(const ConstAutPtrSequence& nfas); * @param[in] nfas Vector of pointers to NFAs to create alphabet from. * @return Created alphabet. */ + //Do we need all the variants? If yes, can we have one with iterators, or a template? OnTheFlyAlphabet create_alphabet(const AutPtrSequence& nfas); /// Do the automata have disjoint sets of states? @@ -460,8 +484,10 @@ bool are_state_disjoint(const Nfa& lhs, const Nfa& rhs); * @param[out] cex Counter-example path for a case the language is not empty. * @return True if the language is empty, false otherwise. */ + //should be a method? bool is_lang_empty(const Nfa& aut, Run* cex = nullptr); +//could be in-place method Nfa uni(const Nfa &lhs, const Nfa &rhs); /** @@ -482,6 +508,8 @@ Nfa uni(const Nfa &lhs, const Nfa &rhs); * @param[out] prod_map Mapping of pairs of the original states (lhs_state, rhs_state) to new product states. * @return NFA as a product of NFAs @p lhs and @p rhs with ε-transitions preserved. */ + +//preserve_epsilon optional too? Do we need both options? Nfa intersection(const Nfa& lhs, const Nfa& rhs, bool preserve_epsilon = false, std::unordered_map, State> *prod_map = nullptr); @@ -497,6 +525,7 @@ Nfa intersection(const Nfa& lhs, const Nfa& rhs, * @return Concatenated automaton. */ // TODO: check how fast is using just concatenate over epsilon and then call remove_epsilon(). +// choice of optional parameters using structure? Nfa concatenate(const Nfa& lhs, const Nfa& rhs, bool use_epsilon = false, StateToStateMap* lhs_result_states_map = nullptr, StateToStateMap* rhs_result_states_map = nullptr); @@ -513,6 +542,8 @@ Nfa concatenate(const Nfa& lhs, const Nfa& rhs, bool use_epsilon = false, * @param[in] sink_state The state into which new transitions are added. * @return True if some new transition was added to the automaton. */ + //method complete + //alphabet optional, sink stata too? bool make_complete(Nfa& aut, const Alphabet& alphabet, State sink_state); /** @@ -532,6 +563,7 @@ bool make_complete(Nfa& aut, const Alphabet& alphabet, State sink_state); * @param[in] sink_state The state into which new transitions are added. * @return True if some new transition was added to the automaton. */ + //eventually only one variant, the version with the optional alphabet (some enum alphabet type) ? bool make_complete(Nfa& aut, const Util::OrdVector& symbols, State sink_state); /** @@ -555,6 +587,7 @@ inline bool make_complete(Nfa& aut, const Alphabet& alphabet) { return make_comp * - "minimize": "true"/"false" (whether to compute minimal deterministic automaton for classical algorithm); * @return Complemented automaton. */ + //method Nfa complement(const Nfa& aut, const Alphabet& alphabet, const StringMap& params = {{"algorithm", "classical"}, {"minimize", "false"}}); @@ -573,6 +606,7 @@ Nfa complement(const Nfa& aut, const Alphabet& alphabet, * - "minimize": "true"/"false" (whether to compute minimal deterministic automaton for classical algorithm); * @return Complemented automaton. */ +//Do we need this? How many algorithms do we have? If yes, maybe these syntactic sugar functions could really have their own file. Nfa complement(const Nfa& aut, const Util::OrdVector& symbols, const StringMap& params = {{"algorithm", "classical"}, {"minimize", "false"}}); @@ -741,6 +775,7 @@ Run encode_word(const StringToSymbolMap& symbol_map, const std::vector struct hash { inline size_t operator()(const Mata::Nfa::Trans& trans) const { diff --git a/src/nfa/operations.cc b/src/nfa/operations.cc index c35b04757..74b70e39b 100644 --- a/src/nfa/operations.cc +++ b/src/nfa/operations.cc @@ -15,6 +15,9 @@ * GNU General Public License for more details. */ +//is it good that header file names don't match cc files? What is the system actually? Is there a difference between operations and algorithms? +//Generally, a comment on what the file is for would be good everywhere. + #include #include #include @@ -34,9 +37,14 @@ using namespace Mata::Nfa; using Mata::Symbol; using Mata::BoolVector; +// Vector of bool is probably slower than vector of char (from some little experiment). +// Just BoolArray would be better? +// It would make sense to make this type name global, it is type that we use globally to represent bool vectors. ? using StateBoolArray = std::vector; ///< Bool array for states in the automaton. namespace { + //Remove direct_, there are no close alternatives for NFA (unlike for Buchi). Remove "compute_" ? + //Is this declared in a header file? Can't find. Simlib::Util::BinaryRelation compute_fw_direct_simulation(const Nfa& aut) { Symbol maxSymbol = 0; const size_t state_num = aut.size(); @@ -58,6 +66,9 @@ namespace { return LTSforSimulation.compute_simulation(); } + //Something shorter? like simulation_quotient? + //State_map could be optional? + //Also some comments needed here. Nfa reduce_size_by_simulation(const Nfa& aut, StateToStateMap &state_map) { Nfa result; const auto sim_relation = Algorithms::compute_relation( @@ -179,10 +190,13 @@ bool Mata::Nfa::are_state_disjoint(const Nfa& lhs, const Nfa& rhs) return true; } // are_disjoint }}} +//Should be in-place method? I would still name it complete, it is a verb too. +//Alphabet should be optional, the automaton has an alphabet that would be used implicitly. bool Mata::Nfa::make_complete(Nfa& aut, const Alphabet& alphabet, State sink_state) { return Mata::Nfa::make_complete(aut, alphabet.get_alphabet_symbols(), sink_state); } +//It is weird to have two finctions like this. Perhaps after we have alphabets finished, we could just pass an alphabet. bool Mata::Nfa::make_complete(Nfa& aut, const Mata::Util::OrdVector& symbols, State sink_state) { bool was_something_added{ false }; @@ -209,6 +223,7 @@ bool Mata::Nfa::make_complete(Nfa& aut, const Mata::Util::OrdVector& sym } //TODO: based on the comments inside, this function needs to be rewritten in a more optimal way. +//Should it take an optional set of epsilons as a parameter? Nfa Mata::Nfa::remove_epsilon(const Nfa& aut, Symbol epsilon) { // cannot use multimap, because it can contain multiple occurrences of (a -> a), (a -> a) std::unordered_map eps_closure; @@ -270,6 +285,7 @@ Nfa Mata::Nfa::remove_epsilon(const Nfa& aut, Symbol epsilon) { return result; } +//TODO: experiment with reverts and chose which should survive Nfa Mata::Nfa::fragile_revert(const Nfa& aut) { const size_t num_of_states{ aut.size() }; @@ -288,6 +304,8 @@ Nfa Mata::Nfa::fragile_revert(const Nfa& aut) { // size of the "used alphabet", i.e. max symbol+1 or 0 Symbol alphasize = (symbols.empty()) ? 0 : (symbols.back()+1); + + //let's remove the static structures #ifdef _STATIC_STRUCTURES_ //STATIC DATA STRUCTURES: // Not sure that it works ideally, whether the space for the inner vectors stays there. @@ -460,6 +478,7 @@ Nfa Mata::Nfa::revert(const Nfa& aut) { //return somewhat_simple_revert(aut); } +//method? bool Mata::Nfa::is_deterministic(const Nfa& aut) { if (aut.initial.size() != 1) { return false; } @@ -477,6 +496,8 @@ bool Mata::Nfa::is_deterministic(const Nfa& aut) return true; } + +//method? bool Mata::Nfa::is_complete(const Nfa& aut, const Alphabet& alphabet) { Util::OrdVector symbs_ls = alphabet.get_alphabet_symbols(); @@ -517,6 +538,8 @@ bool Mata::Nfa::is_complete(const Nfa& aut, const Alphabet& alphabet) return true; } +//remove get_ ? path -> run? Strange, word is a part of Run, why to ask the automaton and call this function then? +//Maybe something strange happened since we introduced the Run data type? std::pair Mata::Nfa::get_word_for_path(const Nfa& aut, const Run& run) { if (run.path.empty()) @@ -558,6 +581,7 @@ std::pair Mata::Nfa::get_word_for_path(const Nfa& aut, const Run& run } //TODO: this is not efficient +//method? bool Mata::Nfa::is_in_lang(const Nfa& aut, const Run& run) { StateSet cur(aut.initial); @@ -573,6 +597,7 @@ bool Mata::Nfa::is_in_lang(const Nfa& aut, const Run& run) /// Checks whether the prefix of a string is in the language of an automaton // TODO: slow and it should share code with is_in_lang +//method? bool Mata::Nfa::is_prfx_in_lang(const Nfa& aut, const Run& run) { StateSet cur = StateSet{ aut.initial }; @@ -597,6 +622,7 @@ Mata::Parser::ParsedSection Mata::Nfa::serialize( return {}; } +//method? bool Mata::Nfa::is_lang_empty(const Nfa& aut, Run* cex) { // {{{ std::list worklist( @@ -664,11 +690,13 @@ bool Mata::Nfa::is_lang_empty(const Nfa& aut, Run* cex) } // is_lang_empty }}} +//method? Nfa Mata::Nfa::Algorithms::minimize_brzozowski(const Nfa& aut) { //compute the minimal deterministic automaton, Brzozovski algorithm return determinize(revert(determinize(revert(aut)))); } +//method? Nfa Mata::Nfa::minimize( const Nfa& aut, const StringMap& params) @@ -692,6 +720,7 @@ Nfa Mata::Nfa::minimize( return algo(aut); } +//could be a method that does it in-place (modifies the object on which it is called)? Nfa Mata::Nfa::uni(const Nfa &lhs, const Nfa &rhs) { Nfa unionAutomaton = rhs; @@ -749,6 +778,7 @@ Simlib::Util::BinaryRelation Mata::Nfa::Algorithms::compute_relation(const Nfa& } } +//All these parameters are making this a monster. state_map optional, params too (or remove), kick out trim_input and don't trim. Nfa Mata::Nfa::reduce(const Nfa &aut, bool trim_input, StateToStateMap *state_map, const StringMap& params) { if (!haskey(params, "algorithm")) { throw std::runtime_error(std::to_string(__func__) + @@ -789,6 +819,7 @@ Nfa Mata::Nfa::reduce(const Nfa &aut, bool trim_input, StateToStateMap *state_ma return result; } +//Might be a method, but it will not be in-place anyway, so I don't know. Nfa Mata::Nfa::determinize( const Nfa& aut, std::unordered_map *subset_map) @@ -874,6 +905,8 @@ std::ostream& std::operator<<(std::ostream& os, const Mata::Nfa::Nfa& nfa) { return os; } +//Are the following functions for alphabets there to stay or to be refacvtored together with alphabets? + void Mata::Nfa::fill_alphabet(const Mata::Nfa::Nfa& nfa, OnTheFlyAlphabet& alphabet) { const size_t nfa_num_of_states{ nfa.size() }; for (Mata::Nfa::State state{ 0 }; state < nfa_num_of_states; ++state) {