Use shared_ptr for the emptiness check interfaces.

At the same time, this adds a is_empty() method to the tgba class,
simplifying many places that ran emptiness checks.

* iface/dve2/dve2check.cc, src/bin/ltlcross.cc,
src/dstarparse/dra2ba.cc, src/ltlvisit/contain.cc, src/tgba/tgba.cc,
src/tgba/tgba.hh, src/tgbaalgos/emptiness.cc,
src/tgbaalgos/emptiness.hh, src/tgbaalgos/gtec/ce.cc,
src/tgbaalgos/gtec/ce.hh, src/tgbaalgos/gtec/gtec.cc,
src/tgbaalgos/gtec/gtec.hh, src/tgbaalgos/gv04.cc,
src/tgbaalgos/gv04.hh, src/tgbaalgos/magic.cc,
src/tgbaalgos/magic.hh, src/tgbaalgos/minimize.cc,
src/tgbaalgos/ndfs_result.hxx, src/tgbaalgos/powerset.cc,
src/tgbaalgos/projrun.cc, src/tgbaalgos/projrun.hh,
src/tgbaalgos/reducerun.cc, src/tgbaalgos/reducerun.hh,
src/tgbaalgos/replayrun.cc, src/tgbaalgos/replayrun.hh,
src/tgbaalgos/rundotdec.cc, src/tgbaalgos/rundotdec.hh,
src/tgbaalgos/se05.cc, src/tgbaalgos/se05.hh,
src/tgbaalgos/tau03.cc, src/tgbaalgos/tau03.hh,
src/tgbaalgos/tau03opt.cc, src/tgbaalgos/tau03opt.hh,
src/tgbaalgos/word.cc, src/tgbaalgos/word.hh,
src/tgbatest/checkpsl.cc, src/tgbatest/complementation.cc,
src/tgbatest/emptchk.cc, src/tgbatest/ltl2tgba.cc,
src/tgbatest/randtgba.cc, wrap/python/ajax/spot.in,
wrap/python/spot.i: Use shared_ptr.
This commit is contained in:
Alexandre Duret-Lutz 2014-08-23 18:34:00 +02:00
parent 803e17bb8d
commit 6d7c258fd7
42 changed files with 335 additions and 402 deletions

View file

