tgba_succ_iterator: have first() and next() return a bool

The returned Boolean indicates whether there is a successor or not.
This way

|  for (i->first(); !i->done(); i->next())
|    {
|       ...
|    }

can be replaced by

| if (i->first()) do
|   {
|      ...
|   }
| while (i->next());

avoiding all the virtual calls to done().

* iface/dve2/dve2.cc, src/kripke/kripkeexplicit.cc,
src/kripke/kripkeexplicit.hh, src/ta/ta.hh, src/ta/taexplicit.cc,
src/ta/taexplicit.hh, src/ta/taproduct.cc, src/ta/taproduct.hh,
src/ta/tgtaproduct.cc, src/ta/tgtaproduct.hh, src/tgba/succiter.hh,
src/tgba/succiterconcrete.cc, src/tgba/succiterconcrete.hh,
src/tgba/taatgba.cc, src/tgba/taatgba.hh, src/tgba/tgba.hh,
src/tgba/tgbaexplicit.hh, src/tgba/tgbakvcomplement.cc,
src/tgba/tgbamask.cc, src/tgba/tgbaproduct.cc,
src/tgba/tgbasafracomplement.cc, src/tgba/tgbasgba.cc,
src/tgba/tgbatba.cc, src/tgba/tgbaunion.cc, src/tgba/tgbaunion.hh,
src/tgba/wdbacomp.cc: Implement and adjust to this new interface.
This commit is contained in:
Alexandre Duret-Lutz 2014-01-26 22:57:14 +01:00
parent 06c69f88ff
commit 1a5c0cb1f3
26 changed files with 256 additions and 206 deletions

View file

@ -272,15 +272,17 @@ namespace spot
} }
virtual virtual
void first() bool first()
{ {
it_ = cc_->transitions.begin(); it_ = cc_->transitions.begin();
return it_ != cc_->transitions.end();
} }
virtual virtual
void next() bool next()
{ {
++it_; ++it_;
return it_ != cc_->transitions.end();
} }
virtual virtual

View file

@ -99,14 +99,16 @@ namespace spot
{ {
} }
void kripke_explicit_succ_iterator::first() bool kripke_explicit_succ_iterator::first()
{ {
it_ = s_->get_succ().begin(); it_ = s_->get_succ().begin();
return it_ != s_->get_succ().end();
} }
void kripke_explicit_succ_iterator::next() bool kripke_explicit_succ_iterator::next()
{ {
++it_; ++it_;
return it_ != s_->get_succ().end();
} }
bool kripke_explicit_succ_iterator::done() const bool kripke_explicit_succ_iterator::done() const

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2011, 2012, 2013 Laboratoire de Recherche et // Copyright (C) 2011, 2012, 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.
@ -97,8 +97,8 @@ namespace spot
~kripke_explicit_succ_iterator(); ~kripke_explicit_succ_iterator();
virtual void first(); virtual bool first();
virtual void next(); virtual bool next();
virtual bool done() const; virtual bool done() const;
virtual state_kripke* current_state() const; virtual state_kripke* current_state() const;

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2010, 2012, 2013 Laboratoire de Recherche et // Copyright (C) 2010, 2012, 2013, 2014 Laboratoire de Recherche et
// Developpement de l Epita (LRDE). // 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.
@ -191,12 +191,9 @@ namespace spot
{ {
} }
virtual void virtual bool first() = 0;
first() = 0; virtual bool next() = 0;
virtual void virtual bool done() const = 0;
next() = 0;
virtual bool
done() const = 0;
virtual state* virtual state*
current_state() const = 0; current_state() const = 0;

View file

@ -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.
// //
@ -54,24 +54,26 @@ namespace spot
transitions_ = s->get_transitions(condition); transitions_ = s->get_transitions(condition);
} }
void bool
ta_explicit_succ_iterator::first() ta_explicit_succ_iterator::first()
{ {
if (transitions_ != 0) if (!transitions_)
i_ = transitions_->begin(); return false;
i_ = transitions_->begin();
return i_ != transitions_->end();
} }
void bool
ta_explicit_succ_iterator::next() ta_explicit_succ_iterator::next()
{ {
++i_; ++i_;
return i_ != transitions_->end();
} }
bool bool
ta_explicit_succ_iterator::done() const ta_explicit_succ_iterator::done() const
{ {
return transitions_ == 0 || transitions_->empty() || i_ return !transitions_ || i_ == transitions_->end();
== transitions_->end();
} }
state* state*

View file

@ -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.
// //
@ -248,12 +248,9 @@ namespace spot
ta_explicit_succ_iterator(const state_ta_explicit* s, bdd condition); ta_explicit_succ_iterator(const state_ta_explicit* s, bdd condition);
virtual void virtual bool first();
first(); virtual bool next();
virtual void virtual bool done() const;
next();
virtual bool
done() const;
virtual state* virtual state*
current_state() const; current_state() const;

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2011, 2012 Laboratoire de Recherche et Développement // Copyright (C) 2011, 2012, 2014 Laboratoire de Recherche et Développement
// de l'Epita (LRDE). // de l'Epita (LRDE).
// //
// //
@ -150,17 +150,18 @@ namespace spot
} }
void bool
ta_succ_iterator_product::first() ta_succ_iterator_product::first()
{ {
next_kripke_dest(); next_kripke_dest();
if (!done()) if (!done())
next_non_stuttering_(); return next_non_stuttering_();
return false;
} }
void bool
ta_succ_iterator_product::next() ta_succ_iterator_product::next()
{ {
delete current_state_; delete current_state_;
@ -173,11 +174,11 @@ namespace spot
step_(); step_();
if (!done()) if (!done())
next_non_stuttering_(); return next_non_stuttering_();
return false;
} }
void bool
ta_succ_iterator_product::next_non_stuttering_() ta_succ_iterator_product::next_non_stuttering_()
{ {
@ -190,7 +191,7 @@ namespace spot
current_state_ = new state_ta_product(source_->get_ta_state(), current_state_ = new state_ta_product(source_->get_ta_state(),
kripke_current_dest_state->clone()); kripke_current_dest_state->clone());
current_acceptance_conditions_ = bddfalse; current_acceptance_conditions_ = bddfalse;
return; return true;
} }
if (!ta_succ_it_->done()) if (!ta_succ_it_->done())
@ -199,11 +200,12 @@ namespace spot
kripke_current_dest_state->clone()); kripke_current_dest_state->clone());
current_acceptance_conditions_ current_acceptance_conditions_
= ta_succ_it_->current_acceptance_conditions(); = ta_succ_it_->current_acceptance_conditions();
return; return true;
} }
step_(); step_();
} }
return false;
} }
bool bool

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2011, 2012, 2013 Laboratoire de Recherche et // Copyright (C) 2011, 2012, 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.
@ -83,12 +83,9 @@ namespace spot
~ta_succ_iterator_product(); ~ta_succ_iterator_product();
// iteration // iteration
void bool first();
first(); bool next();
void bool done() const;
next();
bool
done() const;
// inspection // inspection
state_ta_product* state_ta_product*
@ -106,10 +103,8 @@ namespace spot
protected: protected:
//@{ //@{
/// Internal routines to advance to the next successor. /// Internal routines to advance to the next successor.
void void step_();
step_(); bool next_non_stuttering_();
void
next_non_stuttering_();
/// \brief Move to the next successor in the kripke structure /// \brief Move to the next successor in the kripke structure
void void

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2012 Laboratoire de Recherche et Developpement // Copyright (C) 2012, 2014 Laboratoire de Recherche et Développement
// de l Epita (LRDE). // de l Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -173,19 +173,16 @@ namespace spot
} }
void bool
tgta_succ_iterator_product::first() tgta_succ_iterator_product::first()
{ {
next_kripke_dest(); next_kripke_dest();
trace trace << "*** first() .... if(done()) = ***" << done() << std::endl;
<< "*** first() .... if(done()) = ***" << done() << std::endl; return find_next_succ_();
if (!done())
find_next_succ_();
} }
void bool
tgta_succ_iterator_product::next() tgta_succ_iterator_product::next()
{ {
current_state_->destroy(); current_state_->destroy();
@ -193,18 +190,14 @@ namespace spot
step_(); step_();
trace trace << "*** next() .... if(done()) = ***" << done() << std::endl;
<< "*** next() .... if(done()) = ***" << done() << std::endl;
if (!done())
find_next_succ_();
return find_next_succ_();
} }
void bool
tgta_succ_iterator_product::find_next_succ_() tgta_succ_iterator_product::find_next_succ_()
{ {
while (!done()) while (!done())
{ {
if (!tgta_succ_it_->done()) if (!tgta_succ_it_->done())
@ -214,11 +207,12 @@ namespace spot
tgta_succ_it_->current_state(), pool_); tgta_succ_it_->current_state(), pool_);
current_acceptance_conditions_ current_acceptance_conditions_
= tgta_succ_it_->current_acceptance_conditions(); = tgta_succ_it_->current_acceptance_conditions();
return; return true;
} }
step_(); step_();
} }
return false;
} }
bool bool

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2011, 2012, 2013 Laboratoire de Recherche et Développement // Copyright (C) 2011, 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.
// //
@ -54,12 +54,9 @@ namespace spot
~tgta_succ_iterator_product(); ~tgta_succ_iterator_product();
// iteration // iteration
void bool first();
first(); bool next();
void bool done() const;
next();
bool
done() const;
// inspection // inspection
state_product* state_product*
@ -75,8 +72,7 @@ namespace spot
/// Internal routines to advance to the next successor. /// Internal routines to advance to the next successor.
void void
step_(); step_();
void bool find_next_succ_();
find_next_succ_();
void void
next_kripke_dest(); next_kripke_dest();

View file

@ -53,17 +53,21 @@ namespace spot
/// This method can be called several times to make multiple /// This method can be called several times to make multiple
/// passes over successors. /// passes over successors.
/// ///
/// \warning One should always call \c done() to /// \warning One should always call \c done() (or better: check
/// ensure there is a successor, even after \c first(). A /// the return value of first()) to ensure there is a successor,
/// common trap is to assume that there is at least one /// even after \c first(). A common trap is to assume that there
/// successor: this is wrong. /// is at least one successor: this is wrong.
virtual void first() = 0; ///
/// \return whether there is actually a successor
virtual bool first() = 0;
/// \brief Jump to the next successor (if any). /// \brief Jump to the next successor (if any).
/// ///
/// \warning Again, one should always call \c done() to ensure /// \warning Again, one should always call \c done() (or better:
/// there is a successor. /// check the return value of next()) ensure there is a successor.
virtual void next() = 0; ///
/// \return whether there is actually a successor
virtual bool next() = 0;
/// \brief Check whether the iteration is finished. /// \brief Check whether the iteration is finished.
/// ///
@ -132,8 +136,7 @@ namespace spot
void operator++() void operator++()
{ {
it_->next(); if (!it_->next())
if (it_->done())
it_ = nullptr; it_ = nullptr;
} }
}; };

View file

@ -29,16 +29,18 @@ namespace spot
{ {
} }
void bool
tgba_succ_iterator_concrete::first() tgba_succ_iterator_concrete::first()
{ {
succ_set_left_ = succ_set_; succ_set_left_ = succ_set_;
current_ = bddfalse; current_ = bddfalse;
if (!done()) if (!done())
next(); return next();
else
return false;
} }
void bool
tgba_succ_iterator_concrete::next() tgba_succ_iterator_concrete::next()
{ {
assert(!done()); assert(!done());
@ -86,7 +88,7 @@ namespace spot
succ_set_left_ -= current_; succ_set_left_ -= current_;
if (succ_set_left_ == bddfalse) // No more successors? if (succ_set_left_ == bddfalse) // No more successors?
return; return false;
// Pick one transition, and extract its destination. // Pick one transition, and extract its destination.
bdd trans = bdd_satoneset(succ_set_left_, data_.next_set, bdd trans = bdd_satoneset(succ_set_left_, data_.next_set,
@ -157,6 +159,8 @@ namespace spot
current_state_ = bdd_replace(dest, data_.dict->next_to_now); current_state_ = bdd_replace(dest, data_.dict->next_to_now);
} }
while ((current_state_ & data_.relation) == bddfalse); while ((current_state_ & data_.relation) == bddfalse);
return succ_set_left_ != bddfalse;
} }
bool bool

View file

@ -61,8 +61,8 @@ namespace spot
virtual ~tgba_succ_iterator_concrete(); virtual ~tgba_succ_iterator_concrete();
// iteration // iteration
void first(); bool first();
void next(); bool next();
bool done() const; bool done() const;
// inspection // inspection

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2009, 2010, 2011, 2012, 2013 Laboratoire de Recherche // Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire de
// et Développement de l'Epita (LRDE) // Recherche 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.
// //
@ -315,16 +315,18 @@ namespace spot
} }
} }
void bool
taa_succ_iterator::first() taa_succ_iterator::first()
{ {
i_ = succ_.begin(); i_ = succ_.begin();
return i_ != succ_.end();
} }
void bool
taa_succ_iterator::next() taa_succ_iterator::next()
{ {
++i_; ++i_;
return i_ != succ_.end();
} }
bool bool

View file

@ -113,8 +113,8 @@ namespace spot
taa_succ_iterator(const taa_tgba::state_set* s, bdd all_acc); taa_succ_iterator(const taa_tgba::state_set* s, bdd all_acc);
virtual ~taa_succ_iterator(); virtual ~taa_succ_iterator();
virtual void first(); virtual bool first();
virtual void next(); virtual bool next();
virtual bool done() const; virtual bool done() const;
virtual set_state* current_state() const; virtual set_state* current_state() const;

View file

@ -102,8 +102,7 @@ namespace spot
internal::succ_iterator begin() internal::succ_iterator begin()
{ {
it_->first(); return it_->first() ? it_ : nullptr;
return it_->done() ? nullptr : it_;
} }
internal::succ_iterator end() internal::succ_iterator end()

View file

@ -208,14 +208,16 @@ namespace spot
all_acceptance_conditions_ = all_acc; all_acceptance_conditions_ = all_acc;
} }
virtual void first() virtual bool first()
{ {
it_ = start_->successors.begin(); it_ = start_->successors.begin();
return it_ != start_->successors.end();
} }
virtual void next() virtual bool next()
{ {
++it_; ++it_;
return it_ != start_->successors.end();
} }
virtual bool done() const virtual bool done() const

View file

@ -258,8 +258,8 @@ namespace spot
const state_kv_complement* origin); const state_kv_complement* origin);
virtual ~tgba_kv_complement_succ_iterator() {}; virtual ~tgba_kv_complement_succ_iterator() {};
virtual void first(); virtual bool first();
virtual void next(); virtual bool next();
virtual bool done() const; virtual bool done() const;
virtual state_kv_complement* current_state() const; virtual state_kv_complement* current_state() const;
virtual bdd current_condition() const; virtual bdd current_condition() const;
@ -470,24 +470,25 @@ namespace spot
current_ranks_ = highest_current_ranks_; current_ranks_ = highest_current_ranks_;
} }
void bool
tgba_kv_complement_succ_iterator::first() tgba_kv_complement_succ_iterator::first()
{ {
current_condition_ = condition_list_.begin(); current_condition_ = condition_list_.begin();
if (done()) if (current_condition_ == condition_list_.end())
return; return false;
successor_highest_rank(*current_condition_); successor_highest_rank(*current_condition_);
if (!is_valid_rank()) if (!is_valid_rank())
next_valid_rank(); next_valid_rank();
return current_condition_ != condition_list_.end();
} }
void bool
tgba_kv_complement_succ_iterator::next() tgba_kv_complement_succ_iterator::next()
{ {
if (done()) if (current_condition_ == condition_list_.end())
return; return false;
if (!next_valid_rank()) if (!next_valid_rank())
{ {
@ -499,12 +500,13 @@ namespace spot
next_valid_rank(); next_valid_rank();
} }
} }
return current_condition_ != condition_list_.end();
} }
bool bool
tgba_kv_complement_succ_iterator::done() const tgba_kv_complement_succ_iterator::done() const
{ {
return (current_condition_ == condition_list_.end()); return current_condition_ == condition_list_.end();
} }
state_kv_complement* state_kv_complement*

View file

@ -40,14 +40,16 @@ namespace spot
t.dest->destroy(); t.dest->destroy();
} }
void first() bool first()
{ {
it_ = trans_.begin(); it_ = trans_.begin();
return it_ != trans_.end();
} }
virtual void next() bool next()
{ {
++it_; ++it_;
return it_ != trans_.end();
} }
bool done() const bool done() const

View file

@ -104,26 +104,24 @@ namespace spot
delete right_; delete right_;
} }
virtual void next_non_false_() = 0; virtual bool next_non_false_() = 0;
void first() bool first()
{ {
if (!right_) if (!right_)
return; return false;
left_->first();
right_->first();
// If one of the two successor sets is empty initially, we // If one of the two successor sets is empty initially, we
// reset right_, so that done() can detect this situation // reset right_, so that done() can detect this situation
// easily. (We choose to reset right_ because this variable // easily. (We choose to reset right_ because this variable
// is already used by done().) // is already used by done().)
if (left_->done() || right_->done()) if (!(left_->first() && right_->first()))
{ {
delete right_; delete right_;
right_ = 0; right_ = 0;
return; return false;
} }
next_non_false_(); return next_non_false_();
} }
bool done() const bool done() const
@ -166,19 +164,18 @@ namespace spot
{ {
} }
void step_() bool step_()
{ {
left_->next(); if (left_->next())
if (left_->done()) return true;
{ left_->first();
left_->first(); return right_->next();
right_->next();
}
} }
void next_non_false_() bool next_non_false_()
{ {
while (!done()) assert(!done());
do
{ {
bdd l = left_->current_condition(); bdd l = left_->current_condition();
bdd r = right_->current_condition(); bdd r = right_->current_condition();
@ -187,16 +184,18 @@ namespace spot
if (current_cond != bddfalse) if (current_cond != bddfalse)
{ {
current_cond_ = current_cond; current_cond_ = current_cond;
return; return true;
} }
step_();
} }
while (step_());
return false;
} }
void next() bool next()
{ {
step_(); if (step_())
next_non_false_(); return next_non_false_();
return false;
} }
bdd current_condition() const bdd current_condition() const
@ -235,12 +234,13 @@ namespace spot
{ {
} }
void next_non_false_() bool next_non_false_()
{ {
// All the transitions of left_ iterator have the // All the transitions of left_ iterator have the
// same label, because it is a Kripke structure. // same label, because it is a Kripke structure.
bdd l = left_->current_condition(); bdd l = left_->current_condition();
while (!right_->done()) assert(!right_->done());
do
{ {
bdd r = right_->current_condition(); bdd r = right_->current_condition();
bdd current_cond = l & r; bdd current_cond = l & r;
@ -248,21 +248,21 @@ namespace spot
if (current_cond != bddfalse) if (current_cond != bddfalse)
{ {
current_cond_ = current_cond; current_cond_ = current_cond;
return; return true;
} }
right_->next();
} }
while (right_->next());
return false;
} }
void next() bool next()
{ {
left_->next(); if (left_->next())
if (left_->done()) return true;
{ left_->first();
left_->first(); if (right_->next())
right_->next(); return next_non_false_();
next_non_false_(); return false;
}
} }
bdd current_condition() const bdd current_condition() const

View file

@ -976,8 +976,8 @@ namespace spot
delete p.second; delete p.second;
} }
virtual void first(); virtual bool first();
virtual void next(); virtual bool next();
virtual bool done() const; virtual bool done() const;
virtual state_complement* current_state() const; virtual state_complement* current_state() const;
virtual bdd current_condition() const; virtual bdd current_condition() const;
@ -988,16 +988,18 @@ namespace spot
succ_list_t::const_iterator it_; succ_list_t::const_iterator it_;
}; };
void bool
tgba_safra_complement_succ_iterator::first() tgba_safra_complement_succ_iterator::first()
{ {
it_ = list_.begin(); it_ = list_.begin();
return it_ != list_.end();
} }
void bool
tgba_safra_complement_succ_iterator::next() tgba_safra_complement_succ_iterator::next()
{ {
++it_; ++it_;
return it_ != list_.end();
} }
bool bool

View file

@ -1,5 +1,6 @@
// Copyright (C) 2009, 2011, 2012 Laboratoire de Recherche et Développement // -*- coding: utf-8 -*-
// de l'Epita (LRDE). // Copyright (C) 2009, 2011, 2012, 2014 Laboratoire de Recherche 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.
// //
@ -113,16 +114,16 @@ namespace spot
// iteration // iteration
void bool
first() first()
{ {
it_->first(); return it_->first();
} }
void bool
next() next()
{ {
it_->next(); return it_->next();
} }
bool bool

View file

@ -348,16 +348,18 @@ namespace spot
// iteration // iteration
void bool
first() first()
{ {
it_ = translist_.begin(); it_ = translist_.begin();
return it_ != translist_.end();
} }
void bool
next() next()
{ {
++it_; ++it_;
return it_ != translist_.end();
} }
bool bool

View file

@ -111,62 +111,94 @@ namespace spot
delete right_; delete right_;
} }
void bool
tgba_succ_iterator_union::next() tgba_succ_iterator_union::next()
{ {
// Is it the initial state ? // Is it the initial state ?
if (left_ && right_) if (left_ && right_)
{
// Yes, first iterate on the successors of the initial state of the
// left automaton.
if (!left_->done())
{ {
left_->next(); // Yes, first iterate on the successors of the initial state of the
// left automaton.
if (!left_->done()) if (!left_->done())
current_cond_ = left_->current_condition(); {
if (left_->next())
{
current_cond_ = left_->current_condition();
return true;
}
else if (!right_->done())
{
current_cond_ = right_->current_condition();
return true;
}
else
{
return false;
}
}
// Now iterate with the successors of the initial state of the right
// automaton.
else else
current_cond_ = right_->current_condition(); {
if (right_->next())
{
current_cond_ = right_->current_condition();
return true;
}
else
{
return false;
}
}
} }
// Now iterate with the successors of the initial state of the right
// automaton.
else
{
right_->next();
if (!right_->done())
current_cond_ = right_->current_condition();
}
}
else else
{
// No, iterate either on the left or the right automaton.
if (left_)
{ {
left_->next(); // No, iterate either on the left or the right automaton.
if (!left_->done()) if (left_)
current_cond_ = left_->current_condition(); {
if (left_->next())
{
current_cond_ = left_->current_condition();
return true;
}
else
{
return false;
}
}
else
{
if (right_->next())
{
current_cond_ = right_->current_condition();
return true;
}
else
{
return false;
}
}
} }
else
{
right_->next();
if (!right_->done())
current_cond_ = right_->current_condition();
}
}
} }
void bool
tgba_succ_iterator_union::first() tgba_succ_iterator_union::first()
{ {
bool r = false;
if (right_) if (right_)
{ {
right_->first(); r = right_->first();
current_cond_ = right_->current_condition(); if (r)
} current_cond_ = right_->current_condition();
}
bool l = false;
if (left_) if (left_)
{ {
left_->first(); l = left_->first();
current_cond_ = left_->current_condition(); if (l)
} current_cond_ = left_->current_condition();
}
return r || l;
} }
bool bool

View file

@ -90,8 +90,8 @@ namespace spot
virtual ~tgba_succ_iterator_union(); virtual ~tgba_succ_iterator_union();
// iteration // iteration
void first(); bool first();
void next(); bool next();
bool done() const; bool done() const;
// inspection // inspection

View file

@ -109,20 +109,32 @@ namespace spot
// iteration // iteration
void bool
first() first()
{ {
left_ = bddtrue;
if (it_) if (it_)
it_->first(); it_->first();
left_ = bddtrue; // Return true even if it_ is done, because
// we have to build a sink state.
return true;
} }
void bool
next() next()
{ {
left_ -= current_condition(); if (!it_ || it_->done())
if (it_) {
it_->next(); left_ = bddfalse;
return false;
}
left_ -= it_->current_condition();
if (left_ == bddfalse)
return false;
it_->next();
// Return true even if it_ is done, because
// we have to build a sink state.
return true;
} }
bool bool