Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove unused import #383

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9938c15
lvlfa as a duplicate of nfa
koniksedy Feb 7, 2024
465dbea
lvlfa builder done
koniksedy Feb 8, 2024
931dfc2
make_one_level nontested
koniksedy Feb 12, 2024
8a78b89
Improve levels description
Adda0 Feb 14, 2024
7f5757a
Create identity NFT
Adda0 Feb 14, 2024
c546f82
Add moves wherever possible
Adda0 Feb 14, 2024
ac88810
Create identity with single replace
Adda0 Feb 14, 2024
6ba4248
Rename 'lvlfa' to 'nft'
Adda0 Feb 14, 2024
94794dd
Create NFT from NFA
Adda0 Feb 15, 2024
da1fc07
Check number of levels in equivalence checking
Adda0 Feb 15, 2024
a0fdefb
Implement end marker DFT for reluctant replacement
Adda0 Feb 15, 2024
be4f2f9
Move NFT string solving function into their own namespace
Adda0 Feb 15, 2024
cb7cebd
Create generic end marker DFT
Adda0 Feb 16, 2024
e07c1c2
Generalize end_marker_dft() for general marker DFTconstruction
Adda0 Feb 19, 2024
28b00f3
Rename functions
Adda0 Feb 19, 2024
5ab7569
Construct begin marker DFT
Adda0 Feb 19, 2024
c7b3f0d
Rename `dft` to `nft` where creating DFT is not guaranteed
Adda0 Feb 19, 2024
e75e7f1
nft::are_quivalent implemented using the method get_one_level_aut
koniksedy Feb 19, 2024
08ee399
nft::algorithms::is_included_antichains implemented using the method …
koniksedy Feb 19, 2024
b672b4e
default level set to 1; levels size synchronized with delta
koniksedy Feb 20, 2024
b9360f2
levels initialization fixed
koniksedy Feb 20, 2024
702c475
Merge pull request #379 from VeriFIT/nft-inclusion
Adda0 Feb 20, 2024
5191aab
Apply resize() levels instead of push_back() only when needed
Adda0 Feb 21, 2024
f7223db
Allow adding new states with levels
Adda0 Feb 21, 2024
156811a
Merge pull request #382 from Adda0/add_state_resize
koniksedy Feb 21, 2024
2fd87d3
Remove unused import
Adda0 Feb 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion include/mata/alphabet.hh
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,13 @@ public:

bool operator==(const Alphabet &) const = delete;

/**
* Checks whether the alphabet has any symbols.
*/
virtual bool empty() const = 0;

protected:
virtual const void *address() const { return this; }
virtual const void* address() const { return this; }
}; // class Alphabet.

/**
Expand Down Expand Up @@ -115,6 +120,8 @@ public:

IntAlphabet& operator=(const IntAlphabet& int_alphabet) = delete;

bool empty() const override { return false; }

protected:
const void* address() const override { return &alphabet_instance; }

Expand Down Expand Up @@ -234,6 +241,8 @@ public:
*/
size_t get_number_of_symbols() const { return symbols_.size(); }

bool empty() const override { return symbols_.empty(); }

private:
mata::utils::OrdVector<Symbol> symbols_{}; ///< Map of string transition symbols to symbol values.
Symbol next_symbol_value_{ 0 }; ///< Next value to be used for a newly added symbol.
Expand Down Expand Up @@ -362,6 +371,8 @@ public:
*/
const StringToSymbolMap& get_symbol_map() const { return symbol_map_; }

bool empty() const override { return symbol_map_.empty(); }

private:
StringToSymbolMap symbol_map_{}; ///< Map of string transition symbols to symbol values.
Symbol next_symbol_value_{}; ///< Next value to be used for a newly added symbol.
Expand Down
1 change: 1 addition & 0 deletions include/mata/nfa/delta.hh
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public:
// dangerous, breaks the sortedness invariant
using super::push_back;
// is adding non-const version as well ok?
using super::front;
using super::back;
using super::filter;

Expand Down
14 changes: 7 additions & 7 deletions include/mata/nfa/nfa.hh
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public:
BoolVector get_useful_states() const;

/**
* @brief Structure for storing callback functions (event handlers) utilizing
* @brief Structure for storing callback functions (event handlers) utilizing
* Tarjan's SCC discover algorithm.
*/
struct TarjanDiscoverCallback {
Expand All @@ -182,7 +182,7 @@ public:

/**
* @brief Tarjan's SCC discover algorihm.
*
*
* @param callback Callbacks class to instantiate callbacks for the Tarjan's algorithm.
*/
void tarjan_scc_discover(const TarjanDiscoverCallback& callback) const;
Expand Down Expand Up @@ -275,16 +275,16 @@ public:
StateSet post(const StateSet& states, const Symbol& symbol) const;

/**
* Check whether the language of NFA is empty.
* Currently calls is_lang_empty_scc if cex is null
* Check whether the language of NFA is empty.
* Currently calls is_lang_empty_scc if cex is null
* @param[out] cex Counter-example path for a case the language is not empty.
* @return True if the language is empty, false otherwise.
*/
bool is_lang_empty(Run* cex = nullptr) const;

/**
* @brief Check if the language is empty using Tarjan's SCC discover algorithm.
*
*
* @return Language empty <-> True
*/
bool is_lang_empty_scc() const;
Expand All @@ -307,7 +307,7 @@ public:

/**
* @brief Is the automaton graph acyclic? Used for checking language finiteness.
*
*
* @return true <-> Automaton graph is acyclic.
*/
bool is_acyclic() const;
Expand Down Expand Up @@ -337,7 +337,7 @@ public:

/**
* @brief Get the set of all words in the language of the automaton whose length is <= @p max_length
*
*
* If you have an automaton with finite language (can be checked using @ref is_acyclic),
* you can get all words by calling
* get_words(aut.num_of_states())
Expand Down
125 changes: 125 additions & 0 deletions include/mata/nft/algorithms.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* algorithms.hh -- Wrapping up algorithms for Nft manipulation which would be otherwise in anonymous namespaces.
*/

#ifndef MATA_NFT_INTERNALS_HH_
#define MATA_NFT_INTERNALS_HH_

#include "nft.hh"
#include "mata/simlib/util/binary_relation.hh"

/**
* Concrete NFT implementations of algorithms, such as complement, inclusion, or universality checking.
*
* This is a separation of the implementation from the interface defined in mata::nft.
* Note, that in mata::nft interface, there are particular dispatch functions calling
* these function according to parameters provided by a user.
* E.g. we can call the following function: `is_universal(aut, alph, {{'algorithm', 'antichains'}})`
* to check for universality based on antichain-based algorithm.
*
* In particular, this includes algorithms for:
* 1. Complementation,
* 2. Inclusion,
* 3. Universality checking,
* 4. Intersection/concatenation with epsilon transitions, or,
* 5. Computing relation.
*/
namespace mata::nft::algorithms {

/**
* Brzozowski minimization of automata (revert -> determinize -> revert -> determinize).
* @param[in] aut Automaton to be minimized.
* @return Minimized automaton.
*/
Nft minimize_brzozowski(const Nft& aut);

/**
* Complement implemented by determization, adding sink state and making automaton complete. Then it adds final states
* which were non final in the original automaton.
* @param[in] aut Automaton to be complemented.
* @param[in] symbols Symbols needed to make the automaton complete.
* @param[in] minimize_during_determinization Whether the determinized automaton is computed by (brzozowski)
* minimization.
* @return Complemented automaton.
*/
Nft complement_classical(const Nft& aut, const mata::utils::OrdVector<Symbol>& symbols,
bool minimize_during_determinization = false);

/**
* Inclusion implemented by complementation of bigger automaton, intersecting it with smaller and then it checks
* emptiness of intersection.
* @param[in] smaller Automaton which language should be included in the bigger one.
* @param[in] bigger Automaton which language should include the smaller one.
* @param[in] alphabet Alphabet of both automata (it is computed automatically, but it is more efficient to set it if
* you have it).
* @param[out] cex A potential counterexample word which breaks inclusion
* @return True if smaller language is included,
* i.e., if the final intersection of smaller complement of bigger is empty.
*/
bool is_included_naive(const Nft& smaller, const Nft& bigger, const Alphabet* alphabet = nullptr, Run* cex = nullptr);

/**
* Inclusion implemented by antichain algorithms.
* @param[in] smaller Automaton which language should be included in the bigger one
* @param[in] bigger Automaton which language should include the smaller one
* @param[in] alphabet Alphabet of both automata (not needed for antichain algorithm)
* @param[out] cex A potential counterexample word which breaks inclusion
* @return True if smaller language is included,
* i.e., if the final intersection of smaller complement of bigger is empty.
*/
bool is_included_antichains(const Nft& smaller, const Nft& bigger, const Alphabet* alphabet = nullptr, Run* cex = nullptr);

/**
* Universality check implemented by checking emptiness of complemented automaton
* @param[in] aut Automaton which universality is checked
* @param[in] alphabet Alphabet of the automaton
* @param[out] cex Counterexample word which eventually breaks the universality
* @return True if the complemented automaton has non empty language, i.e., the original one is not universal
*/
bool is_universal_naive(const Nft& aut, const Alphabet& alphabet, Run* cex);

/**
* Universality checking based on subset construction with antichain.
* @param[in] aut Automaton which universality is checked
* @param[in] alphabet Alphabet of the automaton
* @param[out] cex Counterexample word which eventually breaks the universality
* @return True if the automaton is universal, otherwise false.
*/
bool is_universal_antichains(const Nft& aut, const Alphabet& alphabet, Run* cex);

Simlib::Util::BinaryRelation compute_relation(
const Nft& aut,
const ParameterMap& params = {{ "relation", "simulation"}, { "direction", "forward"}});

/**
* @brief Compute product of two NFTs, final condition is to be specified, with a possibility of using multiple epsilons.
*
* @param[in] lhs First NFT to compute intersection for.
* @param[in] rhs Second NFT to compute intersection for.
* @param[in] first_epsilons The smallest epsilon.
* @param[in] final_condition The predicate that tells whether a pair of states is final (conjunction for intersection).
* @param[out] prod_map Can be used to get the mapping of the pairs of the original states to product states.
* Mostly useless, it is only filled in and returned if !=nullptr, but the algorithm internally uses another data structures,
* because this one is too slow.
* @return NFT as a product of NFTs @p lhs and @p rhs with ε-transitions preserved.
*/
Nft product(const Nft& lhs, const Nft& rhs, const std::function<bool(State,State)> && final_condition,
const Symbol first_epsilon = EPSILON, std::unordered_map<std::pair<State,State>, State> *prod_map = nullptr);

/**
* @brief Concatenate two NFTs.
*
* Supports epsilon symbols when @p use_epsilon is set to true.
* @param[in] lhs First automaton to concatenate.
* @param[in] rhs Second automaton to concatenate.
* @param[in] epsilon Epsilon to be used co concatenation (provided @p use_epsilon is true)
* @param[in] use_epsilon Whether to concatenate over epsilon symbol.
* @param[out] lhs_state_renaming Map mapping lhs states to result states.
* @param[out] rhs_state_renaming Map mapping rhs states to result states.
* @return Concatenated automaton.
*/
Nft concatenate_eps(const Nft& lhs, const Nft& rhs, const Symbol& epsilon, bool use_epsilon = false,
StateRenaming* lhs_state_renaming = nullptr, StateRenaming* rhs_state_renaming = nullptr);

} // Namespace mata::nft::algorithms.

#endif // MATA_NFT_INTERNALS_HH_
110 changes: 110 additions & 0 deletions include/mata/nft/builder.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// TODO: Insert file header.

#ifndef LIBMATA_NFT_BUILDER_HH
#define LIBMATA_NFT_BUILDER_HH

#include "mata/nfa/builder.hh"
#include "nft.hh"

#include <filesystem>

/**
* Namespace providing options to build NFAs.
*/
namespace mata::nft::builder {

using namespace mata::nft;

using NameStateMap = std::unordered_map<std::string, State>;

/**
* Create an automaton accepting only a single @p word.
*/
Nft create_single_word_nft(const std::vector<Symbol>& word);

/**
* Create an automaton accepting only a single @p word.
*
* @param word Word to accept.
* @param alphabet Alphabet to use in NFA for translating word into symbols. If specified, the alphabet has to contain
* translations for all of the word symbols. If left empty, a new alphabet with only the symbols of the word will be
* created.
*/
Nft create_single_word_nft(const std::vector<std::string>& word, Alphabet* alphabet = nullptr);

/**
* Create automaton accepting only epsilon string.
*/
Nft create_empty_string_nft();

/**
* Create automaton accepting sigma star over the passed alphabet using DONT_CARE symbol.
*/
Nft create_sigma_star_nft();

/**
* Create automaton accepting sigma star over the passed alphabet.
*
* @param[in] alphabet Alphabet to construct sigma star automaton with. When alphabet is left empty, the default empty
* alphabet is used, creating an automaton accepting only the empty string.
*/
Nft create_sigma_star_nft(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
Nft construct(const mata::parser::ParsedSection& parsec, Alphabet* alphabet, NameStateMap* state_map = nullptr);

/** Loads an automaton from Parsed object */
Nft construct(const mata::IntermediateAut& inter_aut, Alphabet* alphabet, NameStateMap* state_map = nullptr);
/** Loads an automaton from Parsed object; version for python binding */
void construct(
Nft* result, const mata::IntermediateAut& inter_aut, Alphabet* alphabet, NameStateMap* state_map = nullptr
);

template<class ParsedObject>
Nft construct(const ParsedObject& parsed, Alphabet* alphabet = nullptr,
NameStateMap* state_map = nullptr) {
OnTheFlyAlphabet tmp_alphabet{};
if (!alphabet) {
alphabet = &tmp_alphabet;
}
return construct(parsed, alphabet, state_map);
} // construct().

/**
* Parse NFA from the mata format in an input stream.
*
* @param nft_stream Input stream containing NFA in mata format.
* @throws std::runtime_error Parsing of NFA fails.
*/
Nft parse_from_mata(std::istream& nft_stream);

/**
* Parse NFA from the mata format in a string.
*
* @param nft_stream String containing NFA in mata format.
* @throws std::runtime_error Parsing of NFA fails.
*/
Nft parse_from_mata(const std::string& nft_in_mata);

/**
* Parse NFA from the mata format in a file.
*
* @param nft_stream Path to the file containing NFA in mata format.
* @throws std::runtime_error @p nft_file does not exist.
* @throws std::runtime_error Parsing of NFA fails.
*/
Nft parse_from_mata(const std::filesystem::path& nft_file);

/**
* Create NFT from NFA.
* @param nfa_state NFA to create NFT from.
* @param level_cnt Number of levels of NFT.
* @param epsilons Which symbols handle as epsilons.
* @return NFT representing @p nfa_state with @p level_cnt number of levels.
*/
Nft create_from_nfa(const mata::nfa::Nfa& nfa_state, Level level_cnt = 2, const std::set<Symbol>& epsilons = { EPSILON });

} // namespace mata::nft::builder.

#endif //LIBMATA_NFT_BUILDER_HH
Loading
Loading