-
Notifications
You must be signed in to change notification settings - Fork 19
Add reduction using SAT and QBF solvers #407
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
base: devel
Are you sure you want to change the base?
Changes from all commits
6c32178
d14f538
bb25d13
35f77ce
6c531b4
981aa05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
#include <utility> | ||
#include <vector> | ||
#include <queue> | ||
#include <unistd.h> | ||
|
||
#include "mata/alphabet.hh" | ||
#include "mata/parser/parser.hh" | ||
|
@@ -530,20 +531,54 @@ Nfa minimize(const Nfa &aut, const ParameterMap& params = {{ "algorithm", "brzoz | |
*/ | ||
Nfa determinize(const Nfa& aut, std::unordered_map<StateSet, State> *subset_map = nullptr); | ||
|
||
/** | ||
* @brief A CNF transformation to the provided clause in form of disjunctions of long and-not clauses, | ||
* utilized for reduction using SAT and QBF solvers, printed to output | ||
* @param[in] input Vector with the clause in DNF form to transform | ||
* @param[in] max_index Starting index of free variables used for new generated variables | ||
* @param[in] output Output stream | ||
* @return The first variable index that was not utilized | ||
*/ | ||
size_t reduction_tseytin(const std::vector <int>& input, size_t max_index, std::ostream& output); | ||
|
||
/** | ||
* @brief Experimental reduction using sat solver MiniSat with idea of creating minimal nondeterministic automaton, | ||
* is not possible to use for normal sized automata (around 10 states max), requires the alphabet of input automaton | ||
* to be a continuous sequence of numbers strating from 0 | ||
* @param[in] aut Automaton to reduce | ||
* @param[in] params Optional pamaters to control the reduction: | ||
* - "solver": "sat"/"sat_nfa" (sat for the dfa complete automaton with single initial state) | ||
* @param[in] debug Flag for debug output as the reduction can take some time to get the info about the current status | ||
* @return Reduced automaton | ||
*/ | ||
Nfa reduce_sat(const Nfa &aut, const ParameterMap& params = {{"solver", "sat"}}, bool debug = false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that both the specific reduction algorithms should be hidden behind the general reduce function. That is, they should not be in the public API for |
||
|
||
/** | ||
* @brief Experimental reduction using qbf solver CAQE with idea of creating minimal nondeterministic automaton, | ||
* is not possible to use for normal sized automata (around 10 states max), requires the alphabet of input automaton | ||
* to be a continuous sequence of numbers strating from 0 | ||
* @param[in] aut Automaton to reduce | ||
* @param[in] debug Flag for debug output as the reduction can take some time to get the info about the current status | ||
* @return Reduced automaton | ||
*/ | ||
Nfa reduce_qbf(const Nfa &aut, bool debug = false); | ||
|
||
/** | ||
* @brief Reduce the size of the automaton. | ||
* | ||
* @param[in] aut Automaton to reduce. | ||
* @param[out] state_renaming Mapping of original states to reduced states. | ||
* @param[in] params Optional parameters to control the reduction algorithm: | ||
* - "algorithm": "simulation", "residual", | ||
* and options to parametrize residual reduction, not utilized in simulation | ||
* - "algorithm": "simulation", "residual", "solvers", | ||
* options to parametrize residual reduction, not utilized in other reductions | ||
* - "type": "after", "with", | ||
* - "direction": "forward", "backward". | ||
* - "direction": "forward", "backward", | ||
* options to parametrize reduction using solvers, not utilized in other reductions | ||
* - "solver": "sat"/"sat_nfa"/"qbf". | ||
* @return Reduced automaton. | ||
*/ | ||
Nfa reduce(const Nfa &aut, StateRenaming *state_renaming = nullptr, | ||
const ParameterMap& params = {{ "algorithm", "simulation" }, { "type", "after" }, { "direction", "forward" } }); | ||
const ParameterMap& params = {{ "algorithm", "simulation" }, { "type", "after" }, { "direction", "forward" }, {"solver", "nfa"} }); | ||
|
||
/** | ||
* @brief Checks inclusion of languages of two NFAs: @p smaller and @p bigger (smaller <= bigger). | ||
|
@@ -574,6 +609,8 @@ inline bool is_included(const Nfa& smaller, const Nfa& bigger, const Alphabet* c | |
return is_included(smaller, bigger, nullptr, alphabet, params); | ||
} | ||
|
||
// static default value for empty run pair | ||
static std::pair<Run*, Run*> default_runs(nullptr, nullptr); | ||
/** | ||
* @brief Perform equivalence check of two NFAs: @p lhs and @p rhs. | ||
* | ||
|
@@ -582,10 +619,13 @@ inline bool is_included(const Nfa& smaller, const Nfa& bigger, const Alphabet* c | |
* @param[in] alphabet Alphabet of both NFAs to compute with. | ||
* @param[in] params[ Optional parameters to control the equivalence check algorithm: | ||
* - "algorithm": "naive", "antichains" (Default: "antichains") | ||
* @param[out] default_runs Optional parameter for intersection runs to return the found word | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is wasteful to pass by reference and have a statically initialized pair of pointers (which will get modified when the equivalence check gets run the second time -- therefore, they will no longer be the default runs). A pointer to a pair of runs should be used instead, default initialized to However, I think the global variable for default runs should be removed entirely and the parameter here should be a pointer default initialized to |
||
* that differs the input automata, used for solver reduction | ||
* @return True if @p lhs and @p rhs are equivalent, false otherwise. | ||
*/ | ||
bool are_equivalent(const Nfa& lhs, const Nfa& rhs, const Alphabet* alphabet, | ||
const ParameterMap& params = {{ "algorithm", "antichains"}}); | ||
const ParameterMap& params = {{ "algorithm", "antichains"}}, | ||
std::pair<Run*, Run*>& runs = default_runs); | ||
|
||
/** | ||
* @brief Perform equivalence check of two NFAs: @p lhs and @p rhs. | ||
|
@@ -602,9 +642,12 @@ bool are_equivalent(const Nfa& lhs, const Nfa& rhs, const Alphabet* alphabet, | |
* @param[in] rhs Second automaton to concatenate. | ||
* @param[in] params Optional parameters to control the equivalence check algorithm: | ||
* - "algorithm": "naive", "antichains" (Default: "antichains") | ||
* * @param[out] default_runs Optional parameter for intersection runs to return the found word | ||
* that differs the input automata, used for solver reduction | ||
* @return True if @p lhs and @p rhs are equivalent, false otherwise. | ||
*/ | ||
bool are_equivalent(const Nfa& lhs, const Nfa& rhs, const ParameterMap& params = {{ "algorithm", "antichains"}}); | ||
bool are_equivalent(const Nfa& lhs, const Nfa& rhs, const ParameterMap& params = {{ "algorithm", "antichains"}}, | ||
std::pair<Run*, Run*>& runs = default_runs); | ||
|
||
// Reverting the automaton by one of the three functions below, | ||
// currently simple_revert seems best (however, not tested enough). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this method be called
tseytin_transformation()
instead of areduction
? Furthermore, if I am seeing right, this method does not use the underlying automaton in any way, so it can be a utility function, not even a method oNFA, no? Stored somewhere in
utils/
folder, probably.