@ -157,16 +157,16 @@ checked_main(int argc, char **argv)
spot::ltl::atomic_prop_set ap; spot::ltl::atomic_prop_set ap;
auto dict = spot::make_bdd_dict(); auto dict = spot::make_bdd_dict();
spot::const_kripke_ptr model = 0; spot::const_kripke_ptr model = nullptr;
spot::const_tgba_ptr prop = 0; spot::const_tgba_ptr prop = nullptr;
spot::const_tgba_ptr product = 0; spot::const_tgba_ptr product = nullptr;
spot::emptiness_check_instantiator* echeck_inst = 0; spot::emptiness_check_instantiator_ptr echeck_inst = nullptr;
int exit_code = 0; int exit_code = 0;
spot::postprocessor post; spot::postprocessor post;
const spot::ltl::formula* deadf = 0; const spot::ltl::formula* deadf = nullptr;
const spot::ltl::formula* f = 0; const spot::ltl::formula* f = nullptr;
if (dead == 0 || !strcasecmp(dead, "true")) if (!dead || !strcasecmp(dead, "true"))
{ {
deadf = spot::ltl::constant::true_instance(); deadf = spot::ltl::constant::true_instance();
} }
@ -182,8 +182,7 @@ checked_main(int argc, char **argv)
if (output == EmptinessCheck) if (output == EmptinessCheck)
{ {
const char* err; const char* err;
echeck_inst = echeck_inst = spot::make_emptiness_check_instantiator(echeck_algo, &err);
spot::emptiness_check_instantiator::construct(echeck_algo, &err);
if (!echeck_inst) if (!echeck_inst)
{ {
std::cerr << "Failed to parse argument of -e/-E near `" std::cerr << "Failed to parse argument of -e/-E near `"
@ -265,14 +264,14 @@ checked_main(int argc, char **argv)
assert(echeck_inst); assert(echeck_inst);
{ {
spot::emptiness_check* ec = echeck_inst->instantiate(product); auto ec = echeck_inst->instantiate(product);
bool search_many = echeck_inst->options().get("repeated"); bool search_many = echeck_inst->options().get("repeated");
assert(ec); assert(ec);
do do
{ {
int memused = spot::memusage(); int memused = spot::memusage();
tm.start("running emptiness check"); tm.start("running emptiness check");
spot::emptiness_check_result* res; spot::emptiness_check_result_ptr res;
try try
{ {
res = ec->check(); res = ec->check();
@ -315,7 +314,7 @@ checked_main(int argc, char **argv)
else if (accepting_run) else if (accepting_run)
{ {
spot::tgba_run* run; spot::tgba_run_ptr run;
tm.start("computing accepting run"); tm.start("computing accepting run");
try try
{ {
@ -337,31 +336,24 @@ checked_main(int argc, char **argv)
else else
{ {
tm.start("reducing accepting run"); tm.start("reducing accepting run");
spot::tgba_run* redrun = run = spot::reduce_run(res->automaton(), run);
spot::reduce_run(res->automaton(), run);
tm.stop("reducing accepting run"); tm.stop("reducing accepting run");
delete run;
run = redrun;
tm.start("printing accepting run"); tm.start("printing accepting run");
spot::print_tgba_run(std::cout, product, run); spot::print_tgba_run(std::cout, product, run);
tm.stop("printing accepting run"); tm.stop("printing accepting run");
} }
delete run;
} }
else else
{ {
std::cout << "an accepting run exists " std::cout << "an accepting run exists "
<< "(use -C to print it)" << std::endl; << "(use -C to print it)" << std::endl;
} }
delete res;
} }
while (search_many); while (search_many);
delete ec;
} }
safe_exit: safe_exit:
delete echeck_inst;
if (f) if (f)
f->destroy(); f->destroy();

View file

@ -1071,9 +1071,7 @@ namespace
size_t i, size_t j, bool icomp, bool jcomp) size_t i, size_t j, bool icomp, bool jcomp)
{ {
auto prod = spot::product(aut_i, aut_j); auto prod = spot::product(aut_i, aut_j);
spot::emptiness_check* ec = spot::couvreur99(prod); auto res = spot::couvreur99(prod)->check();
spot::emptiness_check_result* res = ec->check();
if (res) if (res)
{ {
std::ostream& err = global_error(); std::ostream& err = global_error();
@ -1088,17 +1086,15 @@ namespace
err << "*N" << j; err << "*N" << j;
err << " is nonempty"; err << " is nonempty";
spot::tgba_run* run = res->accepting_run(); auto run = res->accepting_run();
if (run) if (run)
{ {
const spot::tgba_run* runmin = reduce_run(prod, run); run = reduce_run(prod, run);
delete run;
std::cerr << "; both automata accept the infinite word\n" std::cerr << "; both automata accept the infinite word\n"
<< " "; << " ";
spot::tgba_word w(runmin); spot::tgba_word w(run);
w.simplify(); w.simplify();
w.print(example(), prod->get_dict()) << '\n'; w.print(example(), prod->get_dict()) << '\n';
delete runmin;
} }
else else
{ {
@ -1106,9 +1102,7 @@ namespace
} }
end_error(); end_error();
} }
delete res; return !!res;
delete ec;
return res;
} }
static bool static bool

View file

@ -148,18 +148,10 @@ namespace spot
{ {
state_set keep(sl.begin(), sl.end()); state_set keep(sl.begin(), sl.end());
auto masked = build_tgba_mask_keep(dra->aut, keep, sl.front()); auto masked = build_tgba_mask_keep(dra->aut, keep, sl.front());
emptiness_check* ec = couvreur99(nra_to_nba(dra, masked)); if (!nra_to_nba(dra, masked)->is_empty())
emptiness_check_result* ecr = ec->check(); // This SCC is not DBA-realizable.
delete ecr; return false;
delete ec;
if (ecr)
{
// This SCC is not DBA-realizable.
//std::cerr << "not DBA-realizable\n";
return false;
}
} }
//std::cerr << "non-accepting\n";
for (state_list::const_iterator i = sl.begin(); for (state_list::const_iterator i = sl.begin();
i != sl.end(); ++i) i != sl.end(); ++i)
nonfinal.push_back(*i); nonfinal.push_back(*i);

View file

@ -69,21 +69,10 @@ namespace spot
if (i != l->incompatible.end()) if (i != l->incompatible.end())
return i->second; return i->second;
auto ec = couvreur99(product(l->translation, g->translation)); bool res = product(l->translation, g->translation)->is_empty();
auto ecr = ec->check(); l->incompatible[g] = res;
if (!ecr) g->incompatible[l] = res;
{ return res;
l->incompatible[g] = true;
g->incompatible[l] = true;
}
else
{
l->incompatible[g] = false;
g->incompatible[l] = false;
delete ecr;
}
delete ec;
return !ecr;
} }

View file

@ -21,6 +21,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "tgba.hh" #include "tgba.hh"
#include "tgbaalgos/gtec/gtec.hh"
namespace spot namespace spot
{ {
@ -85,4 +86,13 @@ namespace spot
return num_acc_; return num_acc_;
} }
bool
tgba::is_empty() const
{
// FIXME: This should be improved based on properties of the
// automaton. For instance we do not need couvreur99 is we know
// the automaton is weak.
return !couvreur99(shared_from_this())->check();
}
} }

View file

@ -27,7 +27,6 @@
#include "fwd.hh" #include "fwd.hh"
#include <cassert> #include <cassert>
#include <memory> #include <memory>
#include <memory>
#include "misc/casts.hh" #include "misc/casts.hh"
#include "misc/hash.hh" #include "misc/hash.hh"
@ -465,7 +464,7 @@ namespace spot
/// we never represent transitions! Transition informations are /// we never represent transitions! Transition informations are
/// obtained by querying the iterator over the successors of /// obtained by querying the iterator over the successors of
/// a state. /// a state.
class SPOT_API tgba class SPOT_API tgba: public std::enable_shared_from_this<tgba>
{ {
protected: protected:
tgba(); tgba();
@ -641,6 +640,8 @@ namespace spot
/// the other operand. /// the other operand.
virtual bdd neg_acceptance_conditions() const = 0; virtual bdd neg_acceptance_conditions() const = 0;
virtual bool is_empty() const;
protected: protected:
/// Do the actual computation of tgba::support_conditions(). /// Do the actual computation of tgba::support_conditions().
virtual bdd compute_support_conditions(const state* state) const = 0; virtual bdd compute_support_conditions(const state* state) const = 0;

View file

@ -77,8 +77,8 @@ namespace spot
std::ostream& std::ostream&
print_tgba_run(std::ostream& os, print_tgba_run(std::ostream& os,
const_tgba_ptr a, const const_tgba_ptr& a,
const tgba_run* run) const const_tgba_run_ptr& run)
{ {
bdd_dict_ptr d = a->get_dict(); bdd_dict_ptr d = a->get_dict();
os << "Prefix:" << std::endl; os << "Prefix:" << std::endl;
@ -109,10 +109,10 @@ namespace spot
// emptiness_check_result // emptiness_check_result
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
tgba_run* tgba_run_ptr
emptiness_check_result::accepting_run() emptiness_check_result::accepting_run()
{ {
return 0; return nullptr;
} }
const unsigned_statistics* const unsigned_statistics*
@ -149,6 +149,12 @@ namespace spot
return dynamic_cast<const unsigned_statistics*>(this); return dynamic_cast<const unsigned_statistics*>(this);
} }
const ec_statistics*
emptiness_check::emptiness_check_statistics() const
{
return dynamic_cast<const ec_statistics*>(this);
}
const char* const char*
emptiness_check::parse_options(char* options) emptiness_check::parse_options(char* options)
{ {
@ -180,29 +186,23 @@ namespace spot
namespace namespace
{ {
emptiness_check*
make_couvreur99(const const_tgba_ptr& a, spot::option_map o)
{
return couvreur99(a, o);
}
struct ec_algo struct ec_algo
{ {
const char* name; const char* name;
spot::emptiness_check* (*construct)(const const_tgba_ptr&, emptiness_check_ptr(*construct)(const const_tgba_ptr&,
spot::option_map); spot::option_map);
unsigned int min_acc; unsigned int min_acc;
unsigned int max_acc; unsigned int max_acc;
}; };
ec_algo ec_algos[] = ec_algo ec_algos[] =
{ {
{ "Cou99", make_couvreur99, 0, -1U }, { "Cou99", couvreur99, 0, -1U },
{ "CVWY90", spot::magic_search, 0, 1 }, { "CVWY90", magic_search, 0, 1 },
{ "GV04", spot::explicit_gv04_check, 0, 1 }, { "GV04", explicit_gv04_check, 0, 1 },
{ "SE05", spot::se05, 0, 1 }, { "SE05", se05, 0, 1 },
{ "Tau03", spot::explicit_tau03_search, 1, -1U }, { "Tau03", explicit_tau03_search, 1, -1U },
{ "Tau03_opt", spot::explicit_tau03_opt_search, 0, -1U }, { "Tau03_opt", explicit_tau03_opt_search, 0, -1U },
}; };
} }
@ -224,14 +224,14 @@ namespace spot
return static_cast<ec_algo*>(info_)->max_acc; return static_cast<ec_algo*>(info_)->max_acc;
} }
emptiness_check* emptiness_check_ptr
emptiness_check_instantiator::instantiate(const const_tgba_ptr& a) const emptiness_check_instantiator::instantiate(const const_tgba_ptr& a) const
{ {
return static_cast<ec_algo*>(info_)->construct(a, o_); return static_cast<ec_algo*>(info_)->construct(a, o_);
} }
emptiness_check_instantiator* emptiness_check_instantiator_ptr
emptiness_check_instantiator::construct(const char* name, const char** err) make_emptiness_check_instantiator(const char* name, const char** err)
{ {
// Skip spaces. // Skip spaces.
while (*name && strchr(" \t\n", *name)) while (*name && strchr(" \t\n", *name))
@ -272,17 +272,26 @@ namespace spot
if (n == info->name) if (n == info->name)
{ {
*err = 0; *err = 0;
return new emptiness_check_instantiator(o, info);
struct emptiness_check_instantiator_aux:
public emptiness_check_instantiator
{
emptiness_check_instantiator_aux(option_map o, void* i):
emptiness_check_instantiator(o, i)
{
}
};
return std::make_shared<emptiness_check_instantiator_aux>(o, info);
} }
*err = name; *err = name;
return 0; return nullptr;
} }
// tgba_run_to_tgba // tgba_run_to_tgba
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
tgba_digraph_ptr tgba_digraph_ptr
tgba_run_to_tgba(const const_tgba_ptr& a, const tgba_run* run) tgba_run_to_tgba(const const_tgba_ptr& a, const const_tgba_run_ptr& run)
{ {
auto d = a->get_dict(); auto d = a->get_dict();
auto res = make_tgba_digraph(d); auto res = make_tgba_digraph(d);

View file

@ -34,6 +34,8 @@
namespace spot namespace spot
{ {
struct tgba_run; struct tgba_run;
typedef std::shared_ptr<tgba_run> tgba_run_ptr;
typedef std::shared_ptr<const tgba_run> const_tgba_run_ptr;
/// \addtogroup emptiness_check Emptiness-checks /// \addtogroup emptiness_check Emptiness-checks
/// \ingroup tgba_algorithms /// \ingroup tgba_algorithms
@ -99,7 +101,7 @@ namespace spot
/// cannot produce a counter example (that does not mean there /// cannot produce a counter example (that does not mean there
/// is no counter-example; the mere existence of an instance of /// is no counter-example; the mere existence of an instance of
/// this class asserts the existence of a counter-example). /// this class asserts the existence of a counter-example).
virtual tgba_run* accepting_run(); virtual tgba_run_ptr accepting_run();
/// The automaton on which an accepting_run() was found. /// The automaton on which an accepting_run() was found.
const const_tgba_ptr& const const_tgba_ptr&
@ -129,8 +131,11 @@ namespace spot
option_map o_; ///< The options. option_map o_; ///< The options.
}; };
typedef std::shared_ptr<emptiness_check_result> emptiness_check_result_ptr;
/// Common interface to emptiness check algorithms. /// Common interface to emptiness check algorithms.
class SPOT_API emptiness_check class SPOT_API emptiness_check:
public std::enable_shared_from_this<emptiness_check>
{ {
public: public:
emptiness_check(const const_tgba_ptr& a, option_map o = option_map()) emptiness_check(const const_tgba_ptr& a, option_map o = option_map())
@ -173,11 +178,14 @@ namespace spot
/// Some emptiness_check algorithms, especially those using bit state /// Some emptiness_check algorithms, especially those using bit state
/// hashing may return 0 even if the automaton is not empty. /// hashing may return 0 even if the automaton is not empty.
/// \see safe() /// \see safe()
virtual emptiness_check_result* check() = 0; virtual emptiness_check_result_ptr check() = 0;
/// Return statistics, if available. /// Return statistics, if available.
virtual const unsigned_statistics* statistics() const; virtual const unsigned_statistics* statistics() const;
/// Return emptiness check statistics, if available.
virtual const ec_statistics* emptiness_check_statistics() const;
/// Print statistics, if any. /// Print statistics, if any.
virtual std::ostream& print_stats(std::ostream& os) const; virtual std::ostream& print_stats(std::ostream& os) const;
@ -189,25 +197,18 @@ namespace spot
option_map o_; ///< The options option_map o_; ///< The options
}; };
typedef std::shared_ptr<emptiness_check> emptiness_check_ptr;
class emptiness_check_instantiator;
typedef std::shared_ptr<emptiness_check_instantiator>
emptiness_check_instantiator_ptr;
// Dynamically create emptiness checks. Given their name and options. // Dynamically create emptiness checks. Given their name and options.
class SPOT_API emptiness_check_instantiator class SPOT_API emptiness_check_instantiator
{ {
public: 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. /// Actually instantiate the emptiness check, for \a a.
emptiness_check* instantiate(const const_tgba_ptr& a) const; emptiness_check_ptr instantiate(const const_tgba_ptr& a) const;
/// Accessor to the options. /// Accessor to the options.
/// @{ /// @{
@ -233,15 +234,27 @@ namespace spot
/// ///
/// \return \c -1U if no upper bound exists. /// \return \c -1U if no upper bound exists.
unsigned int max_acceptance_conditions() const; unsigned int max_acceptance_conditions() const;
private: protected:
emptiness_check_instantiator(option_map o, void* i); emptiness_check_instantiator(option_map o, void* i);
option_map o_; option_map o_;
void *info_; void *info_;
}; };
/// @} /// @}
/// \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.
SPOT_API emptiness_check_instantiator_ptr
make_emptiness_check_instantiator(const char* name, const char** err);
/// \addtogroup emptiness_check_algorithms Emptiness-check algorithms /// \addtogroup emptiness_check_algorithms Emptiness-check algorithms
/// \ingroup emptiness_check /// \ingroup emptiness_check
@ -287,14 +300,16 @@ namespace spot
/// actually exists in the automaton (and will also display any /// actually exists in the automaton (and will also display any
/// transition annotation). /// transition annotation).
SPOT_API std::ostream& SPOT_API std::ostream&
print_tgba_run(std::ostream& os, const_tgba_ptr a, const tgba_run* run); print_tgba_run(std::ostream& os,
const const_tgba_ptr& a,
const const_tgba_run_ptr& run);
/// \brief Return an explicit_tgba corresponding to \a run (i.e. comparable /// \brief Return an explicit_tgba corresponding to \a run (i.e. comparable
/// states are merged). /// states are merged).
/// ///
/// \pre \a run must correspond to an actual run of the automaton \a a. /// \pre \a run must correspond to an actual run of the automaton \a a.
SPOT_API tgba_digraph_ptr SPOT_API tgba_digraph_ptr
tgba_run_to_tgba(const const_tgba_ptr& a, const tgba_run* run); tgba_run_to_tgba(const const_tgba_ptr& a, const const_tgba_run_ptr& run);
/// @} /// @}

View file

@ -32,7 +32,7 @@ namespace spot
{ {
public: public:
shortest_path(const state_set* t, shortest_path(const state_set* t,
const couvreur99_check_status* ecs, const std::shared_ptr<const couvreur99_check_status>& ecs,
couvreur99_check_result* r) couvreur99_check_result* r)
: bfs_steps(ecs->aut), target(t), ecs(ecs), r(r) : bfs_steps(ecs->aut), target(t), ecs(ecs), r(r)
{ {
@ -68,13 +68,14 @@ namespace spot
private: private:
state_set seen; state_set seen;
const state_set* target; const state_set* target;
const couvreur99_check_status* ecs; std::shared_ptr<const couvreur99_check_status> ecs;
couvreur99_check_result* r; couvreur99_check_result* r;
}; };
} }
couvreur99_check_result::couvreur99_check_result couvreur99_check_result::couvreur99_check_result
(const couvreur99_check_status* ecs, option_map o) (const std::shared_ptr<const couvreur99_check_status>& ecs,
option_map o)
: emptiness_check_result(ecs->aut, o), ecs_(ecs) : emptiness_check_result(ecs->aut, o), ecs_(ecs)
{ {
} }
@ -90,10 +91,10 @@ namespace spot
return count; return count;
} }
tgba_run* tgba_run_ptr
couvreur99_check_result::accepting_run() couvreur99_check_result::accepting_run()
{ {
run_ = new tgba_run; run_ = std::make_shared<tgba_run>();
assert(!ecs_->root.empty()); assert(!ecs_->root.empty());
@ -212,7 +213,7 @@ namespace spot
return false; return false;
} }
} b(ecs_, this, acc_to_traverse); } b(ecs_.get(), this, acc_to_traverse);
substart = b.search(substart, run_->cycle); substart = b.search(substart, run_->cycle);
assert(substart); assert(substart);

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2013 Laboratoire de Recherche et Développement de // Copyright (C) 2013, 2014 Laboratoire de Recherche et Développement de
// l'Epita (LRDE). // l'Epita (LRDE).
// Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -35,10 +35,11 @@ namespace spot
public acss_statistics public acss_statistics
{ {
public: public:
couvreur99_check_result(const couvreur99_check_status* ecs, couvreur99_check_result(const
std::shared_ptr<const couvreur99_check_status>& ecs,
option_map o = option_map()); option_map o = option_map());
virtual tgba_run* accepting_run(); virtual tgba_run_ptr accepting_run();
void print_stats(std::ostream& os) const; void print_stats(std::ostream& os) const;
@ -50,8 +51,8 @@ namespace spot
void accepting_cycle(); void accepting_cycle();
private: private:
const couvreur99_check_status* ecs_; std::shared_ptr<const couvreur99_check_status> ecs_;
tgba_run* run_; tgba_run_ptr run_;
}; };
} }

View file

@ -45,7 +45,7 @@ namespace spot
removed_components(0) removed_components(0)
{ {
poprem_ = o.get("poprem", 1); poprem_ = o.get("poprem", 1);
ecs_ = new couvreur99_check_status(a); ecs_ = std::make_shared<couvreur99_check_status>(a);
stats["removed components"] = stats["removed components"] =
static_cast<spot::unsigned_statistics::unsigned_fun> static_cast<spot::unsigned_statistics::unsigned_fun>
(&couvreur99_check::get_removed_components); (&couvreur99_check::get_removed_components);
@ -56,7 +56,6 @@ namespace spot
couvreur99_check::~couvreur99_check() couvreur99_check::~couvreur99_check()
{ {
delete ecs_;
} }
unsigned unsigned
@ -129,7 +128,7 @@ namespace spot
} }
} }
emptiness_check_result* emptiness_check_result_ptr
couvreur99_check::check() couvreur99_check::check()
{ {
// We use five main data in this algorithm: // We use five main data in this algorithm:
@ -281,15 +280,15 @@ namespace spot
// cycle. // cycle.
ecs_->cycle_seed = p.first->first; ecs_->cycle_seed = p.first->first;
set_states(ecs_->states()); set_states(ecs_->states());
return new couvreur99_check_result(ecs_, options()); return std::make_shared<couvreur99_check_result>(ecs_, options());
} }
} }
// This automaton recognizes no word. // This automaton recognizes no word.
set_states(ecs_->states()); set_states(ecs_->states());
return 0; return nullptr;
} }
const couvreur99_check_status* std::shared_ptr<const couvreur99_check_status>
couvreur99_check::result() const couvreur99_check::result() const
{ {
return ecs_; return ecs_;
@ -383,7 +382,7 @@ namespace spot
} }
} }
emptiness_check_result* emptiness_check_result_ptr
couvreur99_check_shy::check() couvreur99_check_shy::check()
{ {
// Position in the loop seeking known successors. // Position in the loop seeking known successors.
@ -418,7 +417,7 @@ namespace spot
// This automaton recognizes no word. // This automaton recognizes no word.
set_states(ecs_->states()); set_states(ecs_->states());
assert(poprem_ || depth() == 0); assert(poprem_ || depth() == 0);
return 0; return nullptr;
} }
pos = todo.back().q.begin(); pos = todo.back().q.begin();
@ -554,7 +553,7 @@ namespace spot
// We have found an accepting SCC. Clean up TODO. // We have found an accepting SCC. Clean up TODO.
clear_todo(); clear_todo();
set_states(ecs_->states()); set_states(ecs_->states());
return new couvreur99_check_result(ecs_, options()); return std::make_shared<couvreur99_check_result>(ecs_, options());
} }
// Group the pending successors of formed SCC if requested. // Group the pending successors of formed SCC if requested.
if (group_) if (group_)
@ -592,12 +591,12 @@ namespace spot
} }
} }
emptiness_check* emptiness_check_ptr
couvreur99(const const_tgba_ptr& a, option_map o) couvreur99(const const_tgba_ptr& a, option_map o)
{ {
if (o.get("shy")) if (o.get("shy"))
return new couvreur99_check_shy(a, o); return std::make_shared<couvreur99_check_shy>(a, o);
return new couvreur99_check(a, o); return std::make_shared<couvreur99_check>(a, o);
} }
} }

View file

@ -136,10 +136,10 @@ namespace spot
/// states that belong to the same SCC will be considered when /// states that belong to the same SCC will be considered when
/// choosing a successor. Otherwise, only the successor of the /// choosing a successor. Otherwise, only the successor of the
/// topmost state on the DFS stack are considered. /// topmost state on the DFS stack are considered.
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
couvreur99(const const_tgba_ptr& a, option_map options = option_map()); couvreur99(const const_tgba_ptr& a, option_map options = option_map());
#ifndef SWIG
/// \brief An implementation of the Couvreur99 emptiness-check algorithm. /// \brief An implementation of the Couvreur99 emptiness-check algorithm.
/// ///
/// See the documentation for spot::couvreur99. /// See the documentation for spot::couvreur99.
@ -150,7 +150,7 @@ namespace spot
virtual ~couvreur99_check(); virtual ~couvreur99_check();
/// Check whether the automaton's language is empty. /// Check whether the automaton's language is empty.
virtual emptiness_check_result* check(); virtual emptiness_check_result_ptr check();
virtual std::ostream& print_stats(std::ostream& os) const; virtual std::ostream& print_stats(std::ostream& os) const;
@ -162,10 +162,10 @@ namespace spot
/// This status should not be deleted, it is a pointer /// This status should not be deleted, it is a pointer
/// to a member of this class that will be deleted when /// to a member of this class that will be deleted when
/// the couvreur99 object is deleted. /// the couvreur99 object is deleted.
const couvreur99_check_status* result() const; std::shared_ptr<const couvreur99_check_status> result() const;
protected: protected:
couvreur99_check_status* ecs_; std::shared_ptr<couvreur99_check_status> ecs_;
/// \brief Remove a strongly component from the hash. /// \brief Remove a strongly component from the hash.
/// ///
/// This function remove all accessible state from a given /// This function remove all accessible state from a given
@ -191,7 +191,7 @@ namespace spot
couvreur99_check_shy(const const_tgba_ptr& a, option_map o = option_map()); couvreur99_check_shy(const const_tgba_ptr& a, option_map o = option_map());
virtual ~couvreur99_check_shy(); virtual ~couvreur99_check_shy();
virtual emptiness_check_result* check(); virtual emptiness_check_result_ptr check();
protected: protected:
struct successor { struct successor {
@ -239,7 +239,7 @@ namespace spot
// reprocess the successor states of SCC that have been merged. // reprocess the successor states of SCC that have been merged.
bool group2_; bool group2_;
}; };
#endif
/// @} /// @}
} }

View file

@ -91,7 +91,7 @@ namespace spot
} }
} }
virtual emptiness_check_result* virtual emptiness_check_result_ptr
check() check()
{ {
top = dftop = -1; top = dftop = -1;
@ -162,7 +162,7 @@ namespace spot
set_states(h.size()); set_states(h.size());
} }
if (violation) if (violation)
return new result(*this); return std::make_shared<result>(*this);
return 0; return 0;
} }
@ -287,10 +287,10 @@ namespace spot
return s; return s;
} }
virtual tgba_run* virtual tgba_run_ptr
accepting_run() accepting_run()
{ {
tgba_run* res = new tgba_run; auto res = std::make_shared<tgba_run>();
update_lowlinks(); update_lowlinks();
#ifdef TRACE #ifdef TRACE
@ -409,9 +409,9 @@ namespace spot
} // anonymous } // anonymous
emptiness_check* emptiness_check_ptr
explicit_gv04_check(const const_tgba_ptr& a, option_map o) explicit_gv04_check(const const_tgba_ptr& a, option_map o)
{ {
return new gv04(a, o); return std::make_shared<gv04>(a, o);
} }
} }

View file

@ -25,11 +25,10 @@
# include "misc/optionmap.hh" # include "misc/optionmap.hh"
# include "tgba/fwd.hh" # include "tgba/fwd.hh"
# include "emptiness.hh"
namespace spot namespace spot
{ {
class emptiness_check;
/// \brief Emptiness check based on Geldenhuys and Valmari's /// \brief Emptiness check based on Geldenhuys and Valmari's
/// TACAS'04 paper. /// TACAS'04 paper.
/// \ingroup emptiness_check_algorithms /// \ingroup emptiness_check_algorithms
@ -54,7 +53,7 @@ namespace spot
isbn = {3-540-21299-X} isbn = {3-540-21299-X}
} }
\endverbatim */ \endverbatim */
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
explicit_gv04_check(const const_tgba_ptr& a, option_map o = option_map()); explicit_gv04_check(const const_tgba_ptr& a, option_map o = option_map());
} }

View file

@ -88,8 +88,10 @@ namespace spot
/// check() can be called several times (until it returns a null /// check() can be called several times (until it returns a null
/// pointer) to enumerate all the visited accepting paths. The method /// pointer) to enumerate all the visited accepting paths. The method
/// visits only a finite set of accepting paths. /// visits only a finite set of accepting paths.
virtual emptiness_check_result* check() virtual emptiness_check_result_ptr check()
{ {
auto t = std::static_pointer_cast<magic_search_>
(this->emptiness_check::shared_from_this());
if (st_red.empty()) if (st_red.empty())
{ {
assert(st_blue.empty()); assert(st_blue.empty());
@ -98,19 +100,19 @@ namespace spot
h.add_new_state(s0, BLUE); h.add_new_state(s0, BLUE);
push(st_blue, s0, bddfalse, bddfalse); push(st_blue, s0, bddfalse, bddfalse);
if (dfs_blue()) if (dfs_blue())
return new magic_search_result(*this, options()); return std::make_shared<magic_search_result>(t, options());
} }
else else
{ {
h.pop_notify(st_red.front().s); h.pop_notify(st_red.front().s);
pop(st_red); pop(st_red);
if (!st_red.empty() && dfs_red()) if (!st_red.empty() && dfs_red())
return new magic_search_result(*this, options()); return std::make_shared<magic_search_result>(t, options());
else else
if (dfs_blue()) if (dfs_blue())
return new magic_search_result(*this, options()); return std::make_shared<magic_search_result>(t, options());
} }
return 0; return nullptr;
} }
virtual std::ostream& print_stats(std::ostream &os) const virtual std::ostream& print_stats(std::ostream &os) const
@ -325,25 +327,25 @@ namespace spot
public acss_statistics public acss_statistics
{ {
public: public:
result_from_stack(magic_search_& ms) result_from_stack(std::shared_ptr<magic_search_> ms)
: emptiness_check_result(ms.automaton()), ms_(ms) : emptiness_check_result(ms->automaton()), ms_(ms)
{ {
} }
virtual tgba_run* accepting_run() virtual tgba_run_ptr accepting_run()
{ {
assert(!ms_.st_blue.empty()); assert(!ms_->st_blue.empty());
assert(!ms_.st_red.empty()); assert(!ms_->st_red.empty());
tgba_run* run = new tgba_run; auto run = std::make_shared<tgba_run>();
typename stack_type::const_reverse_iterator i, j, end; typename stack_type::const_reverse_iterator i, j, end;
tgba_run::steps* l; tgba_run::steps* l;
l = &run->prefix; l = &run->prefix;
i = ms_.st_blue.rbegin(); i = ms_->st_blue.rbegin();
end = ms_.st_blue.rend(); --end; end = ms_->st_blue.rend(); --end;
j = i; ++j; j = i; ++j;
for (; i != end; ++i, ++j) for (; i != end; ++i, ++j)
{ {
@ -353,12 +355,12 @@ namespace spot
l = &run->cycle; l = &run->cycle;
j = ms_.st_red.rbegin(); j = ms_->st_red.rbegin();
tgba_run::step s = { i->s->clone(), j->label, j->acc }; tgba_run::step s = { i->s->clone(), j->label, j->acc };
l->push_back(s); l->push_back(s);
i = j; ++j; i = j; ++j;
end = ms_.st_red.rend(); --end; end = ms_->st_red.rend(); --end;
for (; i != end; ++i, ++j) for (; i != end; ++i, ++j)
{ {
tgba_run::step s = { i->s->clone(), j->label, j->acc }; tgba_run::step s = { i->s->clone(), j->label, j->acc };
@ -373,7 +375,7 @@ namespace spot
return 0; return 0;
} }
private: private:
magic_search_& ms_; std::shared_ptr<magic_search_> ms_;
}; };
# define FROM_STACK "ar:from_stack" # define FROM_STACK "ar:from_stack"
@ -381,8 +383,9 @@ namespace spot
class magic_search_result: public emptiness_check_result class magic_search_result: public emptiness_check_result
{ {
public: public:
magic_search_result(magic_search_& m, option_map o = option_map()) magic_search_result(const std::shared_ptr<magic_search_>& m,
: emptiness_check_result(m.automaton(), o), ms(m) option_map o = option_map())
: emptiness_check_result(m->automaton(), o), ms(m)
{ {
if (options()[FROM_STACK]) if (options()[FROM_STACK])
computer = new result_from_stack(ms); computer = new result_from_stack(ms);
@ -409,7 +412,7 @@ namespace spot
delete computer; delete computer;
} }
virtual tgba_run* accepting_run() virtual tgba_run_ptr accepting_run()
{ {
return computer->accepting_run(); return computer->accepting_run();
} }
@ -421,7 +424,7 @@ namespace spot
private: private:
emptiness_check_result* computer; emptiness_check_result* computer;
magic_search_& ms; std::shared_ptr<magic_search_> ms;
}; };
}; };
@ -584,18 +587,20 @@ namespace spot
} // anonymous } // anonymous
emptiness_check* explicit_magic_search(const const_tgba_ptr& a, option_map o) emptiness_check_ptr
explicit_magic_search(const const_tgba_ptr& a, option_map o)
{ {
return new magic_search_<explicit_magic_search_heap>(a, 0, o); return std::make_shared<magic_search_<explicit_magic_search_heap>>(a, 0, o);
} }
emptiness_check* bit_state_hashing_magic_search(const const_tgba_ptr& a, emptiness_check_ptr
size_t size, option_map o) bit_state_hashing_magic_search(const const_tgba_ptr& a,
size_t size, option_map o)
{ {
return new magic_search_<bsh_magic_search_heap>(a, size, o); return std::make_shared<magic_search_<bsh_magic_search_heap>>(a, size, o);
} }
emptiness_check* emptiness_check_ptr
magic_search(const const_tgba_ptr& a, option_map o) magic_search(const const_tgba_ptr& a, option_map o)
{ {
size_t size = o.get("bsh"); size_t size = o.get("bsh");

View file

@ -26,11 +26,10 @@
#include <cstddef> #include <cstddef>
#include "tgba/fwd.hh" #include "tgba/fwd.hh"
#include "misc/optionmap.hh" #include "misc/optionmap.hh"
#include "emptiness.hh"
namespace spot namespace spot
{ {
class emptiness_check;
/// \addtogroup emptiness_check_algorithms /// \addtogroup emptiness_check_algorithms
/// @{ /// @{
@ -97,7 +96,7 @@ namespace spot
/// ///
/// \bug The name is misleading. Magic-search is the algorithm /// \bug The name is misleading. Magic-search is the algorithm
/// from \c godefroid.93.pstv, not \c courcoubetis.92.fmsd. /// from \c godefroid.93.pstv, not \c courcoubetis.92.fmsd.
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
explicit_magic_search(const const_tgba_ptr& a, explicit_magic_search(const const_tgba_ptr& a,
option_map o = option_map()); option_map o = option_map());
@ -128,7 +127,7 @@ namespace spot
/// ///
/// \sa spot::explicit_magic_search /// \sa spot::explicit_magic_search
/// ///
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
bit_state_hashing_magic_search(const const_tgba_ptr& a, size_t size, bit_state_hashing_magic_search(const const_tgba_ptr& a, size_t size,
option_map o = option_map()); option_map o = option_map());
@ -138,7 +137,7 @@ namespace spot
/// bit_state_hashing_magic_search() according to the \c "bsh" option /// bit_state_hashing_magic_search() according to the \c "bsh" option
/// in the \c option_map. If \c "bsh" is set and non null, its value /// in the \c option_map. If \c "bsh" is set and non null, its value
/// is used as the size of the hash map. /// is used as the size of the hash map.
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
magic_search(const const_tgba_ptr& a, option_map o = option_map()); magic_search(const const_tgba_ptr& a, option_map o = option_map());
/// @} /// @}

View file

@ -260,13 +260,7 @@ namespace spot
// Contrustruct a product between // Contrustruct a product between
// LOOP_A, and ORIG_A starting in *IT. // LOOP_A, and ORIG_A starting in *IT.
// FIXME: This could be sped up a lot! // FIXME: This could be sped up a lot!
emptiness_check* ec = couvreur99(product_at(loop_a, orig_a, if (!product_at(loop_a, orig_a, loop_a_init, it)->is_empty())
loop_a_init, it));
emptiness_check_result* res = ec->check();
delete res;
delete ec;
if (res)
{ {
accepting = true; accepting = true;
break; break;
@ -674,25 +668,15 @@ namespace spot
bool ok = false; bool ok = false;
emptiness_check* ec = couvreur99(product(min_aut_f, aut_neg_f)); if (product(min_aut_f, aut_neg_f)->is_empty())
emptiness_check_result* res = ec->check();
if (!res)
{ {
delete ec;
// Complement the minimized WDBA. // Complement the minimized WDBA.
auto neg_min_aut_f = wdba_complement(min_aut_f); auto neg_min_aut_f = wdba_complement(min_aut_f);
ec = couvreur99(product(aut_f, neg_min_aut_f)); if (product(aut_f, neg_min_aut_f)->is_empty())
res = ec->check(); // Finally, we are now sure that it was safe
if (!res) // to minimize the automaton.
{ ok = true;
// Finally, we are now sure that it was safe
// to minimize the automaton.
ok = true;
}
} }
delete res;
delete ec;
if (ok) if (ok)
return min_aut_f; return min_aut_f;

View file

@ -95,9 +95,9 @@ namespace spot
public stats_interface<ndfs_result<ndfs_search, heap>, heap::Has_Size> public stats_interface<ndfs_result<ndfs_search, heap>, heap::Has_Size>
{ {
public: public:
ndfs_result(const ndfs_search& ms) ndfs_result(const std::shared_ptr<ndfs_search>& ms)
: emptiness_check_result(ms.automaton()), ms_(ms), : emptiness_check_result(ms->automaton()), ms_(ms),
h_(ms_.get_heap()) h_(ms->get_heap())
{ {
} }
@ -105,10 +105,10 @@ namespace spot
{ {
} }
virtual tgba_run* accepting_run() virtual tgba_run_ptr accepting_run()
{ {
const stack_type& stb = ms_.get_st_blue(); const stack_type& stb = ms_->get_st_blue();
const stack_type& str = ms_.get_st_red(); const stack_type& str = ms_->get_st_red();
assert(!stb.empty()); assert(!stb.empty());
@ -195,7 +195,7 @@ namespace spot
assert(!acc_trans.empty()); assert(!acc_trans.empty());
tgba_run* run = new tgba_run; auto run = std::make_shared<tgba_run>();
// construct run->cycle from acc_trans. // construct run->cycle from acc_trans.
construct_cycle(run, acc_trans); construct_cycle(run, acc_trans);
// construct run->prefix (a minimal path from the initial state to any // construct run->prefix (a minimal path from the initial state to any
@ -214,7 +214,7 @@ namespace spot
} }
private: private:
const ndfs_search& ms_; std::shared_ptr<ndfs_search> ms_;
const heap& h_; const heap& h_;
template <typename T, int n> template <typename T, int n>
friend struct stats_interface; friend struct stats_interface;
@ -529,7 +529,7 @@ namespace spot
const heap& h; const heap& h;
}; };
void construct_cycle(tgba_run* run, void construct_cycle(tgba_run_ptr run,
const accepting_transitions_list& acc_trans) const accepting_transitions_list& acc_trans)
{ {
assert(!acc_trans.empty()); assert(!acc_trans.empty());
@ -616,7 +616,7 @@ namespace spot
} }
} }
void construct_prefix(tgba_run* run) void construct_prefix(tgba_run_ptr run)
{ {
m_source_trans target; m_source_trans target;
transition tmp; transition tmp;

View file

@ -205,11 +205,7 @@ namespace spot
{ {
// Check the product between LOOP_A, and ORIG_A starting // Check the product between LOOP_A, and ORIG_A starting
// in S. // in S.
auto ec = couvreur99(product_at(loop_a, ref_, loop_a_init, s)); if (!product_at(loop_a, ref_, loop_a_init, s)->is_empty())
emptiness_check_result* res = ec->check();
delete res;
delete ec;
if (res)
{ {
accepting = true; accepting = true;
break; break;
@ -326,9 +322,9 @@ namespace spot
auto det = tba_determinize(aut, threshold_states, threshold_cycles); auto det = tba_determinize(aut, threshold_states, threshold_cycles);
if (!det) if (!det)
return 0; return nullptr;
if (neg_aut == 0) if (neg_aut == nullptr)
{ {
const ltl::formula* neg_f = const ltl::formula* neg_f =
ltl::unop::instance(ltl::unop::Not, f->clone()); ltl::unop::instance(ltl::unop::Not, f->clone());
@ -339,30 +335,13 @@ namespace spot
neg_aut = scc_filter(neg_aut, true); neg_aut = scc_filter(neg_aut, true);
} }
bool ok = false; if (product(det, neg_aut)->is_empty())
// Complement the DBA.
if (product(aut, dtgba_complement(det))->is_empty())
// Finally, we are now sure that it was safe
// to determinize the automaton.
return det;
auto ec = couvreur99(product(det, neg_aut));
auto res = ec->check();
if (!res)
{
delete ec;
// Complement the DBA.
ec = couvreur99(product(aut, dtgba_complement(det)));
res = ec->check();
if (!res)
{
// Finally, we are now sure that it was safe
// to determinize the automaton.
ok = true;
}
}
delete res;
delete ec;
if (ok)
return det;
return aut; return aut;
} }
} }

View file

@ -24,12 +24,12 @@
namespace spot namespace spot
{ {
tgba_run* tgba_run_ptr
project_tgba_run(const const_tgba_ptr& a_run, project_tgba_run(const const_tgba_ptr& a_run,
const const_tgba_ptr& a_proj, const const_tgba_ptr& a_proj,
const tgba_run* run) const const_tgba_run_ptr& run)
{ {
tgba_run* res = new tgba_run; auto res = std::make_shared<tgba_run>();
for (tgba_run::steps::const_iterator i = run->prefix.begin(); for (tgba_run::steps::const_iterator i = run->prefix.begin();
i != run->prefix.end(); ++i) i != run->prefix.end(); ++i)
{ {

View file

@ -26,6 +26,7 @@
# include "misc/common.hh" # include "misc/common.hh"
# include <iosfwd> # include <iosfwd>
# include "tgba/fwd.hh" # include "tgba/fwd.hh"
# include "tgbaalgos/emptiness.hh"
namespace spot namespace spot
{ {
@ -41,10 +42,10 @@ namespace spot
/// \param a_run the automata on which the run was generated /// \param a_run the automata on which the run was generated
/// \param a_proj the automata on which to project the run /// \param a_proj the automata on which to project the run
/// \return true iff the run could be completed /// \return true iff the run could be completed
SPOT_API tgba_run* SPOT_API tgba_run_ptr
project_tgba_run(const const_tgba_ptr& a_run, project_tgba_run(const const_tgba_ptr& a_run,
const const_tgba_ptr& a_proj, const const_tgba_ptr& a_proj,
const tgba_run* run); const const_tgba_run_ptr& run);
} }
#endif // SPOT_TGBAALGOS_PROJRUN_HH #endif // SPOT_TGBAALGOS_PROJRUN_HH

View file

@ -1,7 +1,8 @@
// Copyright (C) 2011, 2013 Laboratoire de Recherche et Développement // -*- coding: utf-8 -*-
// de l'Epita (LRDE). // Copyright (C) 2011, 2013, 2014 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie. // et Marie Curie.
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -86,10 +87,10 @@ namespace spot
}; };
} }
tgba_run* tgba_run_ptr
reduce_run(const const_tgba_ptr& a, const tgba_run* org) reduce_run(const const_tgba_ptr& a, const const_tgba_run_ptr& org)
{ {
tgba_run* res = new tgba_run; auto res = std::make_shared<tgba_run>();
state_set ss; state_set ss;
shortest_path shpath(a); shortest_path shpath(a);
shpath.set_target(&ss); shpath.set_target(&ss);

View file

@ -25,18 +25,17 @@
# include "misc/common.hh" # include "misc/common.hh"
# include "tgba/fwd.hh" # include "tgba/fwd.hh"
# include "tgbaalgos/emptiness.hh"
namespace spot namespace spot
{ {
struct tgba_run;
/// \ingroup tgba_run /// \ingroup tgba_run
/// \brief Reduce an accepting run. /// \brief Reduce an accepting run.
/// ///
/// Return a run which is accepting for \a a and that is no longer /// Return a run which is accepting for \a a and that is no longer
/// than \a org. /// than \a org.
SPOT_API tgba_run* SPOT_API tgba_run_ptr
reduce_run(const const_tgba_ptr& a, const tgba_run* org); reduce_run(const const_tgba_ptr& a, const const_tgba_run_ptr& org);
} }
#endif // SPOT_TGBAALGOS_REDUCERUN_HH #endif // SPOT_TGBAALGOS_REDUCERUN_HH

View file

@ -32,7 +32,8 @@ namespace spot
namespace namespace
{ {
void void
print_annotation(std::ostream& os, const_tgba_ptr a, print_annotation(std::ostream& os,
const const_tgba_ptr& a,
const tgba_succ_iterator* i) const tgba_succ_iterator* i)
{ {
std::string s = a->transition_annotation(i); std::string s = a->transition_annotation(i);
@ -44,7 +45,7 @@ namespace spot
bool bool
replay_tgba_run(std::ostream& os, const const_tgba_ptr& a, replay_tgba_run(std::ostream& os, const const_tgba_ptr& a,
const tgba_run* run, bool debug) const const_tgba_run_ptr& run, bool debug)
{ {
const state* s = a->get_init_state(); const state* s = a->get_init_state();
int serial = 1; int serial = 1;

View file

@ -26,6 +26,7 @@
# include "misc/common.hh" # include "misc/common.hh"
# include <iosfwd> # include <iosfwd>
# include "tgba/fwd.hh" # include "tgba/fwd.hh"
# include "tgbaalgos/emptiness.hh"
namespace spot namespace spot
{ {
@ -48,7 +49,8 @@ namespace spot
/// \return true iff the run could be completed /// \return true iff the run could be completed
SPOT_API bool SPOT_API bool
replay_tgba_run(std::ostream& os, replay_tgba_run(std::ostream& os,
const const_tgba_ptr& a, const tgba_run* run, const const_tgba_ptr& a,
const const_tgba_run_ptr& run,
bool debug = false); bool debug = false);
} }

View file

@ -26,7 +26,8 @@
namespace spot namespace spot
{ {
tgba_run_dotty_decorator::tgba_run_dotty_decorator(const tgba_run* run) tgba_run_dotty_decorator::tgba_run_dotty_decorator(const
const_tgba_run_ptr& run)
: run_(run) : run_(run)
{ {
int n = 1; int n = 1;

View file

@ -38,7 +38,7 @@ namespace spot
class SPOT_API tgba_run_dotty_decorator: public dotty_decorator class SPOT_API tgba_run_dotty_decorator: public dotty_decorator
{ {
public: public:
tgba_run_dotty_decorator(const tgba_run* run); tgba_run_dotty_decorator(const const_tgba_run_ptr& run);
virtual ~tgba_run_dotty_decorator(); virtual ~tgba_run_dotty_decorator();
virtual std::string state_decl(const const_tgba_ptr& a, virtual std::string state_decl(const const_tgba_ptr& a,
@ -52,7 +52,7 @@ namespace spot
const tgba_succ_iterator* si, const tgba_succ_iterator* si,
const std::string& label); const std::string& label);
private: private:
const tgba_run* run_; const_tgba_run_ptr run_;
typedef std::pair<tgba_run::steps::const_iterator, int> step_num; typedef std::pair<tgba_run::steps::const_iterator, int> step_num;
typedef std::list<step_num> step_set; typedef std::list<step_num> step_set;
typedef std::map<const state*, std::pair<step_set, step_set>, typedef std::map<const state*, std::pair<step_set, step_set>,

View file

@ -88,8 +88,10 @@ namespace spot
/// check() can be called several times (until it returns a null /// check() can be called several times (until it returns a null
/// pointer) to enumerate all the visited accepting paths. The method /// pointer) to enumerate all the visited accepting paths. The method
/// visits only a finite set of accepting paths. /// visits only a finite set of accepting paths.
virtual emptiness_check_result* check() virtual emptiness_check_result_ptr check()
{ {
auto t = std::static_pointer_cast<se05_search>
(this->emptiness_check::shared_from_this());
if (st_red.empty()) if (st_red.empty())
{ {
assert(st_blue.empty()); assert(st_blue.empty());
@ -98,17 +100,17 @@ namespace spot
h.add_new_state(s0, CYAN); h.add_new_state(s0, CYAN);
push(st_blue, s0, bddfalse, bddfalse); push(st_blue, s0, bddfalse, bddfalse);
if (dfs_blue()) if (dfs_blue())
return new se05_result(*this, options()); return std::make_shared<se05_result>(t, options());
} }
else else
{ {
h.pop_notify(st_red.front().s); h.pop_notify(st_red.front().s);
pop(st_red); pop(st_red);
if (!st_red.empty() && dfs_red()) if (!st_red.empty() && dfs_red())
return new se05_result(*this, options()); return std::make_shared<se05_result>(t, options());
else else
if (dfs_blue()) if (dfs_blue())
return new se05_result(*this, options()); return std::make_shared<se05_result>(t, options());
} }
return 0; return 0;
} }
@ -330,27 +332,27 @@ namespace spot
public acss_statistics public acss_statistics
{ {
public: public:
result_from_stack(se05_search& ms) result_from_stack(const std::shared_ptr<se05_search>& ms)
: emptiness_check_result(ms.automaton()), ms_(ms) : emptiness_check_result(ms->automaton()), ms_(ms)
{ {
} }
virtual tgba_run* accepting_run() virtual tgba_run_ptr accepting_run()
{ {
assert(!ms_.st_blue.empty()); assert(!ms_->st_blue.empty());
assert(!ms_.st_red.empty()); assert(!ms_->st_red.empty());
tgba_run* run = new tgba_run; auto run = std::make_shared<tgba_run>();
typename stack_type::const_reverse_iterator i, j, end; typename stack_type::const_reverse_iterator i, j, end;
tgba_run::steps* l; tgba_run::steps* l;
const state* target = ms_.st_red.front().s; const state* target = ms_->st_red.front().s;
l = &run->prefix; l = &run->prefix;
i = ms_.st_blue.rbegin(); i = ms_->st_blue.rbegin();
end = ms_.st_blue.rend(); --end; end = ms_->st_blue.rend(); --end;
j = i; ++j; j = i; ++j;
for (; i != end; ++i, ++j) for (; i != end; ++i, ++j)
{ {
@ -364,12 +366,12 @@ namespace spot
l = &run->cycle; l = &run->cycle;
assert(l == &run->cycle); assert(l == &run->cycle);
j = ms_.st_red.rbegin(); j = ms_->st_red.rbegin();
tgba_run::step s = { i->s->clone(), j->label, j->acc }; tgba_run::step s = { i->s->clone(), j->label, j->acc };
l->push_back(s); l->push_back(s);
i = j; ++j; i = j; ++j;
end = ms_.st_red.rend(); --end; end = ms_->st_red.rend(); --end;
for (; i != end; ++i, ++j) for (; i != end; ++i, ++j)
{ {
tgba_run::step s = { i->s->clone(), j->label, j->acc }; tgba_run::step s = { i->s->clone(), j->label, j->acc };
@ -384,7 +386,7 @@ namespace spot
return 0; return 0;
} }
private: private:
se05_search& ms_; std::shared_ptr<se05_search> ms_;
}; };
# define FROM_STACK "ar:from_stack" # define FROM_STACK "ar:from_stack"
@ -392,8 +394,9 @@ namespace spot
class se05_result: public emptiness_check_result class se05_result: public emptiness_check_result
{ {
public: public:
se05_result(se05_search& m, option_map o = option_map()) se05_result(const std::shared_ptr<se05_search>& m,
: emptiness_check_result(m.automaton(), o), ms(m) option_map o = option_map())
: emptiness_check_result(m->automaton(), o), ms(m)
{ {
if (options()[FROM_STACK]) if (options()[FROM_STACK])
computer = new result_from_stack(ms); computer = new result_from_stack(ms);
@ -420,7 +423,7 @@ namespace spot
delete computer; delete computer;
} }
virtual tgba_run* accepting_run() virtual tgba_run_ptr accepting_run()
{ {
return computer->accepting_run(); return computer->accepting_run();
} }
@ -432,7 +435,7 @@ namespace spot
private: private:
emptiness_check_result* computer; emptiness_check_result* computer;
se05_search& ms; std::shared_ptr<se05_search> ms;
}; };
}; };
@ -675,19 +678,20 @@ namespace spot
} // anonymous } // anonymous
emptiness_check* explicit_se05_search(const const_tgba_ptr& a, option_map o) emptiness_check_ptr
explicit_se05_search(const const_tgba_ptr& a, option_map o)
{ {
return new se05_search<explicit_se05_search_heap>(a, 0, o); return std::make_shared<se05_search<explicit_se05_search_heap>>(a, 0, o);
} }
emptiness_check* bit_state_hashing_se05_search(const const_tgba_ptr& a, emptiness_check_ptr
size_t size, bit_state_hashing_se05_search(const const_tgba_ptr& a,
option_map o) size_t size, option_map o)
{ {
return new se05_search<bsh_se05_search_heap>(a, size, o); return std::make_shared<se05_search<bsh_se05_search_heap>>(a, size, o);
} }
emptiness_check* emptiness_check_ptr
se05(const const_tgba_ptr& a, option_map o) se05(const const_tgba_ptr& a, option_map o)
{ {
size_t size = o.get("bsh"); size_t size = o.get("bsh");

View file

@ -26,11 +26,10 @@
# include <cstddef> # include <cstddef>
# include "misc/optionmap.hh" # include "misc/optionmap.hh"
# include "tgba/fwd.hh" # include "tgba/fwd.hh"
# include "emptiness.hh"
namespace spot namespace spot
{ {
class emptiness_check;
/// \addtogroup emptiness_check_algorithms /// \addtogroup emptiness_check_algorithms
/// @{ /// @{
@ -102,7 +101,7 @@ namespace spot
/// ///
/// \sa spot::explicit_magic_search /// \sa spot::explicit_magic_search
/// ///
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
explicit_se05_search(const const_tgba_ptr& a, option_map o = option_map()); explicit_se05_search(const const_tgba_ptr& a, option_map o = option_map());
/// \brief Returns an emptiness checker on the spot::tgba automaton \a a. /// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
@ -132,7 +131,7 @@ namespace spot
/// ///
/// \sa spot::explicit_se05_search /// \sa spot::explicit_se05_search
/// ///
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
bit_state_hashing_se05_search(const const_tgba_ptr& a, size_t size, bit_state_hashing_se05_search(const const_tgba_ptr& a, size_t size,
option_map o = option_map()); option_map o = option_map());
@ -143,7 +142,7 @@ namespace spot
/// bit_state_hashing_se05_search() according to the \c "bsh" option /// bit_state_hashing_se05_search() according to the \c "bsh" option
/// in the \c option_map. If \c "bsh" is set and non null, its value /// in the \c option_map. If \c "bsh" is set and non null, its value
/// is used as the size of the hash map. /// is used as the size of the hash map.
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
se05(const const_tgba_ptr& a, option_map o); se05(const const_tgba_ptr& a, option_map o);
/// @} /// @}

View file

@ -83,18 +83,20 @@ namespace spot
/// ///
/// \return non null pointer iff the algorithm has found an /// \return non null pointer iff the algorithm has found an
/// accepting path. /// accepting path.
virtual emptiness_check_result* check() virtual emptiness_check_result_ptr check()
{ {
if (!st_blue.empty()) if (!st_blue.empty())
return 0; return nullptr;
assert(st_red.empty()); assert(st_red.empty());
const state* s0 = a_->get_init_state(); const state* s0 = a_->get_init_state();
inc_states(); inc_states();
h.add_new_state(s0, BLUE); h.add_new_state(s0, BLUE);
push(st_blue, s0, bddfalse, bddfalse); push(st_blue, s0, bddfalse, bddfalse);
auto t = std::static_pointer_cast<tau03_search>
(this->emptiness_check::shared_from_this());
if (dfs_blue()) if (dfs_blue())
return new ndfs_result<tau03_search<heap>, heap>(*this); return std::make_shared<ndfs_result<tau03_search<heap>, heap>>(t);
return 0; return nullptr;
} }
virtual std::ostream& print_stats(std::ostream &os) const virtual std::ostream& print_stats(std::ostream &os) const
@ -374,9 +376,10 @@ namespace spot
} // anonymous } // anonymous
emptiness_check* explicit_tau03_search(const const_tgba_ptr& a, option_map o) emptiness_check_ptr
explicit_tau03_search(const const_tgba_ptr& a, option_map o)
{ {
return new tau03_search<explicit_tau03_search_heap>(a, 0, o); return std::make_shared<tau03_search<explicit_tau03_search_heap>>(a, 0, o);
} }
} }

View file

@ -25,11 +25,10 @@
# include "misc/optionmap.hh" # include "misc/optionmap.hh"
# include "tgba/fwd.hh" # include "tgba/fwd.hh"
# include "emptiness.hh"
namespace spot namespace spot
{ {
class emptiness_check;
/// \addtogroup emptiness_check_algorithms /// \addtogroup emptiness_check_algorithms
/// @{ /// @{
@ -96,7 +95,7 @@ namespace spot
} }
\endverbatim */ \endverbatim */
/// ///
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
explicit_tau03_search(const const_tgba_ptr& a, option_map o = option_map()); explicit_tau03_search(const const_tgba_ptr& a, option_map o = option_map());
/// @} /// @}

View file

@ -108,18 +108,20 @@ namespace spot
/// ///
/// \return non null pointer iff the algorithm has found an /// \return non null pointer iff the algorithm has found an
/// accepting path. /// accepting path.
virtual emptiness_check_result* check() virtual emptiness_check_result_ptr check()
{ {
if (!st_blue.empty()) if (!st_blue.empty())
return 0; return nullptr;
assert(st_red.empty()); assert(st_red.empty());
const state* s0 = a_->get_init_state(); const state* s0 = a_->get_init_state();
inc_states(); inc_states();
h.add_new_state(s0, CYAN, current_weight); h.add_new_state(s0, CYAN, current_weight);
push(st_blue, s0, bddfalse, bddfalse); push(st_blue, s0, bddfalse, bddfalse);
auto t = std::static_pointer_cast<tau03_opt_search>
(this->emptiness_check::shared_from_this());
if (dfs_blue()) if (dfs_blue())
return new ndfs_result<tau03_opt_search<heap>, heap>(*this); return std::make_shared<ndfs_result<tau03_opt_search<heap>, heap>>(t);
return 0; return nullptr;
} }
virtual std::ostream& print_stats(std::ostream &os) const virtual std::ostream& print_stats(std::ostream &os) const
@ -572,10 +574,12 @@ namespace spot
} // anonymous } // anonymous
emptiness_check* explicit_tau03_opt_search(const const_tgba_ptr& a, emptiness_check_ptr
option_map o) explicit_tau03_opt_search(const const_tgba_ptr& a, option_map o)
{ {
return new tau03_opt_search<explicit_tau03_opt_search_heap>(a, 0, o); return
std::make_shared<tau03_opt_search<explicit_tau03_opt_search_heap>>(a,
0, o);
} }
} }

View file

@ -25,11 +25,10 @@
# include "misc/optionmap.hh" # include "misc/optionmap.hh"
# include "tgba/fwd.hh" # include "tgba/fwd.hh"
# include "emptiness.hh"
namespace spot namespace spot
{ {
class emptiness_check;
/// \addtogroup emptiness_check_algorithms /// \addtogroup emptiness_check_algorithms
/// @{ /// @{
@ -98,7 +97,7 @@ namespace spot
/// the path stored in the blue stack. Such a vector is associated to each /// the path stored in the blue stack. Such a vector is associated to each
/// state of this stack. /// state of this stack.
/// ///
SPOT_API emptiness_check* SPOT_API emptiness_check_ptr
explicit_tau03_opt_search(const const_tgba_ptr& a, explicit_tau03_opt_search(const const_tgba_ptr& a,
option_map o = option_map()); option_map o = option_map());

View file

@ -23,7 +23,7 @@
namespace spot namespace spot
{ {
tgba_word::tgba_word(const tgba_run* run) tgba_word::tgba_word(const tgba_run_ptr run)
{ {
for (tgba_run::steps::const_iterator i = run->prefix.begin(); for (tgba_run::steps::const_iterator i = run->prefix.begin();
i != run->prefix.end(); ++i) i != run->prefix.end(); ++i)

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2013 Laboratoire de Recherche et Développement de // Copyright (C) 2013, 2014 Laboratoire de Recherche et Développement de
// l'Epita (LRDE). // l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -29,7 +29,7 @@ namespace spot
/// \brief An infinite word stored as a lasso. /// \brief An infinite word stored as a lasso.
struct SPOT_API tgba_word struct SPOT_API tgba_word
{ {
tgba_word(const tgba_run* run); tgba_word(const tgba_run_ptr run);
void simplify(); void simplify();
std::ostream& print(std::ostream& os, const bdd_dict_ptr& d) const; std::ostream& print(std::ostream& os, const bdd_dict_ptr& d) const;

View file

@ -29,7 +29,6 @@
#include "tgbaalgos/ltl2taa.hh" #include "tgbaalgos/ltl2taa.hh"
#include "tgbaalgos/sccfilter.hh" #include "tgbaalgos/sccfilter.hh"
#include "tgba/tgbaproduct.hh" #include "tgba/tgbaproduct.hh"
#include "tgbaalgos/gtec/gtec.hh"
#include "tgbaalgos/dotty.hh" #include "tgbaalgos/dotty.hh"
#include "tgbaalgos/dupexp.hh" #include "tgbaalgos/dupexp.hh"
@ -76,14 +75,11 @@ main(int argc, char** argv)
{ {
auto apos = scc_filter(ltl_to_tgba_fm(fpos, d)); auto apos = scc_filter(ltl_to_tgba_fm(fpos, d));
auto aneg = scc_filter(ltl_to_tgba_fm(fneg, d)); auto aneg = scc_filter(ltl_to_tgba_fm(fneg, d));
auto ec = spot::couvreur99(spot::product(apos, aneg)); if (!spot::product(apos, aneg)->is_empty())
auto res = ec->check();
if (res)
{ {
std::cerr << "non-empty intersection between pos and neg (FM)\n"; std::cerr << "non-empty intersection between pos and neg (FM)\n";
exit(2); exit(2);
} }
delete ec;
// Run make_future_conditions_collector, without testing the output. // Run make_future_conditions_collector, without testing the output.
auto fc = spot::make_future_conditions_collector(apos, true); auto fc = spot::make_future_conditions_collector(apos, true);
@ -93,28 +89,22 @@ main(int argc, char** argv)
{ {
auto apos = scc_filter(ltl_to_tgba_fm(fpos, d, true)); auto apos = scc_filter(ltl_to_tgba_fm(fpos, d, true));
auto aneg = scc_filter(ltl_to_tgba_fm(fneg, d, true)); auto aneg = scc_filter(ltl_to_tgba_fm(fneg, d, true));
auto ec = spot::couvreur99(spot::product(apos, aneg)); if (!spot::product(apos, aneg)->is_empty())
auto res = ec->check();
if (res)
{ {
std::cerr << "non-empty intersection between pos and neg (FM -x)\n"; std::cerr << "non-empty intersection between pos and neg (FM -x)\n";
exit(2); exit(2);
} }
delete ec;
} }
if (fpos->is_ltl_formula()) if (fpos->is_ltl_formula())
{ {
auto apos = scc_filter(spot::tgba_dupexp_dfs(ltl_to_taa(fpos, d))); auto apos = scc_filter(spot::tgba_dupexp_dfs(ltl_to_taa(fpos, d)));
auto aneg = scc_filter(spot::tgba_dupexp_dfs(ltl_to_taa(fneg, d))); auto aneg = scc_filter(spot::tgba_dupexp_dfs(ltl_to_taa(fneg, d)));
auto ec = spot::couvreur99(spot::product(apos, aneg)); if (!spot::product(apos, aneg)->is_empty())
auto res = ec->check();
if (res)
{ {
std::cerr << "non-empty intersection between pos and neg (TAA)\n"; std::cerr << "non-empty intersection between pos and neg (TAA)\n";
exit(2); exit(2);
} }
delete ec;
} }
fpos->destroy(); fpos->destroy();
fneg->destroy(); fneg->destroy();

View file

@ -274,8 +274,8 @@ int main(int argc, char* argv[])
nAf = spot::make_kv_complement(Af); nAf = spot::make_kv_complement(Af);
nAnf = spot::make_kv_complement(Anf); nAnf = spot::make_kv_complement(Anf);
} }
spot::emptiness_check* ec = spot::couvreur99(spot::product(nAf, nAnf)); auto ec = spot::couvreur99(spot::product(nAf, nAnf));
spot::emptiness_check_result* res = ec->check(); auto res = ec->check();
spot::tgba_statistics a_size = spot::stats_reachable(ec->automaton()); spot::tgba_statistics a_size = spot::stats_reachable(ec->automaton());
std::cout << "States: " std::cout << "States: "
<< a_size.states << std::endl << a_size.states << std::endl
@ -292,12 +292,8 @@ int main(int argc, char* argv[])
else else
std::cout << "OK"; std::cout << "OK";
std::cout << std::endl; std::cout << std::endl;
delete res;
delete ec;
nf1->destroy(); nf1->destroy();
f1->destroy(); f1->destroy();
} }
return return_value; return return_value;

View file

@ -122,7 +122,7 @@ main(int argc, char** argv)
for (auto& algo: algos) for (auto& algo: algos)
{ {
const char* err; const char* err;
auto i = spot::emptiness_check_instantiator::construct(algo, &err); auto i = spot::make_emptiness_check_instantiator(algo, &err);
if (!i) if (!i)
{ {
std::cerr << "Failed to parse `" << err << '\'' << std::endl; std::cerr << "Failed to parse `" << err << '\'' << std::endl;
@ -157,17 +157,14 @@ main(int argc, char** argv)
int ce_found = 0; int ce_found = 0;
do do
{ {
auto res = ec->check(); if (auto res = ec->check())
if (res)
{ {
++ce_found; ++ce_found;
std::cout << ce_found << " counterexample found\n"; std::cout << ce_found << " counterexample found\n";
auto run = res->accepting_run(); if (auto run = res->accepting_run())
if (run)
{ {
auto ar = spot::tgba_run_to_tgba(a, run); auto ar = spot::tgba_run_to_tgba(a, run);
spot::dotty_reachable(std::cout, ar, false); spot::dotty_reachable(std::cout, ar, false);
delete run;
} }
std::cout << '\n'; std::cout << '\n';
if (runs == 0) if (runs == 0)
@ -175,7 +172,6 @@ main(int argc, char** argv)
std::cerr << "ERROR: Expected no counterexample.\n"; std::cerr << "ERROR: Expected no counterexample.\n";
exit(1); exit(1);
} }
delete res;
} }
else else
{ {
@ -201,10 +197,7 @@ main(int argc, char** argv)
std::cerr << "ERROR: expected a counterexample.\n"; std::cerr << "ERROR: expected a counterexample.\n";
exit(1); exit(1);
} }
delete ec;
} }
delete i;
} }
f->destroy(); f->destroy();
} }

View file

@ -354,7 +354,7 @@ checked_main(int argc, char** argv)
int output = 0; int output = 0;
int formula_index = 0; int formula_index = 0;
const char* echeck_algo = 0; const char* echeck_algo = 0;
spot::emptiness_check_instantiator* echeck_inst = 0; spot::emptiness_check_instantiator_ptr echeck_inst = 0;
enum { NoneDup, BFS, DFS } dupexp = NoneDup; enum { NoneDup, BFS, DFS } dupexp = NoneDup;
bool expect_counter_example = false; bool expect_counter_example = false;
bool accepting_run = false; bool accepting_run = false;
@ -500,7 +500,7 @@ checked_main(int argc, char** argv)
const char* err; const char* err;
echeck_inst = echeck_inst =
spot::emptiness_check_instantiator::construct(echeck_algo, &err); spot::make_emptiness_check_instantiator(echeck_algo, &err);
if (!echeck_inst) if (!echeck_inst)
{ {
std::cerr << "Failed to parse argument of -e near `" std::cerr << "Failed to parse argument of -e near `"
@ -518,7 +518,7 @@ checked_main(int argc, char** argv)
const char* err; const char* err;
echeck_inst = echeck_inst =
spot::emptiness_check_instantiator::construct(echeck_algo, &err); spot::make_emptiness_check_instantiator(echeck_algo, &err);
if (!echeck_inst) if (!echeck_inst)
{ {
std::cerr << "Failed to parse argument of -e near `" std::cerr << "Failed to parse argument of -e near `"
@ -1713,13 +1713,13 @@ checked_main(int argc, char** argv)
if (echeck_inst) if (echeck_inst)
{ {
spot::emptiness_check* ec = echeck_inst->instantiate(a); auto ec = echeck_inst->instantiate(a);
bool search_many = echeck_inst->options().get("repeated"); bool search_many = echeck_inst->options().get("repeated");
assert(ec); assert(ec);
do do
{ {
tm.start("running emptiness check"); tm.start("running emptiness check");
spot::emptiness_check_result* res = ec->check(); auto res = ec->check();
tm.stop("running emptiness check"); tm.stop("running emptiness check");
if (paper_opt) if (paper_opt)
@ -1736,8 +1736,7 @@ checked_main(int argc, char** argv)
std::cout << std::cout <<
ec->automaton()->number_of_acceptance_conditions() ec->automaton()->number_of_acceptance_conditions()
<< ", "; << ", ";
const spot::ec_statistics* ecs = auto ecs = ec->emptiness_check_statistics();
dynamic_cast<const spot::ec_statistics*>(ec);
if (ecs) if (ecs)
std::cout << std::right << std::setw(10) std::cout << std::right << std::setw(10)
<< ecs->states() << ", " << ecs->states() << ", "
@ -1781,7 +1780,7 @@ checked_main(int argc, char** argv)
{ {
tm.start("computing accepting run"); tm.start("computing accepting run");
spot::tgba_run* run = res->accepting_run(); auto run = res->accepting_run();
tm.stop("computing accepting run"); tm.stop("computing accepting run");
if (!run) if (!run)
@ -1793,11 +1792,8 @@ checked_main(int argc, char** argv)
if (opt_reduce) if (opt_reduce)
{ {
tm.start("reducing accepting run"); tm.start("reducing accepting run");
spot::tgba_run* redrun = run = spot::reduce_run(res->automaton(), run);
spot::reduce_run(res->automaton(), run);
tm.stop("reducing accepting run"); tm.stop("reducing accepting run");
delete run;
run = redrun;
} }
if (accepting_run_replay) if (accepting_run_replay)
{ {
@ -1827,7 +1823,6 @@ checked_main(int argc, char** argv)
} }
tm.stop("printing accepting run"); tm.stop("printing accepting run");
} }
delete run;
} }
} }
else else
@ -1836,14 +1831,11 @@ checked_main(int argc, char** argv)
<< "(use -C to print it)" << std::endl; << "(use -C to print it)" << std::endl;
} }
} }
delete res;
} }
while (search_many); while (search_many);
delete ec;
} }
if (f) if (f)
f->destroy(); f->destroy();
delete echeck_inst;
} }
else else
{ {

View file

@ -59,7 +59,7 @@
struct ec_algo struct ec_algo
{ {
std::string name; std::string name;
spot::emptiness_check_instantiator* inst; spot::emptiness_check_instantiator_ptr inst;
}; };
const char* default_algos[] = { const char* default_algos[] = {
@ -84,12 +84,12 @@ const char* default_algos[] = {
std::vector<ec_algo> ec_algos; std::vector<ec_algo> ec_algos;
spot::emptiness_check* spot::emptiness_check_ptr
cons_emptiness_check(int num, spot::const_tgba_ptr a, cons_emptiness_check(int num, spot::const_tgba_ptr a,
const spot::const_tgba_ptr& degen, const spot::const_tgba_ptr& degen,
unsigned int n_acc) unsigned int n_acc)
{ {
spot::emptiness_check_instantiator* inst = ec_algos[num].inst; auto inst = ec_algos[num].inst;
if (n_acc < inst->min_acceptance_conditions() if (n_acc < inst->min_acceptance_conditions()
|| n_acc > inst->max_acceptance_conditions()) || n_acc > inst->max_acceptance_conditions())
a = degen; a = degen;
@ -380,7 +380,7 @@ struct ar_stat
} }
void void
count(const spot::tgba_run* run) count(const spot::const_tgba_run_ptr& run)
{ {
int p = run->prefix.size(); int p = run->prefix.size();
int c = run->cycle.size(); int c = run->cycle.size();
@ -837,9 +837,8 @@ main(int argc, char** argv)
{ {
const char* err; const char* err;
ec_algos[i].inst = ec_algos[i].inst =
spot::emptiness_check_instantiator::construct(ec_algos[i] spot::make_emptiness_check_instantiator(ec_algos[i].name.c_str(),
.name.c_str(), &err);
&err);
if (ec_algos[i].inst == 0) if (ec_algos[i].inst == 0)
{ {
std::cerr << "Parse error after `" << err << '\'' << std::endl; std::cerr << "Parse error after `" << err << '\'' << std::endl;
@ -939,9 +938,7 @@ main(int argc, char** argv)
for (int i = 0; i < n_alg; ++i) for (int i = 0; i < n_alg; ++i)
{ {
spot::emptiness_check* ec; auto ec = cons_emptiness_check(i, a, degen, real_n_acc);
spot::emptiness_check_result* res;
ec = cons_emptiness_check(i, a, degen, real_n_acc);
if (!ec) if (!ec)
continue; continue;
++n_ec; ++n_ec;
@ -952,17 +949,16 @@ main(int argc, char** argv)
std::cout << algo << ": "; std::cout << algo << ": ";
} }
tm_ec.start(algo); tm_ec.start(algo);
spot::emptiness_check_result_ptr res;
for (int count = opt_R;;) for (int count = opt_R;;)
{ {
res = ec->check(); res = ec->check();
if (count-- <= 0) if (count-- <= 0)
break; break;
delete res;
delete ec;
ec = cons_emptiness_check(i, a, degen, real_n_acc); ec = cons_emptiness_check(i, a, degen, real_n_acc);
} }
tm_ec.stop(algo); tm_ec.stop(algo);
const spot::unsigned_statistics* ecs = ec->statistics(); auto ecs = ec->statistics();
if (opt_z && res) if (opt_z && res)
{ {
// Notice that ratios are computed w.r.t. the // Notice that ratios are computed w.r.t. the
@ -1001,7 +997,7 @@ main(int argc, char** argv)
++n_non_empty; ++n_non_empty;
if (opt_replay) if (opt_replay)
{ {
spot::tgba_run* run; spot::tgba_run_ptr run;
bool done = false; bool done = false;
tm_ar.start(algo); tm_ar.start(algo);
for (int count = opt_R;;) for (int count = opt_R;;)
@ -1030,7 +1026,6 @@ main(int argc, char** argv)
if (count-- <= 0 || !run) if (count-- <= 0 || !run)
break; break;
delete run;
} }
if (!run) if (!run)
{ {
@ -1065,7 +1060,7 @@ main(int argc, char** argv)
if (opt_reduce) if (opt_reduce)
{ {
spot::tgba_run* redrun = auto redrun =
spot::reduce_run(res->automaton(), run); spot::reduce_run(res->automaton(), run);
if (!spot::replay_tgba_run(s, if (!spot::replay_tgba_run(s,
res res
@ -1093,14 +1088,11 @@ main(int argc, char** argv)
<< redrun->cycle.size() << redrun->cycle.size()
<< ']'; << ']';
} }
delete redrun;
} }
delete run;
} }
} }
if (!opt_paper) if (!opt_paper)
std::cout << std::endl; std::cout << std::endl;
delete res;
} }
else else
{ {
@ -1122,7 +1114,6 @@ main(int argc, char** argv)
if (opt_Z && !opt_paper) if (opt_Z && !opt_paper)
ec->print_stats(std::cout); ec->print_stats(std::cout);
delete ec;
} }
assert(n_empty + n_non_empty + n_maybe_empty == n_ec); assert(n_empty + n_non_empty + n_maybe_empty == n_ec);
@ -1310,10 +1301,6 @@ main(int argc, char** argv)
delete formula_file; delete formula_file;
} }
if (opt_ec)
for (unsigned i = 0; i < ec_algos.size(); ++i)
delete ec_algos[i].inst;
delete ap; delete ap;
delete apf; delete apf;
return exit_code; return exit_code;

View file

@ -102,7 +102,6 @@ if not script:
httpd.serve_forever() httpd.serve_forever()
import cgi import cgi
import cgitb; cgitb.enable()
import signal import signal
import time import time
import os.path import os.path
@ -120,6 +119,9 @@ sys.stdout = os.fdopen(sys.stdout.fileno(), "wb", 0)
# even errors from subprocesses get printed). # even errors from subprocesses get printed).
os.dup2(sys.stdout.fileno(), sys.stderr.fileno()) os.dup2(sys.stdout.fileno(), sys.stderr.fileno())
import cgitb
sys.excepthook = cgitb.Hook(file=sys.stderr)
# Create the temporary cache directory # Create the temporary cache directory
os.mkdir(tmpdir, 493) # See comment above about 0o755 or 0755. os.mkdir(tmpdir, 493) # See comment above about 0o755 or 0755.
@ -533,7 +535,7 @@ elif translator == 'ta':
refined_rules = False refined_rules = False
if form.getfirst('ta', '') == 'lc': if form.getfirst('ta', '') == 'lc':
refined_rules = True refined_rules = True
automaton = spot.ltl_to_taa(f, dict, refined_rules) automaton = spot.tgba_dupexp_dfs(spot.ltl_to_taa(f, dict, refined_rules))
elif translator == 'l3': elif translator == 'l3':
l3out = '-T' l3out = '-T'
l3opt = { '-l', '-P', '-A', '-c', '-C', '-o', '-p' } l3opt = { '-l', '-P', '-A', '-c', '-C', '-o', '-p' }
@ -770,7 +772,7 @@ if output_type == 'r':
err = "" err = ""
opt = (form.getfirst('ec', 'Cou99') + "(" + opt = (form.getfirst('ec', 'Cou99') + "(" +
form.getfirst('eo', '') + ")") form.getfirst('eo', '') + ")")
eci, err = spot.emptiness_check_instantiator.construct(opt) eci, err = spot.make_emptiness_check_instantiator(opt)
if not eci: if not eci:
unbufprint('<div class="parse-error">Cannot parse "' + opt unbufprint('<div class="parse-error">Cannot parse "' + opt
@ -824,8 +826,4 @@ if output_type == 'r':
del ec_run del ec_run
del ec_res del ec_res
unbufprint('</div>') unbufprint('</div>')
del ec
del ec_a
degen = 0
automaton = 0
finish() finish()

View file

@ -36,7 +36,6 @@
// sed 's/.*<\(.*\)>.*/%shared_ptr(spot::\1)/g' // sed 's/.*<\(.*\)>.*/%shared_ptr(spot::\1)/g'
%shared_ptr(spot::bdd_dict) %shared_ptr(spot::bdd_dict)
%shared_ptr(spot::dstar_aut) %shared_ptr(spot::dstar_aut)
%shared_ptr(spot::dstar_aut)
%shared_ptr(spot::future_conditions_collector) %shared_ptr(spot::future_conditions_collector)
%shared_ptr(spot::kripke) %shared_ptr(spot::kripke)
%shared_ptr(spot::saba) %shared_ptr(spot::saba)
@ -56,6 +55,10 @@
%shared_ptr(spot::tgba_sgba_proxy) %shared_ptr(spot::tgba_sgba_proxy)
%shared_ptr(spot::tgta) %shared_ptr(spot::tgta)
%shared_ptr(spot::tgta_explicit) %shared_ptr(spot::tgta_explicit)
%shared_ptr(spot::tgba_run)
%shared_ptr(spot::emptiness_check)
%shared_ptr(spot::emptiness_check_result)
%shared_ptr(spot::emptiness_check_instantiator)
namespace std { namespace std {
%template(liststr) list<string>; %template(liststr) list<string>;
@ -203,19 +206,8 @@ using namespace spot;
%include "ltlvisit/simplify.hh" %include "ltlvisit/simplify.hh"
%include "ltlvisit/tostring.hh" %include "ltlvisit/tostring.hh"
%include "ltlvisit/tunabbrev.hh" %include "ltlvisit/tunabbrev.hh"
%include "ltlvisit/apcollect.hh"
%include "ltlvisit/lbt.hh" %include "ltlvisit/lbt.hh"
%feature("new") spot::emptiness_check::check;
%feature("new") spot::emptiness_check_instantiator::construct;
%feature("new") spot::emptiness_check_instantiator::instanciate;
%feature("new") spot::emptiness_check_result::accepting_run;
%feature("new") spot::explicit_magic_search;
%feature("new") spot::explicit_se05_search;
%feature("new") spot::tgba::get_init_state;
%feature("new") spot::tgba::succ_iter;
%feature("new") spot::tgba_succ_iterator::current_state;
// Help SWIG with namespace lookups. // Help SWIG with namespace lookups.
#define ltl spot::ltl #define ltl spot::ltl
%include "tgba/bddprint.hh" %include "tgba/bddprint.hh"
@ -232,6 +224,9 @@ namespace spot {
}; };
} }
// Should come after the definition of tgba_digraph
%include "ltlvisit/apcollect.hh"
%include "tgbaalgos/degen.hh" %include "tgbaalgos/degen.hh"
%include "tgbaalgos/dottydec.hh" %include "tgbaalgos/dottydec.hh"
%include "tgbaalgos/dotty.hh" %include "tgbaalgos/dotty.hh"