* src/tgbaalgos/magic.hh: Fix a comment and remove se05 interface.

* src/tgbaalgos/magic.cc: Fix a comment.
* src/tgbaalgos/se05.hh: New file.
* src/tgbaalgos/se05.cc: Fix a comment.
* src/tgbaalgos/tau03.hh: New file.
* src/tgbaalgos/tau03.cc: New file.
* src/tgbaalgos/Makefile.am: Add it.
* src/tgbatest/ltl2tgba.cc: Add tau03 new emptiness check.
* src/tgbatest/randtgba.cc: Add tau03 new emptiness check.
* src/tgbatest/emptchkr: Fix a comment.
* src/tgbatest/tba_samples_from_spin/explicit1_1.tba,
src/tgbatest/tba_samples_from_spin/explicit1_2.tba,
src/tgbatest/tba_samples_from_spin/explicit1_3.tba,
src/tgbatest/tba_samples_from_spin/explicit1_4.tba,
src/tgbatest/tba_samples_from_spin/explicit1_5.tba,
src/tgbatest/tba_samples_from_spin/explicit1_6.tba,
src/tgbatest/tba_samples_from_spin/explicit1_7.tba,
src/tgbatest/tba_samples_from_spin/explicit1_8.tba,
src/tgbatest/tba_samples_from_spin/explicit1_9.tba,
src/tgbatest/tba_samples_from_spin/explicit2_1.tba,
src/tgbatest/tba_samples_from_spin/explicit2_2.tba,
src/tgbatest/tba_samples_from_spin/explicit2_3.tba,
src/tgbatest/tba_samples_from_spin/explicit2_4.tba,
src/tgbatest/tba_samples_from_spin/explicit2_5.tba,
src/tgbatest/tba_samples_from_spin/explicit2_6.tba,
src/tgbatest/tba_samples_from_spin/explicit2_7.tba,
src/tgbatest/tba_samples_from_spin/explicit2_8.tba,
src/tgbatest/tba_samples_from_spin/explicit2_9.tba: New files
* src/tgbatest/tba_samples_from_spin.test : New test.
* src/tgbatest/Makefile.am: Add it.
This commit is contained in:
Denis Poitrenaud 2004-11-17 17:07:25 +00:00
parent c3e399c837
commit 9bea364e40
31 changed files with 836079 additions and 133 deletions

View file

@ -1,3 +1,36 @@
2004-11-17 Poitrenaud Denis <denis@src.lip6.fr>
* src/tgbaalgos/magic.hh: Fix a comment and remove se05 interface.
* src/tgbaalgos/magic.cc: Fix a comment.
* src/tgbaalgos/se05.hh: New file.
* src/tgbaalgos/se05.cc: Fix a comment.
* src/tgbaalgos/tau03.hh: New file.
* src/tgbaalgos/tau03.cc: New file.
* src/tgbaalgos/Makefile.am: Add it.
* src/tgbatest/ltl2tgba.cc: Add tau03 new emptiness check.
* src/tgbatest/randtgba.cc: Add tau03 new emptiness check.
* src/tgbatest/emptchkr: Fix a comment.
* src/tgbatest/tba_samples_from_spin/explicit1_1.tba,
src/tgbatest/tba_samples_from_spin/explicit1_2.tba,
src/tgbatest/tba_samples_from_spin/explicit1_3.tba,
src/tgbatest/tba_samples_from_spin/explicit1_4.tba,
src/tgbatest/tba_samples_from_spin/explicit1_5.tba,
src/tgbatest/tba_samples_from_spin/explicit1_6.tba,
src/tgbatest/tba_samples_from_spin/explicit1_7.tba,
src/tgbatest/tba_samples_from_spin/explicit1_8.tba,
src/tgbatest/tba_samples_from_spin/explicit1_9.tba,
src/tgbatest/tba_samples_from_spin/explicit2_1.tba,
src/tgbatest/tba_samples_from_spin/explicit2_2.tba,
src/tgbatest/tba_samples_from_spin/explicit2_3.tba,
src/tgbatest/tba_samples_from_spin/explicit2_4.tba,
src/tgbatest/tba_samples_from_spin/explicit2_5.tba,
src/tgbatest/tba_samples_from_spin/explicit2_6.tba,
src/tgbatest/tba_samples_from_spin/explicit2_7.tba,
src/tgbatest/tba_samples_from_spin/explicit2_8.tba,
src/tgbatest/tba_samples_from_spin/explicit2_9.tba: New files
* src/tgbatest/tba_samples_from_spin.test : New test.
* src/tgbatest/Makefile.am: Add it.
2004-11-17 Alexandre Duret-Lutz <adl@src.lip6.fr> 2004-11-17 Alexandre Duret-Lutz <adl@src.lip6.fr>
* src/tgba/tgba.hh, src/tgbaalgos/dotty.hh, * src/tgba/tgba.hh, src/tgbaalgos/dotty.hh,

View file

@ -43,7 +43,9 @@ tgbaalgos_HEADERS = \
replayrun.hh \ replayrun.hh \
rundotdec.hh \ rundotdec.hh \
save.hh \ save.hh \
se05.hh \
stats.hh \ stats.hh \
tau03.hh \
reductgba_sim.hh reductgba_sim.hh
noinst_LTLIBRARIES = libtgbaalgos.la noinst_LTLIBRARIES = libtgbaalgos.la
@ -66,6 +68,7 @@ libtgbaalgos_la_SOURCES = \
save.cc \ save.cc \
se05.cc \ se05.cc \
stats.cc \ stats.cc \
tau03.cc \
reductgba_sim.cc \ reductgba_sim.cc \
reductgba_sim_del.cc reductgba_sim_del.cc

View file

@ -19,12 +19,12 @@
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA. // 02111-1307, USA.
#include <cstring> #include <cassert>
#include <iostream>
#include "misc/hash.hh"
#include <list> #include <list>
#include <iterator> #include <iterator>
#include <cassert> #include "misc/hash.hh"
#include "tgba/tgba.hh"
#include "emptiness.hh"
#include "magic.hh" #include "magic.hh"
namespace spot namespace spot
@ -129,10 +129,10 @@ namespace spot
const state* s; const state* s;
/// Design the next successor of \a s which has to be visited. /// Design the next successor of \a s which has to be visited.
tgba_succ_iterator* it; tgba_succ_iterator* it;
/// The label of the transition followed to reach \a s /// The label of the transition traversed to reach \a s
/// (false for the first one). /// (false for the first one).
bdd label; bdd label;
/// The acc set of the transition followed to reach \a s /// The acceptance set of the transition traversed to reach \a s
/// (false for the first one). /// (false for the first one).
bdd acc; bdd acc;
}; };
@ -255,9 +255,6 @@ namespace spot
f.it->next(); f.it->next();
typename heap::color_ref c = h.get_color_ref(s_prime); typename heap::color_ref c = h.get_color_ref(s_prime);
if (c.is_white()) if (c.is_white())
// Notice that this case is taken into account only to
// support successive calls to the check method. Without
// this functionnality, one can check assert(c.is_white()).
// Go down the edge (f.s, <label, acc>, s_prime) // Go down the edge (f.s, <label, acc>, s_prime)
{ {
++nbn; ++nbn;

View file

@ -22,25 +22,26 @@
#ifndef SPOT_TGBAALGOS_MAGIC_HH #ifndef SPOT_TGBAALGOS_MAGIC_HH
# define SPOT_TGBAALGOS_MAGIC_HH # define SPOT_TGBAALGOS_MAGIC_HH
#include "tgba/tgba.hh" #include <cstddef>
#include "emptiness.hh"
namespace spot namespace spot
{ {
class tgba;
class emptiness_check;
/// \addtogroup emptiness_check_algorithms /// \addtogroup emptiness_check_algorithms
/// @{ /// @{
/// \brief Returns an emptiness checker on the spot::tgba automaton \a a. /// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
/// During the visit of \a a, the returned checker stores explicitely all
/// the traversed states.
/// ///
/// \pre The automaton \a a must have at most one accepting condition (i.e. /// \pre The automaton \a a must have at most one accepting condition (i.e.
/// it is a TBA). /// it is a TBA).
/// ///
/// The method \a check() of the returned checker can be called several times /// During the visit of \a a, the returned checker stores explicitely all
/// the traversed states.
/// The method \a check() of the checker can be called several times
/// (until it returns a null pointer) to enumerate all the visited accepting /// (until it returns a null pointer) to enumerate all the visited accepting
/// paths. The implemented algorithm is the following. /// paths. The implemented algorithm is the following:
/// ///
/// \verbatim /// \verbatim
/// procedure check () /// procedure check ()
@ -95,111 +96,31 @@ namespace spot
emptiness_check* explicit_magic_search(const tgba *a); emptiness_check* explicit_magic_search(const tgba *a);
/// \brief Returns an emptiness checker on the spot::tgba automaton \a a. /// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
/// During the visit of \a a, the returned checker does not store explicitely
/// the traversed states but uses the bit state hashing technic. However, the
/// implemented algorithm is the same as the one of
/// spot::explicit_magic_search.
/// ///
/// \pre The automaton \a a must have at most one accepting condition (i.e. /// \pre The automaton \a a must have at most one accepting condition (i.e.
/// it is a TBA). /// it is a TBA).
/// ///
/// During the visit of \a a, the returned checker does not store explicitely
/// the traversed states but uses the bit-state hashing technic presented in:
///
/// \verbatim
/// @book{Holzmann91,
/// author = {G.J. Holzmann},
/// title = {Design and Validation of Computer Protocols},
/// publisher = {Prentice-Hall},
/// address = {Englewood Cliffs, New Jersey},
/// year = {1991}
/// }
/// \endverbatim
///
/// Consequently, the detection of an acceptence cycle is not ensured. The
/// implemented algorithm is the same as the one of
/// spot::explicit_magic_search.
///
/// \sa spot::explicit_magic_search /// \sa spot::explicit_magic_search
/// ///
emptiness_check* bit_state_hashing_magic_search(const tgba *a, size_t size); emptiness_check* bit_state_hashing_magic_search(const tgba *a, size_t size);
/// \brief Returns an emptiness check on the spot::tgba automaton \a a.
/// During the visit of \a a, the returned checker stores explicitely all
/// the traversed states.
///
/// \pre The automaton \a a must have at most one accepting condition (i.e.
/// it is a TBA).
///
/// The method \a check() of the returned checker can be called several times
/// (until it returns a null pointer) to enumerate all the visited accepting
/// paths. The implemented algorithm is the following:
///
/// \verbatim
/// procedure check ()
/// begin
/// weight = 0;
/// call dfs_blue(s0);
/// end;
///
/// procedure dfs_blue (s)
/// begin
/// s.color = cyan;
/// s.weight = weight;
/// for all t in post(s) do
/// if t.color == white then
/// if the edge (s,t) is accepting then
/// weight = weight + 1;
/// end if;
/// call dfs_blue(t);
/// if the edge (s,t) is accepting then
/// weight = weight - 1;
/// end if;
/// else if t.color == cyan and
/// (the edge (s,t) is accepting or
/// weight > t.weight) then
/// report cycle;
/// end if;
/// if the edge (s,t) is accepting then
/// call dfs_red(t);
/// end if;
/// end for;
/// s.color = blue;
/// end;
///
/// procedure dfs_red(s)
/// begin
/// if s.color == cyan then
/// report cycle;
/// end if;
/// s.color = red;
/// for all t in post(s) do
/// if t.color != red then
/// call dfs_red(t);
/// end if;
/// end for;
/// end;
/// \endverbatim
///
/// It is an adaptation to TBA (and a slight extension) of the one
/// presented in
/// \verbatim
/// InProceedings{ schwoon.05.tacas,
/// author = {Stephan Schwoon and Javier Esparza},
/// title = {A Note on On-The-Fly Verification Algorithms},
/// booktitle = {TACAS'05},
/// pages = {},
/// year = {2005},
/// volume = {},
/// series = {LNCS},
/// publisher = {Springer-Verlag}
/// }
/// \endverbatim
///
/// The extention consists in the introduction of a weight associated
/// to each state in the blue stack (the cyan states). The weight of a
/// cyan state corresponds to the number of accepting arcs traversed to reach
/// it from the initial state. Weights are used to detect accepting cycle in
/// the blue dfs.
///
emptiness_check* explicit_se05_search(const tgba *a);
/// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
/// During the visit of \a a, the returned checker does not store explicitely
/// the traversed states but uses the bit state hashing technic. However, the
/// implemented algorithm is the same as the one of
/// spot::explicit_se05_search.
///
/// \pre The automaton \a a must have at most one accepting condition (i.e.
/// it is a TBA).
///
/// \sa spot::explicit_se05_search
///
emptiness_check* bit_state_hashing_se05_search(const tgba *a, size_t size);
/// @} /// @}
} }

View file

@ -24,11 +24,14 @@
#ifdef TRACE #ifdef TRACE
#include <iostream> #include <iostream>
#endif #endif
#include "misc/hash.hh"
#include <cassert>
#include <list> #include <list>
#include <iterator> #include <iterator>
#include <cassert> #include "misc/hash.hh"
#include "magic.hh" #include "tgba/tgba.hh"
#include "emptiness.hh"
#include "se05.hh"
namespace spot namespace spot
{ {
@ -133,10 +136,10 @@ namespace spot
const state* s; const state* s;
/// Design the next successor of \a s which has to be visited. /// Design the next successor of \a s which has to be visited.
tgba_succ_iterator* it; tgba_succ_iterator* it;
/// The label of the transition followed to reach \a s /// The label of the transition traversed to reach \a s
/// (false for the first one). /// (false for the first one).
bdd label; bdd label;
/// The acc set of the transition followed to reach \a s /// The acceptance set of the transition traversed to reach \a s
/// (false for the first one). /// (false for the first one).
bdd acc; bdd acc;
}; };
@ -314,9 +317,6 @@ namespace spot
f.it->next(); f.it->next();
typename heap::color_ref c = h.get_color_ref(s_prime); typename heap::color_ref c = h.get_color_ref(s_prime);
if (c.is_white()) if (c.is_white())
// Notice that this case is taken into account only to
// support successive calls to the check method. Without
// this functionnality => assert(c.is_white())
// Go down the edge (f.s, <label, acc>, s_prime) // Go down the edge (f.s, <label, acc>, s_prime)
{ {
#ifdef TRACE #ifdef TRACE

148
src/tgbaalgos/se05.hh Normal file
View file

@ -0,0 +1,148 @@
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Spot; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
#ifndef SPOT_TGBAALGOS_SE05_HH
# define SPOT_TGBAALGOS_SE05_HH
#include <cstddef>
namespace spot
{
class tgba;
class emptiness_check;
/// \addtogroup emptiness_check_algorithms
/// @{
/// \brief Returns an emptiness check on the spot::tgba automaton \a a.
///
/// \pre The automaton \a a must have at most one accepting condition (i.e.
/// it is a TBA).
///
/// During the visit of \a a, the returned checker stores explicitely all
/// the traversed states.
/// The method \a check() of the checker can be called several times
/// (until it returns a null pointer) to enumerate all the visited accepting
/// paths. The implemented algorithm is an optimization of
/// spot::explicit_magic_search and is the following:
///
/// \verbatim
/// procedure check ()
/// begin
/// weight = 0;
/// call dfs_blue(s0);
/// end;
///
/// procedure dfs_blue (s)
/// begin
/// s.color = cyan;
/// s.weight = weight;
/// for all t in post(s) do
/// if t.color == white then
/// if the edge (s,t) is accepting then
/// weight = weight + 1;
/// end if;
/// call dfs_blue(t);
/// if the edge (s,t) is accepting then
/// weight = weight - 1;
/// end if;
/// else if t.color == cyan and
/// (the edge (s,t) is accepting or
/// weight > t.weight) then
/// report cycle;
/// end if;
/// if the edge (s,t) is accepting then
/// call dfs_red(t);
/// end if;
/// end for;
/// s.color = blue;
/// end;
///
/// procedure dfs_red(s)
/// begin
/// if s.color == cyan then
/// report cycle;
/// end if;
/// s.color = red;
/// for all t in post(s) do
/// if t.color != red then
/// call dfs_red(t);
/// end if;
/// end for;
/// end;
/// \endverbatim
///
/// It is an adaptation to TBA (and a slight extension) of the one
/// presented in
/// \verbatim
/// @techreport{SE04,
/// author = {Stefan Schwoon and Javier Esparza},
/// institution = {Universit{\"a}t Stuttgart, Fakult\"at Informatik,
/// Elektrotechnik und Informationstechnik},
/// month = {November},
/// number = {2004/06},
/// title = {A Note on On-The-Fly Verification Algorithms},
/// year = {2004},
/// url =
///{http://www.fmi.uni-stuttgart.de/szs/publications/info/schwoosn.SE04.shtml}
/// }
/// \endverbatim
///
/// The extention consists in the introduction of a weight associated
/// to each state in the blue stack (the cyan states). The weight of a
/// cyan state corresponds to the number of accepting arcs traversed to reach
/// it from the initial state. Weights are used to detect accepting cycle in
/// the blue dfs.
///
/// \sa spot::explicit_magic_search
///
emptiness_check* explicit_se05_search(const tgba *a);
/// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
///
/// \pre The automaton \a a must have at most one accepting condition (i.e.
/// it is a TBA).
///
/// During the visit of \a a, the returned checker does not store explicitely
/// the traversed states but uses the bit-state hashing technicpresented in:
///
/// \verbatim
/// @book{Holzmann91,
/// author = {G.J. Holzmann},
/// title = {Design and Validation of Computer Protocols},
/// publisher = {Prentice-Hall},
/// address = {Englewood Cliffs, New Jersey},
/// year = {1991}
/// }
/// \endverbatim
///
/// Consequently, the detection of an acceptence cycle is not ensured. The
/// implemented algorithm is the same as the one of
/// spot::explicit_se05_search.
///
/// \sa spot::explicit_se05_search
///
emptiness_check* bit_state_hashing_se05_search(const tgba *a, size_t size);
/// @}
}
#endif // SPOT_TGBAALGOS_MAGIC_HH

423
src/tgbaalgos/tau03.cc Normal file
View file

@ -0,0 +1,423 @@
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Spot; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//#define TRACE
#ifdef TRACE
#include <iostream>
#include "tgba/bddprint.hh"
#endif
#include <cassert>
#include <list>
#include <iterator>
#include "misc/hash.hh"
#include "tgba/tgba.hh"
#include "emptiness.hh"
#include "magic.hh"
#include "tau03.hh"
namespace spot
{
namespace
{
enum color {WHITE, CYAN, BLUE};
/// \brief Emptiness checker on spot::tgba automata having at most one
/// accepting condition (i.e. a TBA).
template <typename heap>
class tau03_search : public emptiness_check
{
public:
/// \brief Initialize the search algorithm on the automaton \a a
tau03_search(const tgba *a, size_t size)
: h(size), a(a), all_cond(a->all_acceptance_conditions())
{
assert(a->number_of_acceptance_conditions() > 0);
}
virtual ~tau03_search()
{
// Release all iterators on the stacks.
while (!st_blue.empty())
{
h.pop_notify(st_blue.front().s);
delete st_blue.front().it;
st_blue.pop_front();
}
while (!st_red.empty())
{
h.pop_notify(st_red.front().s);
delete st_red.front().it;
st_red.pop_front();
}
}
/// \brief Perform a Magic Search.
///
/// \return non null pointer iff the algorithm has found an
/// accepting path.
virtual emptiness_check_result* check()
{
if (!st_red.empty())
{
assert(!st_blue.empty());
return 0;
}
assert(st_blue.empty());
nbn = nbt = 0;
sts = mdp = 0;
const state* s0 = a->get_init_state();
++nbn;
h.add_new_state(s0, CYAN);
push(st_blue, s0, bddfalse, bddfalse);
if (dfs_blue())
return new emptiness_check_result;
return 0;
}
virtual std::ostream& print_stats(std::ostream &os) const
{
os << nbn << " distinct nodes visited" << std::endl;
os << nbt << " transitions explored" << std::endl;
os << mdp << " nodes for the maximal stack depth" << std::endl;
return os;
}
private:
/// \brief counters for statistics (number of distinct nodes, of
/// transitions and maximal stacks size.
int nbn, nbt, mdp, sts;
struct stack_item
{
stack_item(const state* n, tgba_succ_iterator* i, bdd l, bdd a)
: s(n), it(i), label(l), acc(a) {};
/// The visited state.
const state* s;
/// Design the next successor of \a s which has to be visited.
tgba_succ_iterator* it;
/// The label of the transition traversed to reach \a s
/// (false for the first one).
bdd label;
/// The acceptance set of the transition traversed to reach \a s
/// (false for the first one).
bdd acc;
};
typedef std::list<stack_item> stack_type;
void push(stack_type& st, const state* s,
const bdd& label, const bdd& acc)
{
++sts;
if (sts>mdp)
mdp = sts;
tgba_succ_iterator* i = a->succ_iter(s);
i->first();
st.push_front(stack_item(s, i, label, acc));
}
/// \brief Stack of the blue dfs.
stack_type st_blue;
/// \brief Stack of the red dfs.
stack_type st_red;
/// \brief Map where each visited state is colored
/// by the last dfs visiting it.
heap h;
/// State targeted by the red dfs.
const state* target;
/// The automata to check.
const tgba* a;
/// The unique accepting condition of the automaton \a a.
bdd all_cond;
bool dfs_blue()
{
while (!st_blue.empty())
{
stack_item& f = st_blue.front();
#ifdef TRACE
std::cout << "DFS_BLUE treats: "
<< a->format_state(f.s) << std::endl;
#endif
if (!f.it->done())
{
++nbt;
const state *s_prime = f.it->current_state();
bdd label = f.it->current_condition();
bdd acc = f.it->current_acceptance_conditions();
#ifdef TRACE
std::cout << " Visit the successor: "
<< a->format_state(s_prime) << std::endl;
#endif
f.it->next();
typename heap::color_ref c = h.get_color_ref(s_prime);
if (c.is_white())
// Go down the edge (f.s, <label, acc>, s_prime)
{
++nbn;
#ifdef TRACE
std::cout << " It is white, go down" << std::endl;
#endif
h.add_new_state(s_prime, CYAN);
push(st_blue, s_prime, label, acc);
}
else // Backtrack the edge (f.s, <label, acc>, s_prime)
{
#ifdef TRACE
std::cout << " It is cyan or blue, pop it"
<< std::endl;
#endif
h.pop_notify(s_prime);
}
}
else
// Backtrack the edge
// (predecessor of f.s in st_blue, <f.label, f.acc>, f.s)
{
#ifdef TRACE
std::cout << " All the successors have been visited"
<< ", rescan this successors"
<< std::endl;
#endif
typename heap::color_ref c = h.get_color_ref(f.s);
assert(!c.is_white());
tgba_succ_iterator* i = a->succ_iter(f.s);
for (i->first(); !i->done(); i->next())
{
++nbt;
const state *s_prime = i->current_state();
bdd label = i->current_condition();
bdd acc = i->current_acceptance_conditions();
typename heap::color_ref c_prime = h.get_color_ref(s_prime);
assert(!c_prime.is_white());
bdd acu = acc | c.get_acc();
#ifdef TRACE
std::cout << "DFS_BLUE rescanning from: "
<< a->format_state(f.s) << std::endl;
std::cout << " tests "
<< a->format_state(s_prime) << std::endl;
std::cout << " if ";
bdd_print_acc(std::cout, a->get_dict(), acu);
std::cout << std::endl;
std::cout << " is not included in ";
bdd_print_acc(std::cout, a->get_dict(), c_prime.get_acc());
std::cout << std::endl;
#endif
if ((c_prime.get_acc() & acu) != acu)
{
#ifdef TRACE
std::cout << " that is true, starts a red dfs with "
<< a->format_state(s_prime)
<< " propagating: ";
bdd_print_acc(std::cout, a->get_dict(), acu);
std::cout << std::endl;
#endif
target = f.s;
c_prime.cumulate_acc(acu);
push(st_red, s_prime, label, acc);
if (target->compare(s_prime) == 0 &&
c_prime.get_acc() == all_cond)
{
delete i;
return true;
}
if (dfs_red(acu) || c.get_acc() == all_cond)
{
delete i;
return true;
}
}
}
delete i;
c.set_color(BLUE);
delete f.it;
--sts;
h.pop_notify(f.s);
st_blue.pop_front();
}
}
return false;
}
bool dfs_red(const bdd& acu)
{
assert(!st_red.empty());
while (!st_red.empty())
{
stack_item& f = st_red.front();
#ifdef TRACE
std::cout << "DFS_RED treats: "
<< a->format_state(f.s) << std::endl;
#endif
if (!f.it->done()) // Go down
{
++nbt;
const state *s_prime = f.it->current_state();
bdd label = f.it->current_condition();
bdd acc = f.it->current_acceptance_conditions();
#ifdef TRACE
std::cout << " Visit the successor: "
<< a->format_state(s_prime) << std::endl;
#endif
f.it->next();
typename heap::color_ref c_prime = h.get_color_ref(s_prime);
if (!c_prime.is_white() &&
(c_prime.get_acc() & acu) != acu)
{
#ifdef TRACE
std::cout << " It is cyan or blue and propagation "
<< "is nedded, go down"
<< std::endl;
#endif
c_prime.cumulate_acc(acu);
push(st_red, s_prime, label, acc);
if (target->compare(s_prime) == 0 &&
c_prime.get_acc() == all_cond)
return true;
}
else
{
#ifdef TRACE
std::cout << " It is white or no propagation is needed "
<< ", pop it"
<< std::endl;
#endif
if (c_prime.is_white())
delete s_prime;
h.pop_notify(s_prime);
}
}
else // Backtrack
{
#ifdef TRACE
std::cout << " All the successors have been visited"
<< ", pop it" << std::endl;
#endif
--sts;
h.pop_notify(f.s);
delete f.it;
st_red.pop_front();
}
}
return false;
}
};
class explicit_tau03_search_heap
{
public:
class color_ref
{
public:
color_ref(color* c, bdd* a) :p(c), acc(a)
{
}
color get_color() const
{
return *p;
}
void set_color(color c)
{
assert(!is_white());
*p = c;
}
const bdd& get_acc() const
{
assert(!is_white());
return *acc;
}
void cumulate_acc(const bdd& a)
{
assert(!is_white());
*acc |= a;
}
bool is_white() const
{
return p == 0;
}
private:
color *p;
bdd* acc;
};
explicit_tau03_search_heap(size_t)
{
}
~explicit_tau03_search_heap()
{
hash_type::const_iterator s = h.begin();
while (s != h.end())
{
// Advance the iterator before deleting the "key" pointer.
const state* ptr = s->first;
++s;
delete ptr;
}
}
color_ref get_color_ref(const state*& s)
{
hash_type::iterator it = h.find(s);
if (it==h.end())
return color_ref(0, 0);
if (s!=it->first)
{
delete s;
s = it->first;
}
return color_ref(&(it->second.first), &(it->second.second));
}
void add_new_state(const state* s, color c)
{
assert(h.find(s)==h.end());
h.insert(std::make_pair(s, std::make_pair(c, bddfalse)));
}
void pop_notify(const state*)
{
}
private:
typedef Sgi::hash_map<const state*, std::pair<color, bdd>,
state_ptr_hash, state_ptr_equal> hash_type;
hash_type h;
};
} // anonymous
emptiness_check* explicit_tau03_search(const tgba *a)
{
return new tau03_search<explicit_tau03_search_heap>(a, 0);
}
}

110
src/tgbaalgos/tau03.hh Normal file
View file

@ -0,0 +1,110 @@
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Spot; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
#ifndef SPOT_TGBAALGOS_TAU03_HH
# define SPOT_TGBAALGOS_TAU03_HH
namespace spot
{
class tgba;
class emptiness_check;
/// \addtogroup emptiness_check_algorithms
/// @{
/// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
///
/// \pre The automaton \a a must have at least one accepting condition.
///
/// During the visit of \a a, the returned checker stores explicitely all
/// the traversed states. The implemented algorithm is the following:
///
/// \verbatim
/// procedure check ()
/// begin
/// call dfs_blue(s0);
/// end;
///
/// procedure dfs_blue (s)
/// begin
/// s.color = cyan;
/// s.acc = emptyset;
/// for all t in post(s) do
/// if t.color == white then
/// call dfs_blue(t);
/// end if;
/// end for;
/// for all t in post(s) do
/// let (s, l, a, t) be the edge from s to t;
/// if a U s.acc not included in t.acc then
/// target = s;
/// call dfs_red(t, a U s.acc);
/// end if;
/// end for;
/// if s.acc == all_acc then
/// report a cycle;
/// end if;
/// s.color = blue;
/// end;
///
/// procedure dfs_red(s, A)
/// begin
/// s.acc = s.acc U A;
/// // The following test has been added to the origiginal algorithm to
/// // report a cycle as soon as possible (and to mimic the classic magic
/// // search.
/// if s == target and s.acc == all_acc then
/// report a cycle;
/// end if;
/// for all t in post(s) do
/// let (s, l, a, t) be the edge from s to t;
/// if t.color != white and A not included in t.acc then
/// call dfs_red(t, A);
/// end if;
/// end for;
/// end;
/// \endverbatim
///
/// This algorithm is the one presented in
///
/// \verbatim
/// @techreport{HUT-TCS-A83,
/// address = {Espoo, Finland},
/// author = {Heikki Tauriainen},
/// institution = {Helsinki University of Technology, Laboratory for
/// Theoretical Computer Science},
/// month = {December},
/// number = {A83},
/// pages = {132},
/// title = {On Translating Linear Temporal Logic into Alternating and
/// Nondeterministic Automata},
/// type = {Research Report},
/// year = {2003},
/// url = {http://www.tcs.hut.fi/Publications/info/bibdb.HUT-TCS-A83.shtml}
/// }
/// \endverbatim
///
emptiness_check* explicit_tau03_search(const tgba *a);
/// @}
}
#endif // SPOT_TGBAALGOS_MAGIC_HH

View file

@ -84,6 +84,7 @@ TESTS = \
emptchke.test \ emptchke.test \
dfs.test \ dfs.test \
emptchkr.test \ emptchkr.test \
tba_samples_from_spin.test \
spotlbtt.test spotlbtt.test
EXTRA_DIST = $(TESTS) ltl2baw.pl EXTRA_DIST = $(TESTS) ltl2baw.pl

View file

@ -36,7 +36,7 @@ run 0 ./randtgba -e 100 -s 50 -r -a 1 0.1 -d 0.02
run 0 ./randtgba -e 100 -s 100 -r -a 1 0.1 -d 0.04 run 0 ./randtgba -e 100 -s 100 -r -a 1 0.1 -d 0.04
run 0 ./randtgba -e 100 -s 150 -r -a 1 0.1 -d 0.08 run 0 ./randtgba -e 100 -s 150 -r -a 1 0.1 -d 0.08
# Two acceptance conditions # Four acceptance conditions
run 0 ./randtgba -e 100 -s 200 -r -a 4 0.1 -d 0.01 run 0 ./randtgba -e 100 -s 200 -r -a 4 0.1 -d 0.01
run 0 ./randtgba -e 100 -s 250 -r -a 4 0.1 -d 0.02 run 0 ./randtgba -e 100 -s 250 -r -a 4 0.1 -d 0.02
run 0 ./randtgba -e 100 -s 300 -r -a 4 0.1 -d 0.04 run 0 ./randtgba -e 100 -s 300 -r -a 4 0.1 -d 0.04

View file

@ -36,6 +36,8 @@
#include "tgbaalgos/lbtt.hh" #include "tgbaalgos/lbtt.hh"
#include "tgba/tgbatba.hh" #include "tgba/tgbatba.hh"
#include "tgbaalgos/magic.hh" #include "tgbaalgos/magic.hh"
#include "tgbaalgos/se05.hh"
#include "tgbaalgos/tau03.hh"
#include "tgbaalgos/gtec/gtec.hh" #include "tgbaalgos/gtec/gtec.hh"
#include "tgbaalgos/gtec/ce.hh" #include "tgbaalgos/gtec/ce.hh"
#include "tgbaparse/public.hh" #include "tgbaparse/public.hh"
@ -125,7 +127,8 @@ syntax(char* prog)
<< " bsh_se05_search[(heap size in MB - 10MB by default)]" << " bsh_se05_search[(heap size in MB - 10MB by default)]"
<< std::endl << std::endl
<< " bsh_se05_search_repeated[(heap size in MB - 10MB" << " bsh_se05_search_repeated[(heap size in MB - 10MB"
<< " by default)]" << std::endl; << " by default)]" << std::endl
<< " tau03_search" << std::endl;
exit(2); exit(2);
} }
@ -144,9 +147,10 @@ main(int argc, char** argv)
int output = 0; int output = 0;
int formula_index = 0; int formula_index = 0;
std::string echeck_algo; std::string echeck_algo;
enum { None, Couvreur, Couvreur2, MagicSearch, Se05Search } echeck = None; enum { None, Couvreur, Couvreur2, MagicSearch, Se05Search, Tau03Search }
echeck = None;
enum { NoneDup, BFS, DFS } dupexp = NoneDup; enum { NoneDup, BFS, DFS } dupexp = NoneDup;
bool magic_many = false; bool search_many = false;
bool bit_state_hashing = false; bool bit_state_hashing = false;
int heap_size = 10*1024*1024; int heap_size = 10*1024*1024;
bool expect_counter_example = false; bool expect_counter_example = false;
@ -368,7 +372,7 @@ main(int argc, char** argv)
{ {
echeck = MagicSearch; echeck = MagicSearch;
degeneralize_maybe = true; degeneralize_maybe = true;
magic_many = true; search_many = true;
} }
else if (echeck_algo == "bsh_magic_search") else if (echeck_algo == "bsh_magic_search")
{ {
@ -381,7 +385,7 @@ main(int argc, char** argv)
echeck = MagicSearch; echeck = MagicSearch;
degeneralize_maybe = true; degeneralize_maybe = true;
bit_state_hashing = true; bit_state_hashing = true;
magic_many = true; search_many = true;
} }
else if (echeck_algo == "se05_search") else if (echeck_algo == "se05_search")
{ {
@ -392,7 +396,7 @@ main(int argc, char** argv)
{ {
echeck = Se05Search; echeck = Se05Search;
degeneralize_maybe = true; degeneralize_maybe = true;
magic_many = true; search_many = true;
} }
else if (echeck_algo == "bsh_se05_search") else if (echeck_algo == "bsh_se05_search")
{ {
@ -405,7 +409,11 @@ main(int argc, char** argv)
echeck = Se05Search; echeck = Se05Search;
degeneralize_maybe = true; degeneralize_maybe = true;
bit_state_hashing = true; bit_state_hashing = true;
magic_many = true; search_many = true;
}
else if (echeck_algo == "tau03_search")
{
echeck = Tau03Search;
} }
else else
{ {
@ -649,6 +657,19 @@ main(int argc, char** argv)
else else
ec = spot::explicit_se05_search(a); ec = spot::explicit_se05_search(a);
break; break;
case Tau03Search:
if (a->number_of_acceptance_conditions() == 0)
{
std::cout << "To apply tau03_search, the automaton must have at "
<< "least on accepting condition. Try with another "
<< "algorithm." << std::endl;
}
else
{
ec = spot::explicit_tau03_search(a);
}
break;
} }
if (ec) if (ec)
@ -702,7 +723,7 @@ main(int argc, char** argv)
} }
delete res; delete res;
} }
while (magic_many); while (search_many);
delete ec; delete ec;
} }

View file

@ -34,6 +34,8 @@
#include "tgbaalgos/emptiness.hh" #include "tgbaalgos/emptiness.hh"
#include "tgbaalgos/gtec/gtec.hh" #include "tgbaalgos/gtec/gtec.hh"
#include "tgbaalgos/magic.hh" #include "tgbaalgos/magic.hh"
#include "tgbaalgos/se05.hh"
#include "tgbaalgos/tau03.hh"
#include "tgbaalgos/replayrun.hh" #include "tgbaalgos/replayrun.hh"
void void
@ -42,7 +44,7 @@ syntax(char* prog)
std::cerr << "Usage: "<< prog << " [OPTIONS...] PROPS..." << std::endl std::cerr << "Usage: "<< prog << " [OPTIONS...] PROPS..." << std::endl
<< std::endl << std::endl
<< "Options:" << std::endl << "Options:" << std::endl
<< " -a N F number of accepence conditions a propability that" << " -a N F number of acceptance conditions and probability that"
<< " one is true [0 0.0]" << std::endl << " one is true [0 0.0]" << std::endl
<< " -d F density of the graph [0.2]" << std::endl << " -d F density of the graph [0.2]" << std::endl
<< " -e N compare result of all " << " -e N compare result of all "
@ -205,6 +207,13 @@ main(int argc, char** argv)
ec_name.push_back("couvreur99_shy"); ec_name.push_back("couvreur99_shy");
ec_safe.push_back(true); ec_safe.push_back(true);
if (opt_n_acc >= 1)
{
ec_obj.push_back(spot::explicit_tau03_search(a));
ec_name.push_back("explicit_tau03_search");
ec_safe.push_back(true);
}
if (opt_n_acc <= 1) if (opt_n_acc <= 1)
{ {
ec_obj.push_back(spot::explicit_magic_search(a)); ec_obj.push_back(spot::explicit_magic_search(a));

View file

@ -0,0 +1,76 @@
#!/bin/sh
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
# et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Spot; see the file COPYING. If not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
. ./defs
light_run()
{
expected_exitcode=$1
shift
exitcode=0
"$@" || exitcode=$?
test $exitcode = $expected_exitcode || exit 1
}
set -e
expect_ce()
{
light_run 0 ./ltl2tgba -X -e "$1"
light_run 0 ./ltl2tgba -X -ecouvreur99_shy "$1"
light_run 0 ./ltl2tgba -X -emagic_search "$1"
light_run 0 ./ltl2tgba -X -ebsh_magic_search "$1"
light_run 0 ./ltl2tgba -X -ese05_search "$1"
light_run 0 ./ltl2tgba -X -ebsh_se05_search "$1"
light_run 0 ./ltl2tgba -X -etau03_search "$1"
}
expect_no()
{
light_run 0 ./ltl2tgba -X -E "$1"
light_run 0 ./ltl2tgba -X -Ecouvreur99_shy "$1"
light_run 0 ./ltl2tgba -X -Emagic_search "$1"
light_run 0 ./ltl2tgba -X -Ebsh_magic_search "$1"
light_run 0 ./ltl2tgba -X -Ese05_search "$1"
light_run 0 ./ltl2tgba -X -Ebsh_se05_search "$1"
light_run 0 ./ltl2tgba -X -Etau03_search "$1"
}
expect_no tba_samples_from_spin/explicit1_1.tba
expect_ce tba_samples_from_spin/explicit1_2.tba
expect_no tba_samples_from_spin/explicit1_3.tba
expect_no tba_samples_from_spin/explicit1_4.tba
expect_ce tba_samples_from_spin/explicit1_5.tba
expect_no tba_samples_from_spin/explicit1_6.tba
expect_no tba_samples_from_spin/explicit1_7.tba
expect_ce tba_samples_from_spin/explicit1_8.tba
expect_ce tba_samples_from_spin/explicit1_9.tba
expect_ce tba_samples_from_spin/explicit2_1.tba
expect_ce tba_samples_from_spin/explicit2_2.tba
expect_no tba_samples_from_spin/explicit2_3.tba
expect_no tba_samples_from_spin/explicit2_4.tba
expect_ce tba_samples_from_spin/explicit2_5.tba
expect_no tba_samples_from_spin/explicit2_6.tba
expect_ce tba_samples_from_spin/explicit2_7.tba
expect_ce tba_samples_from_spin/explicit2_8.tba
expect_no tba_samples_from_spin/explicit2_9.tba

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff