* src/tgbaalgos/Makefile.am (tgbaalgos_HEADERS): Add reachiters.hh.
(libtgbaalgos_la_SOURCES): Add reachiters.cc. * src/tgbaalgos/dotty.cc, src/tgbaalgos/save.cc: Rewrite using spot::tgba_reachable_iterator_breadth_first. * src/tgbatest/explicit.test, src/tgbatest/tgbaread.test, src/tgbatest/tripprod.test: Adjust expected output.
This commit is contained in:
parent
664e49e07e
commit
e24d3be8a7
9 changed files with 322 additions and 114 deletions
11
ChangeLog
11
ChangeLog
|
|
@ -1,9 +1,18 @@
|
||||||
|
2003-07-25 Alexandre Duret-Lutz <aduret@src.lip6.fr>
|
||||||
|
|
||||||
|
* src/tgbaalgos/Makefile.am (tgbaalgos_HEADERS): Add reachiters.hh.
|
||||||
|
(libtgbaalgos_la_SOURCES): Add reachiters.cc.
|
||||||
|
* src/tgbaalgos/dotty.cc, src/tgbaalgos/save.cc: Rewrite using
|
||||||
|
spot::tgba_reachable_iterator_breadth_first.
|
||||||
|
* src/tgbatest/explicit.test, src/tgbatest/tgbaread.test,
|
||||||
|
src/tgbatest/tripprod.test: Adjust expected output.
|
||||||
|
|
||||||
2003-07-24 Alexandre Duret-Lutz <aduret@src.lip6.fr>
|
2003-07-24 Alexandre Duret-Lutz <aduret@src.lip6.fr>
|
||||||
|
|
||||||
* configure.ac: Output iface/gspn/defs.
|
* configure.ac: Output iface/gspn/defs.
|
||||||
* iface/gspn/Makefile.am (EXTRA_DIST): Add $(TESTS).
|
* iface/gspn/Makefile.am (EXTRA_DIST): Add $(TESTS).
|
||||||
(TESTS, check_SCRIPTS, distclean-local): New.
|
(TESTS, check_SCRIPTS, distclean-local): New.
|
||||||
* iface/gspn/dcswave.test, iface/gspn/simple.test,
|
* iface/gspn/dcswave.test, iface/gspn/simple.test,
|
||||||
iface/gspn/defs.in: New files.
|
iface/gspn/defs.in: New files.
|
||||||
* iface/gspn/dottygspn.cc (main): Take the list of properties
|
* iface/gspn/dottygspn.cc (main): Take the list of properties
|
||||||
of interest in argument.
|
of interest in argument.
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ AM_CXXFLAGS = $(WARNING_CXXFLAGS)
|
||||||
tgbaalgosdir = $(pkgincludedir)/tgbaalgos
|
tgbaalgosdir = $(pkgincludedir)/tgbaalgos
|
||||||
|
|
||||||
tgbaalgos_HEADERS = \
|
tgbaalgos_HEADERS = \
|
||||||
|
reachiter.hh \
|
||||||
dotty.hh \
|
dotty.hh \
|
||||||
lbtt.hh \
|
lbtt.hh \
|
||||||
ltl2tgba.hh \
|
ltl2tgba.hh \
|
||||||
|
|
@ -11,6 +12,7 @@ tgbaalgos_HEADERS = \
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libtgbaalgos.la
|
noinst_LTLIBRARIES = libtgbaalgos.la
|
||||||
libtgbaalgos_la_SOURCES = \
|
libtgbaalgos_la_SOURCES = \
|
||||||
|
reachiter.cc \
|
||||||
dotty.cc \
|
dotty.cc \
|
||||||
lbtt.cc \
|
lbtt.cc \
|
||||||
ltl2tgba.cc \
|
ltl2tgba.cc \
|
||||||
|
|
|
||||||
|
|
@ -1,80 +1,60 @@
|
||||||
#include <map>
|
|
||||||
#include "tgba/tgba.hh"
|
#include "tgba/tgba.hh"
|
||||||
#include "dotty.hh"
|
#include "dotty.hh"
|
||||||
#include "tgba/bddprint.hh"
|
#include "tgba/bddprint.hh"
|
||||||
|
#include "reachiter.hh"
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
typedef std::map<state*, int, state_ptr_less_than> seen_map;
|
|
||||||
|
|
||||||
/// Output and record a state.
|
class dotty_bfs : public tgba_reachable_iterator_breadth_first
|
||||||
static bool
|
|
||||||
dotty_state(std::ostream& os,
|
|
||||||
const tgba* g, state* st, seen_map& m, int& node)
|
|
||||||
{
|
{
|
||||||
seen_map::iterator i = m.find(st);
|
public:
|
||||||
|
dotty_bfs(const tgba* a, std::ostream& os)
|
||||||
|
: tgba_reachable_iterator_breadth_first(a), os_(os)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Already drawn?
|
void
|
||||||
if (i != m.end())
|
start()
|
||||||
{
|
{
|
||||||
node = i->second;
|
os_ << "digraph G {" << std::endl;
|
||||||
return false;
|
os_ << " size=\"7.26,10.69\"" << std::endl;
|
||||||
}
|
os_ << " 0 [label=\"\", style=invis]" << std::endl;
|
||||||
|
os_ << " 0 -> 1" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
node = m.size() + 1;
|
void
|
||||||
m[st] = node;
|
end()
|
||||||
|
{
|
||||||
|
os_ << "}" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
os << " " << node << " [label=\""
|
void
|
||||||
<< g->format_state(st) << "\"]" << std::endl;
|
process_state(const state* s, int n, tgba_succ_iterator*)
|
||||||
return true;
|
{
|
||||||
}
|
os_ << " " << n << " [label=\""
|
||||||
|
<< automata_->format_state(s) << "\"]" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
/// Process successors.
|
void
|
||||||
static void
|
process_link(int in, int out, const tgba_succ_iterator* si)
|
||||||
dotty_rec(std::ostream& os,
|
{
|
||||||
const tgba* g, state* st, seen_map& m, int father)
|
os_ << " " << in << " -> " << out << " [label=\"";
|
||||||
{
|
bdd_print_set(os_, automata_->get_dict(),
|
||||||
tgba_succ_iterator* si = g->succ_iter(st);
|
si->current_condition()) << "\\n";
|
||||||
for (si->first(); !si->done(); si->next())
|
bdd_print_set(os_, automata_->get_dict(),
|
||||||
{
|
si->current_accepting_conditions()) << "\"]" << std::endl;
|
||||||
int node;
|
}
|
||||||
state* s = si->current_state();
|
|
||||||
bool recurse = dotty_state(os, g, s, m, node);
|
private:
|
||||||
os << " " << father << " -> " << node << " [label=\"";
|
std::ostream& os_;
|
||||||
bdd_print_set(os, g->get_dict(), si->current_condition()) << "\\n";
|
};
|
||||||
bdd_print_set(os, g->get_dict(), si->current_accepting_conditions())
|
|
||||||
<< "\"]" << std::endl;
|
|
||||||
if (recurse)
|
|
||||||
{
|
|
||||||
dotty_rec(os, g, s, m, node);
|
|
||||||
// Do not delete S, it is used as key in M.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete si;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream&
|
std::ostream&
|
||||||
dotty_reachable(std::ostream& os, const tgba* g)
|
dotty_reachable(std::ostream& os, const tgba* g)
|
||||||
{
|
{
|
||||||
seen_map m;
|
dotty_bfs d(g, os);
|
||||||
state* state = g->get_init_state();
|
d.run();
|
||||||
os << "digraph G {" << std::endl;
|
|
||||||
os << " size=\"7.26,10.69\"" << std::endl;
|
|
||||||
os << " 0 [label=\"\", style=invis]" << std::endl;
|
|
||||||
int init;
|
|
||||||
dotty_state(os, g, state, m, init);
|
|
||||||
os << " 0 -> " << init << std::endl;
|
|
||||||
dotty_rec(os, g, state, m, init);
|
|
||||||
os << "}" << std::endl;
|
|
||||||
|
|
||||||
// Finally delete all states used as keys in m:
|
|
||||||
for (seen_map::iterator i = m.begin(); i != m.end(); ++i)
|
|
||||||
delete i->first;
|
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
126
src/tgbaalgos/reachiter.cc
Normal file
126
src/tgbaalgos/reachiter.cc
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
#include "reachiter.hh"
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
// tgba_reachable_iterator
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
tgba_reachable_iterator::tgba_reachable_iterator(const tgba* a)
|
||||||
|
: automata_(a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
tgba_reachable_iterator::~tgba_reachable_iterator()
|
||||||
|
{
|
||||||
|
for (seen_map::const_iterator s = seen.begin(); s != seen.end(); ++s)
|
||||||
|
delete s->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tgba_reachable_iterator::run()
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
start();
|
||||||
|
state* i = automata_->get_init_state();
|
||||||
|
add_state(i);
|
||||||
|
seen[i] = ++n;
|
||||||
|
const state* t;
|
||||||
|
while ((t = next_state()))
|
||||||
|
{
|
||||||
|
assert(seen.find(t) != seen.end());
|
||||||
|
int tn = seen[t];
|
||||||
|
tgba_succ_iterator* si = automata_->succ_iter(t);
|
||||||
|
process_state(t, tn, si);
|
||||||
|
for (si->first(); ! si->done(); si->next())
|
||||||
|
{
|
||||||
|
const state* current = si->current_state();
|
||||||
|
seen_map::const_iterator s = seen.find(current);
|
||||||
|
if (s == seen.end())
|
||||||
|
{
|
||||||
|
seen[current] = ++n;
|
||||||
|
add_state(current);
|
||||||
|
process_link(tn, n, si);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
process_link(tn, seen[current], si);
|
||||||
|
delete current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete si;
|
||||||
|
}
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tgba_reachable_iterator::start()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tgba_reachable_iterator::end()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tgba_reachable_iterator::process_state(const state*, int,
|
||||||
|
tgba_succ_iterator*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tgba_reachable_iterator::process_link(int, int, const tgba_succ_iterator*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// tgba_reachable_iterator_depth_first
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
tgba_reachable_iterator_depth_first::
|
||||||
|
tgba_reachable_iterator_depth_first(const tgba* a)
|
||||||
|
: tgba_reachable_iterator(a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tgba_reachable_iterator_depth_first::add_state(const state* s)
|
||||||
|
{
|
||||||
|
todo.push(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
const state*
|
||||||
|
tgba_reachable_iterator_depth_first::next_state()
|
||||||
|
{
|
||||||
|
if (todo.empty())
|
||||||
|
return 0;
|
||||||
|
const state* s = todo.top();
|
||||||
|
todo.pop();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tgba_reachable_iterator_breadth_first
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
tgba_reachable_iterator_breadth_first::
|
||||||
|
tgba_reachable_iterator_breadth_first(const tgba* a)
|
||||||
|
: tgba_reachable_iterator(a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tgba_reachable_iterator_breadth_first::add_state(const state* s)
|
||||||
|
{
|
||||||
|
todo.push_back(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
const state*
|
||||||
|
tgba_reachable_iterator_breadth_first::next_state()
|
||||||
|
{
|
||||||
|
if (todo.empty())
|
||||||
|
return 0;
|
||||||
|
const state* s = todo.front();
|
||||||
|
todo.pop_front();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
94
src/tgbaalgos/reachiter.hh
Normal file
94
src/tgbaalgos/reachiter.hh
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
#ifndef SPOT_TGBAALGOS_REACHITER_HH
|
||||||
|
# define SPOT_TGBAALGOS_REACHITER_HH
|
||||||
|
|
||||||
|
#include "tgba/tgba.hh"
|
||||||
|
#include <stack>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
/// \brief Iterate over all reachable states of a spot::tgba.
|
||||||
|
class tgba_reachable_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tgba_reachable_iterator(const tgba* a);
|
||||||
|
virtual ~tgba_reachable_iterator();
|
||||||
|
|
||||||
|
/// \brief Iterate over all reachable states of a spot::tgba.
|
||||||
|
///
|
||||||
|
/// This is a template method that will call add_state(), next_state(),
|
||||||
|
/// start(), end(), process_state(), and process_link(), while it
|
||||||
|
/// iterate over state.
|
||||||
|
void run();
|
||||||
|
|
||||||
|
/// \name Todo list management.
|
||||||
|
///
|
||||||
|
/// spot::tgba_reachable_iterator_depth_first and
|
||||||
|
/// spot::tgba_reachable_iterator_breadth_first offer two precanned
|
||||||
|
/// implementations for these functions.
|
||||||
|
/// \{
|
||||||
|
/// \brief Called by run() to register newly discovered states.
|
||||||
|
virtual void add_state(const state* s) = 0;
|
||||||
|
/// \brief Called by run() to obtain the
|
||||||
|
virtual const state* next_state() = 0;
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
/// Called by run() before starting its iteration.
|
||||||
|
virtual void start();
|
||||||
|
/// Called by run() once all states have been explored.
|
||||||
|
virtual void end();
|
||||||
|
|
||||||
|
/// Called by run() to process a state.
|
||||||
|
///
|
||||||
|
/// \param s The current state.
|
||||||
|
/// \param n An unique number assigned to \a s.
|
||||||
|
/// \param si The spot::tgba_succ_iterator for \a s.
|
||||||
|
virtual void process_state(const state* s, int n, tgba_succ_iterator* si);
|
||||||
|
/// Called by run() to process a transition.
|
||||||
|
///
|
||||||
|
/// \param in The source state number.
|
||||||
|
/// \param out The destination state number.
|
||||||
|
/// \param si The spot::tgba_succ_iterator positionned on the current
|
||||||
|
/// transition.
|
||||||
|
virtual void process_link(int in, int out, const tgba_succ_iterator* si);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const tgba* automata_; ///< The spot::tgba to explore.
|
||||||
|
|
||||||
|
typedef std::map<const state*, int, state_ptr_less_than> seen_map;
|
||||||
|
seen_map seen; ///< States already seen.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief An implementation of spot::tgba_reachable_iterator that browses
|
||||||
|
/// states depth first.
|
||||||
|
class tgba_reachable_iterator_depth_first : public tgba_reachable_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tgba_reachable_iterator_depth_first(const tgba* a);
|
||||||
|
|
||||||
|
virtual void add_state(const state* s);
|
||||||
|
virtual const state* next_state();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::stack<const state*> todo; ///< A stack of state yet to explore.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief An implementation of spot::tgba_reachable_iterator that browses
|
||||||
|
/// states breadth first.
|
||||||
|
class tgba_reachable_iterator_breadth_first : public tgba_reachable_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tgba_reachable_iterator_breadth_first(const tgba* a);
|
||||||
|
|
||||||
|
virtual void add_state(const state* s);
|
||||||
|
virtual const state* next_state();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::deque<const state*> todo; ///< A queue of state yet to explore.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SPOT_TGBAALGOS_REACHITER_HH
|
||||||
|
|
@ -1,63 +1,60 @@
|
||||||
#include <set>
|
|
||||||
#include "tgba/tgba.hh"
|
#include "tgba/tgba.hh"
|
||||||
#include "save.hh"
|
#include "save.hh"
|
||||||
#include "tgba/bddprint.hh"
|
#include "tgba/bddprint.hh"
|
||||||
#include "ltlvisit/tostring.hh"
|
#include "ltlvisit/tostring.hh"
|
||||||
|
#include "reachiter.hh"
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
typedef std::set<state*, state_ptr_less_than> seen_set;
|
|
||||||
|
|
||||||
/// Process successors.
|
class save_bfs : public tgba_reachable_iterator_breadth_first
|
||||||
static void
|
|
||||||
save_rec(std::ostream& os, const tgba* g, state* st, seen_set& m)
|
|
||||||
{
|
{
|
||||||
m.insert(st);
|
public:
|
||||||
std::string cur = g->format_state(st);
|
save_bfs(const tgba* a, std::ostream& os)
|
||||||
tgba_succ_iterator* si = g->succ_iter(st);
|
: tgba_reachable_iterator_breadth_first(a), os_(os)
|
||||||
for (si->first(); !si->done(); si->next())
|
{
|
||||||
{
|
}
|
||||||
state* s = si->current_state();
|
|
||||||
os << "\"" << cur << "\", \"" << g->format_state(s) << "\", ";
|
|
||||||
|
|
||||||
bdd_print_sat(os, g->get_dict(), si->current_condition()) << ",";
|
void
|
||||||
bdd_print_acc(os, g->get_dict(), si->current_accepting_conditions())
|
start()
|
||||||
<< ";" << std::endl;
|
{
|
||||||
|
const bdd_dict* d = automata_->get_dict();
|
||||||
|
os_ << "acc =";
|
||||||
|
for (bdd_dict::fv_map::const_iterator ai = d->acc_map.begin();
|
||||||
|
ai != d->acc_map.end(); ++ai)
|
||||||
|
{
|
||||||
|
os_ << " \"";
|
||||||
|
ltl::to_string(ai->first, os_) << "\"";
|
||||||
|
}
|
||||||
|
os_ << ";" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
process_state(const state* s, int, tgba_succ_iterator* si)
|
||||||
|
{
|
||||||
|
const bdd_dict* d = automata_->get_dict();
|
||||||
|
std::string cur = automata_->format_state(s);
|
||||||
|
for (si->first(); !si->done(); si->next())
|
||||||
|
{
|
||||||
|
state* dest = si->current_state();
|
||||||
|
os_ << "\"" << cur << "\", \""
|
||||||
|
<< automata_->format_state(dest) << "\", ";
|
||||||
|
bdd_print_sat(os_, d, si->current_condition()) << ",";
|
||||||
|
bdd_print_acc(os_, d, si->current_accepting_conditions());
|
||||||
|
os_ << ";" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::ostream& os_;
|
||||||
|
};
|
||||||
|
|
||||||
// Destination already explored?
|
|
||||||
seen_set::iterator i = m.find(s);
|
|
||||||
if (i != m.end())
|
|
||||||
{
|
|
||||||
delete s;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
save_rec(os, g, s, m);
|
|
||||||
// Do not delete S, it is used as key in M.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete si;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream&
|
std::ostream&
|
||||||
tgba_save_reachable(std::ostream& os, const tgba* g)
|
tgba_save_reachable(std::ostream& os, const tgba* g)
|
||||||
{
|
{
|
||||||
const bdd_dict* d = g->get_dict();
|
save_bfs b(g, os);
|
||||||
os << "acc =";
|
b.run();
|
||||||
for (bdd_dict::fv_map::const_iterator ai = d->acc_map.begin();
|
|
||||||
ai != d->acc_map.end(); ++ai)
|
|
||||||
{
|
|
||||||
os << " \"";
|
|
||||||
ltl::to_string(ai->first, os) << "\"";
|
|
||||||
}
|
|
||||||
os << ";" << std::endl;
|
|
||||||
|
|
||||||
seen_set m;
|
|
||||||
state* state = g->get_init_state();
|
|
||||||
save_rec(os, g, state, m);
|
|
||||||
// Finally delete all states used as keys in m:
|
|
||||||
for (seen_set::iterator i = m.begin(); i != m.end(); ++i)
|
|
||||||
delete *i;
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@ cat >expected <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
size="7.26,10.69"
|
size="7.26,10.69"
|
||||||
0 [label="", style=invis]
|
0 [label="", style=invis]
|
||||||
1 [label="state 0"]
|
|
||||||
0 -> 1
|
0 -> 1
|
||||||
2 [label="state 1"]
|
1 [label="state 0"]
|
||||||
1 -> 2 [label="T\n<Acc[p]:0, Acc[q]:1, Acc[r]:0><Acc[p]:1, Acc[q]:0, Acc[r]:0>"]
|
1 -> 2 [label="T\n<Acc[p]:0, Acc[q]:1, Acc[r]:0><Acc[p]:1, Acc[q]:0, Acc[r]:0>"]
|
||||||
3 [label="state 2"]
|
2 [label="state 1"]
|
||||||
2 -> 3 [label="<a:1>\n<Acc[p]:0, Acc[q]:0, Acc[r]:1>"]
|
2 -> 3 [label="<a:1>\n<Acc[p]:0, Acc[q]:0, Acc[r]:1>"]
|
||||||
|
3 [label="state 2"]
|
||||||
3 -> 1 [label="<b:1, c:1>\nF"]
|
3 -> 1 [label="<b:1, c:1>\nF"]
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@ cat >expected <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
size="7.26,10.69"
|
size="7.26,10.69"
|
||||||
0 [label="", style=invis]
|
0 [label="", style=invis]
|
||||||
1 [label="s1"]
|
|
||||||
0 -> 1
|
0 -> 1
|
||||||
2 [label="s2"]
|
1 [label="s1"]
|
||||||
1 -> 2 [label="<a:1, b:0>\n<Acc[c]:0, Acc[d]:1><Acc[c]:1, Acc[d]:0>"]
|
1 -> 2 [label="<a:1, b:0>\n<Acc[c]:0, Acc[d]:1><Acc[c]:1, Acc[d]:0>"]
|
||||||
3 [label="state 3"]
|
2 [label="s2"]
|
||||||
2 -> 3 [label="<a:1>\n<Acc[c]:1, Acc[d]:0>"]
|
2 -> 3 [label="<a:1>\n<Acc[c]:1, Acc[d]:0>"]
|
||||||
|
3 [label="state 3"]
|
||||||
3 -> 1 [label="T\nF"]
|
3 -> 1 [label="T\nF"]
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@ cat >expected <<EOF
|
||||||
acc = "p1" "p2" "p3" "p4";
|
acc = "p1" "p2" "p3" "p4";
|
||||||
"s1 * s1 * s1", "s3 * s2 * s2", a b, "p1" "p2";
|
"s1 * s1 * s1", "s3 * s2 * s2", a b, "p1" "p2";
|
||||||
"s1 * s1 * s1", "s2 * s2 * s2", a b, "p1" "p2";
|
"s1 * s1 * s1", "s2 * s2 * s2", a b, "p1" "p2";
|
||||||
"s2 * s2 * s2", "s3 * s1 * s3", a c, "p3" "p4";
|
|
||||||
"s1 * s1 * s1", "s3 * s2 * s3", a b, "p1" "p2";
|
"s1 * s1 * s1", "s3 * s2 * s3", a b, "p1" "p2";
|
||||||
"s1 * s1 * s1", "s2 * s2 * s3", b, "p1" "p2";
|
"s1 * s1 * s1", "s2 * s2 * s3", b, "p1" "p2";
|
||||||
|
"s2 * s2 * s2", "s3 * s1 * s3", a c, "p3" "p4";
|
||||||
"s2 * s2 * s3", "s3 * s1 * s2", a c, "p3" "p4";
|
"s2 * s2 * s3", "s3 * s1 * s2", a c, "p3" "p4";
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue