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

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

View file

@ -34,6 +34,8 @@
namespace spot
{
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
/// \ingroup tgba_algorithms
@ -99,7 +101,7 @@ namespace spot
/// cannot produce a counter example (that does not mean there
/// is no counter-example; the mere existence of an instance of
/// 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.
const const_tgba_ptr&
@ -129,8 +131,11 @@ namespace spot
option_map o_; ///< The options.
};
typedef std::shared_ptr<emptiness_check_result> emptiness_check_result_ptr;
/// 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:
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
/// hashing may return 0 even if the automaton is not empty.
/// \see safe()
virtual emptiness_check_result* check() = 0;
virtual emptiness_check_result_ptr check() = 0;
/// Return statistics, if available.
virtual const unsigned_statistics* statistics() const;
/// Return emptiness check statistics, if available.
virtual const ec_statistics* emptiness_check_statistics() const;
/// Print statistics, if any.
virtual std::ostream& print_stats(std::ostream& os) const;
@ -189,25 +197,18 @@ namespace spot
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.
class SPOT_API 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 const_tgba_ptr& a) const;
emptiness_check_ptr instantiate(const const_tgba_ptr& a) const;
/// Accessor to the options.
/// @{
@ -233,15 +234,27 @@ namespace spot
///
/// \return \c -1U if no upper bound exists.
unsigned int max_acceptance_conditions() const;
private:
protected:
emptiness_check_instantiator(option_map o, void* i);
option_map o_;
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
/// \ingroup emptiness_check
@ -287,14 +300,16 @@ namespace spot
/// actually exists in the automaton (and will also display any
/// transition annotation).
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
/// states are merged).
///
/// \pre \a run must correspond to an actual run of the automaton \a a.
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:
shortest_path(const state_set* t,
const couvreur99_check_status* ecs,
const std::shared_ptr<const couvreur99_check_status>& ecs,
couvreur99_check_result* r)
: bfs_steps(ecs->aut), target(t), ecs(ecs), r(r)
{
@ -68,13 +68,14 @@ namespace spot
private:
state_set seen;
const state_set* target;
const couvreur99_check_status* ecs;
std::shared_ptr<const couvreur99_check_status> ecs;
couvreur99_check_result* r;
};
}
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)
{
}
@ -90,10 +91,10 @@ namespace spot
return count;
}
tgba_run*
tgba_run_ptr
couvreur99_check_result::accepting_run()
{
run_ = new tgba_run;
run_ = std::make_shared<tgba_run>();
assert(!ecs_->root.empty());
@ -212,7 +213,7 @@ namespace spot
return false;
}
} b(ecs_, this, acc_to_traverse);
} b(ecs_.get(), this, acc_to_traverse);
substart = b.search(substart, run_->cycle);
assert(substart);

View file

@ -1,5 +1,5 @@
// -*- 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).
// Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -35,10 +35,11 @@ namespace spot
public acss_statistics
{
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());
virtual tgba_run* accepting_run();
virtual tgba_run_ptr accepting_run();
void print_stats(std::ostream& os) const;
@ -50,8 +51,8 @@ namespace spot
void accepting_cycle();
private:
const couvreur99_check_status* ecs_;
tgba_run* run_;
std::shared_ptr<const couvreur99_check_status> ecs_;
tgba_run_ptr run_;
};
}

View file

@ -45,7 +45,7 @@ namespace spot
removed_components(0)
{
poprem_ = o.get("poprem", 1);
ecs_ = new couvreur99_check_status(a);
ecs_ = std::make_shared<couvreur99_check_status>(a);
stats["removed components"] =
static_cast<spot::unsigned_statistics::unsigned_fun>
(&couvreur99_check::get_removed_components);
@ -56,7 +56,6 @@ namespace spot
couvreur99_check::~couvreur99_check()
{
delete ecs_;
}
unsigned
@ -129,7 +128,7 @@ namespace spot
}
}
emptiness_check_result*
emptiness_check_result_ptr
couvreur99_check::check()
{
// We use five main data in this algorithm:
@ -281,15 +280,15 @@ namespace spot
// cycle.
ecs_->cycle_seed = p.first->first;
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.
set_states(ecs_->states());
return 0;
return nullptr;
}
const couvreur99_check_status*
std::shared_ptr<const couvreur99_check_status>
couvreur99_check::result() const
{
return ecs_;
@ -383,7 +382,7 @@ namespace spot
}
}
emptiness_check_result*
emptiness_check_result_ptr
couvreur99_check_shy::check()
{
// Position in the loop seeking known successors.
@ -418,7 +417,7 @@ namespace spot
// This automaton recognizes no word.
set_states(ecs_->states());
assert(poprem_ || depth() == 0);
return 0;
return nullptr;
}
pos = todo.back().q.begin();
@ -554,7 +553,7 @@ namespace spot
// We have found an accepting SCC. Clean up TODO.
clear_todo();
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.
if (group_)
@ -592,12 +591,12 @@ namespace spot
}
}
emptiness_check*
emptiness_check_ptr
couvreur99(const const_tgba_ptr& a, option_map o)
{
if (o.get("shy"))
return new couvreur99_check_shy(a, o);
return new couvreur99_check(a, o);
return std::make_shared<couvreur99_check_shy>(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
/// choosing a successor. Otherwise, only the successor of the
/// 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());
#ifndef SWIG
/// \brief An implementation of the Couvreur99 emptiness-check algorithm.
///
/// See the documentation for spot::couvreur99.
@ -150,7 +150,7 @@ namespace spot
virtual ~couvreur99_check();
/// 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;
@ -162,10 +162,10 @@ namespace spot
/// This status should not be deleted, it is a pointer
/// to a member of this class that will be deleted when
/// the couvreur99 object is deleted.
const couvreur99_check_status* result() const;
std::shared_ptr<const couvreur99_check_status> result() const;
protected:
couvreur99_check_status* ecs_;
std::shared_ptr<couvreur99_check_status> ecs_;
/// \brief Remove a strongly component from the hash.
///
/// 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());
virtual ~couvreur99_check_shy();
virtual emptiness_check_result* check();
virtual emptiness_check_result_ptr check();
protected:
struct successor {
@ -239,7 +239,7 @@ namespace spot
// reprocess the successor states of SCC that have been merged.
bool group2_;
};
#endif
/// @}
}

View file

@ -91,7 +91,7 @@ namespace spot
}
}
virtual emptiness_check_result*
virtual emptiness_check_result_ptr
check()
{
top = dftop = -1;
@ -162,7 +162,7 @@ namespace spot
set_states(h.size());
}
if (violation)
return new result(*this);
return std::make_shared<result>(*this);
return 0;
}
@ -287,10 +287,10 @@ namespace spot
return s;
}
virtual tgba_run*
virtual tgba_run_ptr
accepting_run()
{
tgba_run* res = new tgba_run;
auto res = std::make_shared<tgba_run>();
update_lowlinks();
#ifdef TRACE
@ -409,9 +409,9 @@ namespace spot
} // anonymous
emptiness_check*
emptiness_check_ptr
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 "tgba/fwd.hh"
# include "emptiness.hh"
namespace spot
{
class emptiness_check;
/// \brief Emptiness check based on Geldenhuys and Valmari's
/// TACAS'04 paper.
/// \ingroup emptiness_check_algorithms
@ -54,7 +53,7 @@ namespace spot
isbn = {3-540-21299-X}
}
\endverbatim */
SPOT_API emptiness_check*
SPOT_API emptiness_check_ptr
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
/// pointer) to enumerate all the visited accepting paths. The method
/// 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())
{
assert(st_blue.empty());
@ -98,19 +100,19 @@ namespace spot
h.add_new_state(s0, BLUE);
push(st_blue, s0, bddfalse, bddfalse);
if (dfs_blue())
return new magic_search_result(*this, options());
return std::make_shared<magic_search_result>(t, options());
}
else
{
h.pop_notify(st_red.front().s);
pop(st_red);
if (!st_red.empty() && dfs_red())
return new magic_search_result(*this, options());
return std::make_shared<magic_search_result>(t, options());
else
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
@ -325,25 +327,25 @@ namespace spot
public acss_statistics
{
public:
result_from_stack(magic_search_& ms)
: emptiness_check_result(ms.automaton()), ms_(ms)
result_from_stack(std::shared_ptr<magic_search_> 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_red.empty());
assert(!ms_->st_blue.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;
tgba_run::steps* l;
l = &run->prefix;
i = ms_.st_blue.rbegin();
end = ms_.st_blue.rend(); --end;
i = ms_->st_blue.rbegin();
end = ms_->st_blue.rend(); --end;
j = i; ++j;
for (; i != end; ++i, ++j)
{
@ -353,12 +355,12 @@ namespace spot
l = &run->cycle;
j = ms_.st_red.rbegin();
j = ms_->st_red.rbegin();
tgba_run::step s = { i->s->clone(), j->label, j->acc };
l->push_back(s);
i = j; ++j;
end = ms_.st_red.rend(); --end;
end = ms_->st_red.rend(); --end;
for (; i != end; ++i, ++j)
{
tgba_run::step s = { i->s->clone(), j->label, j->acc };
@ -373,7 +375,7 @@ namespace spot
return 0;
}
private:
magic_search_& ms_;
std::shared_ptr<magic_search_> ms_;
};
# define FROM_STACK "ar:from_stack"
@ -381,8 +383,9 @@ namespace spot
class magic_search_result: public emptiness_check_result
{
public:
magic_search_result(magic_search_& m, option_map o = option_map())
: emptiness_check_result(m.automaton(), o), ms(m)
magic_search_result(const std::shared_ptr<magic_search_>& m,
option_map o = option_map())
: emptiness_check_result(m->automaton(), o), ms(m)
{
if (options()[FROM_STACK])
computer = new result_from_stack(ms);
@ -409,7 +412,7 @@ namespace spot
delete computer;
}
virtual tgba_run* accepting_run()
virtual tgba_run_ptr accepting_run()
{
return computer->accepting_run();
}
@ -421,7 +424,7 @@ namespace spot
private:
emptiness_check_result* computer;
magic_search_& ms;
std::shared_ptr<magic_search_> ms;
};
};
@ -584,18 +587,20 @@ namespace spot
} // 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,
size_t size, option_map o)
emptiness_check_ptr
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)
{
size_t size = o.get("bsh");

View file

@ -26,11 +26,10 @@
#include <cstddef>
#include "tgba/fwd.hh"
#include "misc/optionmap.hh"
#include "emptiness.hh"
namespace spot
{
class emptiness_check;
/// \addtogroup emptiness_check_algorithms
/// @{
@ -97,7 +96,7 @@ namespace spot
///
/// \bug The name is misleading. Magic-search is the algorithm
/// 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,
option_map o = option_map());
@ -128,7 +127,7 @@ namespace spot
///
/// \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,
option_map o = option_map());
@ -138,7 +137,7 @@ namespace spot
/// 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
/// 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());
/// @}

View file

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

View file

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

View file

@ -205,11 +205,7 @@ namespace spot
{
// Check the product between LOOP_A, and ORIG_A starting
// in S.
auto ec = couvreur99(product_at(loop_a, ref_, loop_a_init, s));
emptiness_check_result* res = ec->check();
delete res;
delete ec;
if (res)
if (!product_at(loop_a, ref_, loop_a_init, s)->is_empty())
{
accepting = true;
break;
@ -326,9 +322,9 @@ namespace spot
auto det = tba_determinize(aut, threshold_states, threshold_cycles);
if (!det)
return 0;
return nullptr;
if (neg_aut == 0)
if (neg_aut == nullptr)
{
const ltl::formula* neg_f =
ltl::unop::instance(ltl::unop::Not, f->clone());
@ -339,30 +335,13 @@ namespace spot
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;
}
}

View file

@ -24,12 +24,12 @@
namespace spot
{
tgba_run*
tgba_run_ptr
project_tgba_run(const const_tgba_ptr& a_run,
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();
i != run->prefix.end(); ++i)
{

View file

@ -26,6 +26,7 @@
# include "misc/common.hh"
# include <iosfwd>
# include "tgba/fwd.hh"
# include "tgbaalgos/emptiness.hh"
namespace spot
{
@ -41,10 +42,10 @@ namespace spot
/// \param a_run the automata on which the run was generated
/// \param a_proj the automata on which to project the run
/// \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,
const const_tgba_ptr& a_proj,
const tgba_run* run);
const const_tgba_run_ptr& run);
}
#endif // SPOT_TGBAALGOS_PROJRUN_HH

View file

@ -1,7 +1,8 @@
// Copyright (C) 2011, 2013 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// -*- coding: utf-8 -*-
// 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),
// 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.
//
// This file is part of Spot, a model checking library.
@ -86,10 +87,10 @@ namespace spot
};
}
tgba_run*
reduce_run(const const_tgba_ptr& a, const tgba_run* org)
tgba_run_ptr
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;
shortest_path shpath(a);
shpath.set_target(&ss);

View file

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

View file

@ -32,7 +32,8 @@ namespace spot
namespace
{
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)
{
std::string s = a->transition_annotation(i);
@ -44,7 +45,7 @@ namespace spot
bool
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();
int serial = 1;

View file

@ -26,6 +26,7 @@
# include "misc/common.hh"
# include <iosfwd>
# include "tgba/fwd.hh"
# include "tgbaalgos/emptiness.hh"
namespace spot
{
@ -48,7 +49,8 @@ namespace spot
/// \return true iff the run could be completed
SPOT_API bool
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);
}

View file

@ -26,7 +26,8 @@
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)
{
int n = 1;

View file

@ -38,7 +38,7 @@ namespace spot
class SPOT_API tgba_run_dotty_decorator: public dotty_decorator
{
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 std::string state_decl(const const_tgba_ptr& a,
@ -52,7 +52,7 @@ namespace spot
const tgba_succ_iterator* si,
const std::string& label);
private:
const tgba_run* run_;
const_tgba_run_ptr run_;
typedef std::pair<tgba_run::steps::const_iterator, int> step_num;
typedef std::list<step_num> 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
/// pointer) to enumerate all the visited accepting paths. The method
/// 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())
{
assert(st_blue.empty());
@ -98,17 +100,17 @@ namespace spot
h.add_new_state(s0, CYAN);
push(st_blue, s0, bddfalse, bddfalse);
if (dfs_blue())
return new se05_result(*this, options());
return std::make_shared<se05_result>(t, options());
}
else
{
h.pop_notify(st_red.front().s);
pop(st_red);
if (!st_red.empty() && dfs_red())
return new se05_result(*this, options());
return std::make_shared<se05_result>(t, options());
else
if (dfs_blue())
return new se05_result(*this, options());
return std::make_shared<se05_result>(t, options());
}
return 0;
}
@ -330,27 +332,27 @@ namespace spot
public acss_statistics
{
public:
result_from_stack(se05_search& ms)
: emptiness_check_result(ms.automaton()), ms_(ms)
result_from_stack(const std::shared_ptr<se05_search>& 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_red.empty());
assert(!ms_->st_blue.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;
tgba_run::steps* l;
const state* target = ms_.st_red.front().s;
const state* target = ms_->st_red.front().s;
l = &run->prefix;
i = ms_.st_blue.rbegin();
end = ms_.st_blue.rend(); --end;
i = ms_->st_blue.rbegin();
end = ms_->st_blue.rend(); --end;
j = i; ++j;
for (; i != end; ++i, ++j)
{
@ -364,12 +366,12 @@ namespace spot
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 };
l->push_back(s);
i = j; ++j;
end = ms_.st_red.rend(); --end;
end = ms_->st_red.rend(); --end;
for (; i != end; ++i, ++j)
{
tgba_run::step s = { i->s->clone(), j->label, j->acc };
@ -384,7 +386,7 @@ namespace spot
return 0;
}
private:
se05_search& ms_;
std::shared_ptr<se05_search> ms_;
};
# define FROM_STACK "ar:from_stack"
@ -392,8 +394,9 @@ namespace spot
class se05_result: public emptiness_check_result
{
public:
se05_result(se05_search& m, option_map o = option_map())
: emptiness_check_result(m.automaton(), o), ms(m)
se05_result(const std::shared_ptr<se05_search>& m,
option_map o = option_map())
: emptiness_check_result(m->automaton(), o), ms(m)
{
if (options()[FROM_STACK])
computer = new result_from_stack(ms);
@ -420,7 +423,7 @@ namespace spot
delete computer;
}
virtual tgba_run* accepting_run()
virtual tgba_run_ptr accepting_run()
{
return computer->accepting_run();
}
@ -432,7 +435,7 @@ namespace spot
private:
emptiness_check_result* computer;
se05_search& ms;
std::shared_ptr<se05_search> ms;
};
};
@ -675,19 +678,20 @@ namespace spot
} // 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,
size_t size,
option_map o)
emptiness_check_ptr
bit_state_hashing_se05_search(const const_tgba_ptr& a,
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)
{
size_t size = o.get("bsh");

View file

@ -26,11 +26,10 @@
# include <cstddef>
# include "misc/optionmap.hh"
# include "tgba/fwd.hh"
# include "emptiness.hh"
namespace spot
{
class emptiness_check;
/// \addtogroup emptiness_check_algorithms
/// @{
@ -102,7 +101,7 @@ namespace spot
///
/// \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());
/// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
@ -132,7 +131,7 @@ namespace spot
///
/// \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,
option_map o = option_map());
@ -143,7 +142,7 @@ namespace spot
/// 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
/// 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);
/// @}

View file

@ -83,18 +83,20 @@ namespace spot
///
/// \return non null pointer iff the algorithm has found an
/// accepting path.
virtual emptiness_check_result* check()
virtual emptiness_check_result_ptr check()
{
if (!st_blue.empty())
return 0;
return nullptr;
assert(st_red.empty());
const state* s0 = a_->get_init_state();
inc_states();
h.add_new_state(s0, BLUE);
push(st_blue, s0, bddfalse, bddfalse);
auto t = std::static_pointer_cast<tau03_search>
(this->emptiness_check::shared_from_this());
if (dfs_blue())
return new ndfs_result<tau03_search<heap>, heap>(*this);
return 0;
return std::make_shared<ndfs_result<tau03_search<heap>, heap>>(t);
return nullptr;
}
virtual std::ostream& print_stats(std::ostream &os) const
@ -374,9 +376,10 @@ namespace spot
} // 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 "tgba/fwd.hh"
# include "emptiness.hh"
namespace spot
{
class emptiness_check;
/// \addtogroup emptiness_check_algorithms
/// @{
@ -96,7 +95,7 @@ namespace spot
}
\endverbatim */
///
SPOT_API emptiness_check*
SPOT_API emptiness_check_ptr
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
/// accepting path.
virtual emptiness_check_result* check()
virtual emptiness_check_result_ptr check()
{
if (!st_blue.empty())
return 0;
return nullptr;
assert(st_red.empty());
const state* s0 = a_->get_init_state();
inc_states();
h.add_new_state(s0, CYAN, current_weight);
push(st_blue, s0, bddfalse, bddfalse);
auto t = std::static_pointer_cast<tau03_opt_search>
(this->emptiness_check::shared_from_this());
if (dfs_blue())
return new ndfs_result<tau03_opt_search<heap>, heap>(*this);
return 0;
return std::make_shared<ndfs_result<tau03_opt_search<heap>, heap>>(t);
return nullptr;
}
virtual std::ostream& print_stats(std::ostream &os) const
@ -572,10 +574,12 @@ namespace spot
} // anonymous
emptiness_check* explicit_tau03_opt_search(const const_tgba_ptr& a,
option_map o)
emptiness_check_ptr
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 "tgba/fwd.hh"
# include "emptiness.hh"
namespace spot
{
class emptiness_check;
/// \addtogroup emptiness_check_algorithms
/// @{
@ -98,7 +97,7 @@ namespace spot
/// the path stored in the blue stack. Such a vector is associated to each
/// state of this stack.
///
SPOT_API emptiness_check*
SPOT_API emptiness_check_ptr
explicit_tau03_opt_search(const const_tgba_ptr& a,
option_map o = option_map());

View file

@ -23,7 +23,7 @@
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();
i != run->prefix.end(); ++i)

View file

@ -1,5 +1,5 @@
// -*- 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).
//
// This file is part of Spot, a model checking library.
@ -29,7 +29,7 @@ namespace spot
/// \brief An infinite word stored as a lasso.
struct SPOT_API tgba_word
{
tgba_word(const tgba_run* run);
tgba_word(const tgba_run_ptr run);
void simplify();
std::ostream& print(std::ostream& os, const bdd_dict_ptr& d) const;