Use the degeneralization unicity_table in more places.
* src/tgbaalgos/degen.cc (unicity_table): Move and rename as... * src/tgba/state.hh (state_unicity_table): ... this. * src/tgbaalgos/cutscc.cc, src/tgbaalgos/cycles.cc, src/tgbaalgos/cycles.hh, src/tgbaalgos/minimize.cc, src/tgbaalgos/powerset.cc, src/tgbaalgos/powerset.hh, src/tgbaalgos/safety.cc: Use it to simplify existing code.
This commit is contained in:
parent
c7b3148cb4
commit
2f71741575
9 changed files with 100 additions and 161 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2009, 2011, 2013 Laboratoire de Recherche et
|
// Copyright (C) 2009, 2011, 2013, 2014 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6
|
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6
|
||||||
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
||||||
|
|
@ -176,6 +176,64 @@ namespace spot
|
||||||
state_ptr_hash, state_ptr_equal> state_set;
|
state_ptr_hash, state_ptr_equal> state_set;
|
||||||
|
|
||||||
|
|
||||||
|
/// \ingroup tgba_essentials
|
||||||
|
/// \brief Render state pointers unique via a hash table.
|
||||||
|
class SPOT_API state_unicity_table
|
||||||
|
{
|
||||||
|
state_set m;
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \brief Canonicalize state pointer.
|
||||||
|
///
|
||||||
|
/// If this is the first time a state is seen, this return the
|
||||||
|
/// state pointer as-is, otherwise it frees the state and returns
|
||||||
|
/// a point to the previously seen copy.
|
||||||
|
///
|
||||||
|
/// States are owned by the table and will be freed on
|
||||||
|
/// destruction.
|
||||||
|
const state* operator()(const state* s)
|
||||||
|
{
|
||||||
|
auto p = m.insert(s);
|
||||||
|
if (!p.second)
|
||||||
|
s->destroy();
|
||||||
|
return *p.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Canonicalize state pointer.
|
||||||
|
///
|
||||||
|
/// Same as operator(), except that a nullptr
|
||||||
|
/// is returned if the state is not new.
|
||||||
|
const state* is_new(const state* s)
|
||||||
|
{
|
||||||
|
auto p = m.insert(s);
|
||||||
|
if (!p.second)
|
||||||
|
{
|
||||||
|
s->destroy();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return *p.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
~state_unicity_table()
|
||||||
|
{
|
||||||
|
for (state_set::iterator i = m.begin(); i != m.end();)
|
||||||
|
{
|
||||||
|
// Advance the iterator before destroying its key. This
|
||||||
|
// avoid issues with old g++ implementations.
|
||||||
|
state_set::iterator old = i++;
|
||||||
|
(*old)->destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
size()
|
||||||
|
{
|
||||||
|
return m.size();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Functions related to shared_ptr.
|
// Functions related to shared_ptr.
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2009, 2011, 2012, 2013 Laboratoire de Recherche et
|
// Copyright (C) 2009, 2011, 2012, 2013, 2014 Laboratoire de Recherche
|
||||||
// Developpement de l'Epita (LRDE).
|
// et Developpement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -33,12 +33,10 @@ namespace spot
|
||||||
const std::set<unsigned>& s)
|
const std::set<unsigned>& s)
|
||||||
{
|
{
|
||||||
tgba_explicit_string* sub_a = new tgba_explicit_string(a->get_dict());
|
tgba_explicit_string* sub_a = new tgba_explicit_string(a->get_dict());
|
||||||
state* cur = a->get_init_state();
|
const state* cur = a->get_init_state();
|
||||||
std::queue<state*> tovisit;
|
std::queue<const state*> tovisit;
|
||||||
typedef std::unordered_set<const state*,
|
|
||||||
state_ptr_hash, state_ptr_equal> hash_type;
|
|
||||||
// Setup
|
// Setup
|
||||||
hash_type seen;
|
state_unicity_table seen;
|
||||||
unsigned scc_number;
|
unsigned scc_number;
|
||||||
std::string cur_format = a->format_state(cur);
|
std::string cur_format = a->format_state(cur);
|
||||||
std::set<unsigned>::iterator it;
|
std::set<unsigned>::iterator it;
|
||||||
|
|
@ -46,8 +44,7 @@ namespace spot
|
||||||
for (it = s.begin(); it != s.end() && !m.accepting(*it); ++it)
|
for (it = s.begin(); it != s.end() && !m.accepting(*it); ++it)
|
||||||
continue;
|
continue;
|
||||||
assert(it != s.end());
|
assert(it != s.end());
|
||||||
tovisit.push(cur);
|
tovisit.push(seen(cur));
|
||||||
seen.insert(cur);
|
|
||||||
sub_a->add_state(cur_format);
|
sub_a->add_state(cur_format);
|
||||||
sub_a->copy_acceptance_conditions_of(a);
|
sub_a->copy_acceptance_conditions_of(a);
|
||||||
// If the initial is not part of one of the desired SCC, exit
|
// If the initial is not part of one of the desired SCC, exit
|
||||||
|
|
@ -68,15 +65,8 @@ namespace spot
|
||||||
// Is the successor included in one of the desired SCC ?
|
// Is the successor included in one of the desired SCC ?
|
||||||
if (s.find(scc_number) != s.end())
|
if (s.find(scc_number) != s.end())
|
||||||
{
|
{
|
||||||
if (seen.find(dst) == seen.end())
|
if (seen.is_new(dst))
|
||||||
{
|
tovisit.push(dst);
|
||||||
tovisit.push(dst);
|
|
||||||
seen.insert(dst); // has_state?
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dst->destroy();
|
|
||||||
}
|
|
||||||
state_explicit_string::transition* t =
|
state_explicit_string::transition* t =
|
||||||
sub_a->create_transition(cur_format, dst_format);
|
sub_a->create_transition(cur_format, dst_format);
|
||||||
sub_a->add_conditions(t, sit->current_condition());
|
sub_a->add_conditions(t, sit->current_condition());
|
||||||
|
|
@ -90,11 +80,6 @@ namespace spot
|
||||||
}
|
}
|
||||||
delete sit;
|
delete sit;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_type::iterator it2;
|
|
||||||
// Free visited states.
|
|
||||||
for (it2 = seen.begin(); it2 != seen.end(); ++it2)
|
|
||||||
(*it2)->destroy();
|
|
||||||
return sub_a;
|
return sub_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright (C) 2012 Laboratoire de Recherche et Developpement de
|
// -*- coding: utf-8 -*-
|
||||||
|
// Copyright (C) 2012, 2014 Laboratoire de Recherche et Developpement 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.
|
||||||
|
|
@ -47,14 +48,12 @@ namespace spot
|
||||||
q.pop_back();
|
q.pop_back();
|
||||||
|
|
||||||
y->second.mark = false;
|
y->second.mark = false;
|
||||||
for (set_type::iterator i = y->second.b.begin();
|
for (auto s: y->second.b)
|
||||||
i != y->second.b.end(); ++i)
|
|
||||||
{
|
{
|
||||||
tagged_state x = tags_.find(*i);
|
tagged_state x = tags_.find(s);
|
||||||
assert(x != tags_.end());
|
assert(x != tags_.end());
|
||||||
// insert y in A(x)
|
// insert y in A(x)
|
||||||
x->second.del.erase(y->first);
|
x->second.del.erase(y->first);
|
||||||
|
|
||||||
// unmark x recursively if marked
|
// unmark x recursively if marked
|
||||||
if (x->second.mark)
|
if (x->second.mark)
|
||||||
q.push_back(x);
|
q.push_back(x);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012, 2013 Laboratoire de Recherche et Développement
|
// Copyright (C) 2012, 2013, 2014 Laboratoire de Recherche et
|
||||||
// de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -79,9 +79,6 @@ namespace spot
|
||||||
class SPOT_API enumerate_cycles
|
class SPOT_API enumerate_cycles
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
typedef std::unordered_set<const state*,
|
|
||||||
state_ptr_hash, state_ptr_equal> set_type;
|
|
||||||
|
|
||||||
// Extra information required for the algorithm for each state.
|
// Extra information required for the algorithm for each state.
|
||||||
struct state_info
|
struct state_info
|
||||||
{
|
{
|
||||||
|
|
@ -98,10 +95,10 @@ namespace spot
|
||||||
// that a contributed to a contributed to a cycle.
|
// that a contributed to a contributed to a cycle.
|
||||||
bool mark;
|
bool mark;
|
||||||
// Deleted successors (in the paper, states deleted from A(x))
|
// Deleted successors (in the paper, states deleted from A(x))
|
||||||
set_type del;
|
state_set del;
|
||||||
// Predecessors of the current states, that could not yet
|
// Predecessors of the current states, that could not yet
|
||||||
// contribute to a cycle.
|
// contribute to a cycle.
|
||||||
set_type b;
|
state_set b;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Store the state_info for all visited states.
|
// Store the state_info for all visited states.
|
||||||
|
|
|
||||||
|
|
@ -67,37 +67,6 @@ namespace spot
|
||||||
// Queue of state to be processed.
|
// Queue of state to be processed.
|
||||||
typedef std::deque<degen_state> queue_t;
|
typedef std::deque<degen_state> queue_t;
|
||||||
|
|
||||||
// Memory management for the input states.
|
|
||||||
class unicity_table
|
|
||||||
{
|
|
||||||
state_set m;
|
|
||||||
public:
|
|
||||||
const state* operator()(const state* s)
|
|
||||||
{
|
|
||||||
auto p = m.insert(s);
|
|
||||||
if (!p.second)
|
|
||||||
s->destroy();
|
|
||||||
return *p.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
~unicity_table()
|
|
||||||
{
|
|
||||||
for (state_set::iterator i = m.begin(); i != m.end();)
|
|
||||||
{
|
|
||||||
// Advance the iterator before destroying its key. This
|
|
||||||
// avoid issues with old g++ implementations.
|
|
||||||
state_set::iterator old = i++;
|
|
||||||
(*old)->destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
size()
|
|
||||||
{
|
|
||||||
return m.size();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Acceptance set common to all outgoing transitions (of the same
|
// Acceptance set common to all outgoing transitions (of the same
|
||||||
// SCC -- we do not care about the other) of some state.
|
// SCC -- we do not care about the other) of some state.
|
||||||
class outgoing_acc
|
class outgoing_acc
|
||||||
|
|
@ -165,10 +134,10 @@ namespace spot
|
||||||
typedef std::unordered_map<const state*, bool,
|
typedef std::unordered_map<const state*, bool,
|
||||||
state_ptr_hash, state_ptr_equal> cache_t;
|
state_ptr_hash, state_ptr_equal> cache_t;
|
||||||
cache_t cache_;
|
cache_t cache_;
|
||||||
unicity_table& uniq_;
|
state_unicity_table& uniq_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
has_acc_loop(const tgba* a, unicity_table& uniq):
|
has_acc_loop(const tgba* a, state_unicity_table& uniq):
|
||||||
a_(a),
|
a_(a),
|
||||||
uniq_(uniq)
|
uniq_(uniq)
|
||||||
{
|
{
|
||||||
|
|
@ -329,7 +298,7 @@ namespace spot
|
||||||
|
|
||||||
// Make sure we always use the same pointer for identical states
|
// Make sure we always use the same pointer for identical states
|
||||||
// from the input automaton.
|
// from the input automaton.
|
||||||
unicity_table uniq;
|
state_unicity_table uniq;
|
||||||
|
|
||||||
// Accepting loop checker, for some heuristics.
|
// Accepting loop checker, for some heuristics.
|
||||||
has_acc_loop acc_loop(a, uniq);
|
has_acc_loop acc_loop(a, uniq);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2010, 2011, 2012, 2013 Laboratoire de Recherche et
|
// Copyright (C) 2010, 2011, 2012, 2013, 2014 Laboratoire de Recherche
|
||||||
// Développement de l'Epita (LRDE).
|
// et Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -52,6 +52,8 @@
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
|
// FIXME: do we really want to use unordered_set instead of set here?
|
||||||
|
// This calls for benchmarking.
|
||||||
typedef std::unordered_set<const state*,
|
typedef std::unordered_set<const state*,
|
||||||
state_ptr_hash, state_ptr_equal> hash_set;
|
state_ptr_hash, state_ptr_equal> hash_set;
|
||||||
typedef std::unordered_map<const state*, unsigned,
|
typedef std::unordered_map<const state*, unsigned,
|
||||||
|
|
@ -184,36 +186,13 @@ namespace spot
|
||||||
power_map& pm, const state* dest)
|
power_map& pm, const state* dest)
|
||||||
: bfs_steps(det_a), scc_n(scc_n), sm(sm), pm(pm), dest(dest)
|
: bfs_steps(det_a), scc_n(scc_n), sm(sm), pm(pm), dest(dest)
|
||||||
{
|
{
|
||||||
seen.insert(dest);
|
seen(dest);
|
||||||
}
|
|
||||||
|
|
||||||
virtual
|
|
||||||
~wdba_search_acc_loop()
|
|
||||||
{
|
|
||||||
hash_set::const_iterator i = seen.begin();
|
|
||||||
while (i != seen.end())
|
|
||||||
{
|
|
||||||
hash_set::const_iterator old = i;
|
|
||||||
++i;
|
|
||||||
(*old)->destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const state*
|
virtual const state*
|
||||||
filter(const state* s)
|
filter(const state* s)
|
||||||
{
|
{
|
||||||
// Use the state from seen.
|
s = seen(s);
|
||||||
hash_set::const_iterator i = seen.find(s);
|
|
||||||
if (i == seen.end())
|
|
||||||
{
|
|
||||||
seen.insert(s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s->destroy();
|
|
||||||
s = *i;
|
|
||||||
}
|
|
||||||
// Ignore states outside SCC #n.
|
|
||||||
if (sm.scc_of_state(s) != scc_n)
|
if (sm.scc_of_state(s) != scc_n)
|
||||||
return 0;
|
return 0;
|
||||||
return s;
|
return s;
|
||||||
|
|
@ -229,7 +208,7 @@ namespace spot
|
||||||
scc_map& sm;
|
scc_map& sm;
|
||||||
power_map& pm;
|
power_map& pm;
|
||||||
const state* dest;
|
const state* dest;
|
||||||
hash_set seen;
|
state_unicity_table seen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright (C) 2009, 2010, 2011, 2013 Laboratoire de Recherche et
|
// -*- coding: utf-8 -*-
|
||||||
// Développement de l'Epita (LRDE).
|
// Copyright (C) 2009, 2010, 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.
|
||||||
|
|
@ -54,8 +55,7 @@ namespace spot
|
||||||
|
|
||||||
{
|
{
|
||||||
power_state ps;
|
power_state ps;
|
||||||
state* s = aut->get_init_state();
|
const state* s = pm.canonicalize(aut->get_init_state());
|
||||||
pm.states.insert(s);
|
|
||||||
ps.insert(s);
|
ps.insert(s);
|
||||||
todo.push_back(ps);
|
todo.push_back(ps);
|
||||||
seen[ps] = 1;
|
seen[ps] = 1;
|
||||||
|
|
@ -325,7 +325,7 @@ namespace spot
|
||||||
tgba_explicit_number* det = tgba_powerset(aut, pm, false);
|
tgba_explicit_number* det = tgba_powerset(aut, pm, false);
|
||||||
|
|
||||||
if ((threshold_states > 0)
|
if ((threshold_states > 0)
|
||||||
&& (pm.map_.size() > pm.states.size() * threshold_states))
|
&& (pm.map_.size() > pm.states_.size() * threshold_states))
|
||||||
{
|
{
|
||||||
delete det;
|
delete det;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2011, 2013 Laboratoire de Recherche et Développement
|
// Copyright (C) 2011, 2013, 2014 Laboratoire de Recherche et
|
||||||
// de l'Epita.
|
// Développement de l'Epita.
|
||||||
// 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.
|
||||||
|
|
@ -34,21 +34,6 @@ namespace spot
|
||||||
{
|
{
|
||||||
typedef std::set<const state*, state_ptr_less_than> power_state;
|
typedef std::set<const state*, state_ptr_less_than> power_state;
|
||||||
typedef std::map<int, power_state> power_map_data;
|
typedef std::map<int, power_state> power_map_data;
|
||||||
typedef std::unordered_set<const state*, state_ptr_hash,
|
|
||||||
state_ptr_equal> state_set;
|
|
||||||
|
|
||||||
~power_map()
|
|
||||||
{
|
|
||||||
// Release all states.
|
|
||||||
state_set::const_iterator i = states.begin();
|
|
||||||
while (i != states.end())
|
|
||||||
{
|
|
||||||
// Advance the iterator before deleting the key.
|
|
||||||
const state* s = *i;
|
|
||||||
++i;
|
|
||||||
s->destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const power_state&
|
const power_state&
|
||||||
states_of(int s) const
|
states_of(int s) const
|
||||||
|
|
@ -59,21 +44,11 @@ namespace spot
|
||||||
const state*
|
const state*
|
||||||
canonicalize(const state* s)
|
canonicalize(const state* s)
|
||||||
{
|
{
|
||||||
state_set::const_iterator i = states.find(s);
|
return states_(s);
|
||||||
if (i != states.end())
|
|
||||||
{
|
|
||||||
s->destroy();
|
|
||||||
s = *i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
states.insert(s);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
power_map_data map_;
|
power_map_data map_;
|
||||||
state_set states;
|
state_unicity_table states_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2010, 2011, 2013 Laboratoire de Recherche et
|
// Copyright (C) 2010, 2011, 2013, 2014 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE)
|
// Développement de l'Epita (LRDE)
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -72,16 +72,10 @@ namespace spot
|
||||||
|
|
||||||
bool is_safety_mwdba(const tgba* aut)
|
bool is_safety_mwdba(const tgba* aut)
|
||||||
{
|
{
|
||||||
typedef std::unordered_set<const state*,
|
state_unicity_table seen; // States already seen.
|
||||||
state_ptr_hash, state_ptr_equal> seen_map;
|
|
||||||
seen_map seen; // States already seen.
|
|
||||||
std::deque<const state*> todo; // A queue of states yet to explore.
|
std::deque<const state*> todo; // A queue of states yet to explore.
|
||||||
|
|
||||||
{
|
todo.push_back(seen(aut->get_init_state()));
|
||||||
state* s = aut->get_init_state();
|
|
||||||
todo.push_back(s);
|
|
||||||
seen.insert(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
bdd all_acc = aut->all_acceptance_conditions();
|
bdd all_acc = aut->all_acceptance_conditions();
|
||||||
|
|
||||||
|
|
@ -100,28 +94,11 @@ namespace spot
|
||||||
all_accepting = false;
|
all_accepting = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state* d = it->current_state();
|
if (const state* d = seen.is_new(it->current_state()))
|
||||||
if (seen.find(d) != seen.end())
|
todo.push_back(d);
|
||||||
{
|
|
||||||
d->destroy();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
seen.insert(d);
|
|
||||||
todo.push_back(d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete it;
|
delete it;
|
||||||
}
|
}
|
||||||
|
|
||||||
seen_map::const_iterator it = seen.begin();
|
|
||||||
while (it != seen.end())
|
|
||||||
{
|
|
||||||
seen_map::const_iterator old = it;
|
|
||||||
++it;
|
|
||||||
(*old)->destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
return all_accepting;
|
return all_accepting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue