* src/tgbaalgos/emptiness.hh, src/tgbaalgos/emptiness.cc
(emptiness_check_instantiator): New class. * src/misc/optionmap.hh (set (const option_map&)): New method. * src/tgbatest/randtgba.cc: Create every emptiness check via emptiness_check_instantiator.
This commit is contained in:
parent
435b03c2b2
commit
4e1916ec50
7 changed files with 239 additions and 64 deletions
|
|
@ -24,9 +24,19 @@
|
|||
#include "tgba/tgba.hh"
|
||||
#include "tgba/bddprint.hh"
|
||||
#include "tgba/tgbaexplicit.hh"
|
||||
#include "tgbaalgos/gtec/gtec.hh"
|
||||
#include "tgbaalgos/gv04.hh"
|
||||
#include "tgbaalgos/magic.hh"
|
||||
#include "tgbaalgos/se05.hh"
|
||||
#include "tgbaalgos/tau03.hh"
|
||||
#include "tgbaalgos/tau03opt.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
|
||||
// tgba_run
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
tgba_run::~tgba_run()
|
||||
{
|
||||
for (steps::const_iterator i = prefix.begin(); i != prefix.end(); ++i)
|
||||
|
|
@ -51,6 +61,20 @@ namespace spot
|
|||
}
|
||||
}
|
||||
|
||||
tgba_run&
|
||||
tgba_run::operator=(const tgba_run& run)
|
||||
{
|
||||
if (&run != this)
|
||||
{
|
||||
this->~tgba_run();
|
||||
new(this) tgba_run(run);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// print_tgba_run
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::ostream&
|
||||
print_tgba_run(std::ostream& os,
|
||||
const tgba* a,
|
||||
|
|
@ -82,17 +106,8 @@ namespace spot
|
|||
return os;
|
||||
}
|
||||
|
||||
tgba_run&
|
||||
tgba_run::operator=(const tgba_run& run)
|
||||
{
|
||||
if (&run != this)
|
||||
{
|
||||
this->~tgba_run();
|
||||
new(this) tgba_run(run);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// emptiness_check_result
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
tgba_run*
|
||||
emptiness_check_result::accepting_run()
|
||||
|
|
@ -121,6 +136,9 @@ namespace spot
|
|||
}
|
||||
|
||||
|
||||
// emptiness_check
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
emptiness_check::~emptiness_check()
|
||||
{
|
||||
}
|
||||
|
|
@ -157,6 +175,110 @@ namespace spot
|
|||
return os;
|
||||
}
|
||||
|
||||
// emptiness_check_instantiator
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
spot::emptiness_check*
|
||||
couvreur99_cons(const spot::tgba* a, spot::option_map o)
|
||||
{
|
||||
return spot::couvreur99(a, o);
|
||||
}
|
||||
|
||||
struct ec_algo
|
||||
{
|
||||
const char* name;
|
||||
spot::emptiness_check* (*construct)(const spot::tgba*,
|
||||
spot::option_map);
|
||||
unsigned int min_acc;
|
||||
unsigned int max_acc;
|
||||
};
|
||||
|
||||
ec_algo ec_algos[] =
|
||||
{
|
||||
{ "Cou99", couvreur99_cons, 0, -1U },
|
||||
{ "CVWY90", spot::magic_search, 0, 1 },
|
||||
{ "GV04", spot::explicit_gv04_check, 0, 1 },
|
||||
{ "SE05", spot::se05, 0, 1 },
|
||||
{ "Tau03", spot::explicit_tau03_search, 1, -1U },
|
||||
{ "Tau03_opt", spot::explicit_tau03_opt_search, 0, -1U },
|
||||
};
|
||||
}
|
||||
|
||||
emptiness_check_instantiator::emptiness_check_instantiator(option_map o,
|
||||
void* i)
|
||||
: o_(o), info_(i)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int
|
||||
emptiness_check_instantiator::min_acceptance_conditions() const
|
||||
{
|
||||
return static_cast<ec_algo*>(info_)->min_acc;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
emptiness_check_instantiator::max_acceptance_conditions() const
|
||||
{
|
||||
return static_cast<ec_algo*>(info_)->max_acc;
|
||||
}
|
||||
|
||||
emptiness_check*
|
||||
emptiness_check_instantiator::instantiate(const tgba* a) const
|
||||
{
|
||||
return static_cast<ec_algo*>(info_)->construct(a, o_);
|
||||
}
|
||||
|
||||
emptiness_check_instantiator*
|
||||
emptiness_check_instantiator::construct(const char* name, const char** err)
|
||||
{
|
||||
// Skip spaces.
|
||||
while (*name && strchr(" \t\n", *name))
|
||||
++name;
|
||||
|
||||
const char* opt_str = strchr(name, '(');
|
||||
option_map o;
|
||||
if (opt_str)
|
||||
{
|
||||
const char* opt_start = opt_str + 1;
|
||||
const char* opt_end = strchr(opt_start, ')');
|
||||
if (!opt_end)
|
||||
{
|
||||
*err = opt_start;
|
||||
return 0;
|
||||
}
|
||||
std::string opt(opt_start, opt_end);
|
||||
|
||||
const char* res = o.parse_options(opt.c_str());
|
||||
if (res)
|
||||
{
|
||||
*err = opt.c_str() - res + opt_start;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt_str)
|
||||
opt_str = name + strlen(name);
|
||||
|
||||
// Ignore spaces before `(' (or trailing spaces).
|
||||
while (opt_str > name && strchr(" \t\n", *--opt_str))
|
||||
continue;
|
||||
std::string n(name, opt_str + 1);
|
||||
|
||||
|
||||
ec_algo* info = ec_algos;
|
||||
for (unsigned i = 0; i < sizeof(ec_algos)/sizeof(*ec_algos); ++i, ++info)
|
||||
if (n == info->name)
|
||||
return new emptiness_check_instantiator(o, info);
|
||||
*err = name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// tgba_run_to_tgba
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string format_state(const tgba* a, const state* s, int n)
|
||||
|
|
|
|||
|
|
@ -188,6 +188,57 @@ namespace spot
|
|||
option_map o_; ///< The options
|
||||
};
|
||||
|
||||
|
||||
// Dynamically create emptiness checks. Given their name and options.
|
||||
class emptiness_check_instantiator
|
||||
{
|
||||
public:
|
||||
/// \brief Create an emptiness-check instantiator, given the name
|
||||
/// of an emptiness check.
|
||||
///
|
||||
/// \a name should have the form \c "name" or \c "name(options)".
|
||||
///
|
||||
/// On error, the function returns 0. If the name of the algorithm
|
||||
/// was unknown, \c *err will be set to \c name. If some fragment of
|
||||
/// the options could not be parsed, \c *err will point to that
|
||||
/// fragment.
|
||||
static emptiness_check_instantiator* construct(const char* name,
|
||||
const char** err);
|
||||
|
||||
/// Actually instantiate the emptiness check, for \a a.
|
||||
emptiness_check* instantiate(const tgba* a) const;
|
||||
|
||||
/// Accessor to the options.
|
||||
/// @{
|
||||
const option_map&
|
||||
options() const
|
||||
{
|
||||
return o_;
|
||||
}
|
||||
|
||||
option_map&
|
||||
options()
|
||||
{
|
||||
return o_;
|
||||
}
|
||||
/// @}
|
||||
|
||||
/// \brief Minimum number of acceptance conditions supported by
|
||||
/// the emptiness check.
|
||||
unsigned int min_acceptance_conditions() const;
|
||||
|
||||
/// \brief Maximum number of acceptance conditions supported by
|
||||
/// the emptiness check.
|
||||
///
|
||||
/// \return \c -1U if no upper bound exists.
|
||||
unsigned int max_acceptance_conditions() const;
|
||||
private:
|
||||
emptiness_check_instantiator(option_map o, void* i);
|
||||
option_map o_;
|
||||
void *info_;
|
||||
};
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
/// \addtogroup emptiness_check_algorithms Emptiness-check algorithms
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue