Commit 63917def authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz

twa_run: keep a pointer to the automaton

This simplify all laters invocations, because we do not have to pass
the automaton the run was generated on.

This fixes #113 by allowing the __str__ function to be implemented on
runs.

* src/twaalgos/emptiness.cc, src/twaalgos/emptiness.hh (twa_run):
Store the automaton.
(prin_twa_run): Rewrite as an overloaded <<.
* src/twaalgos/reducerun.cc, src/twaalgos/reducerun.hh (reduce_run):
Do not like the automaton as a parameter.
* src/twaalgos/replayrun.cc, src/twaalgos/replayrun.hh (replay_twa_run):
Likewise.
* src/bin/common_aoutput.hh, src/bin/ltlcross.cc,
src/tests/complementation.cc, src/tests/ikwiad.cc,
src/tests/randtgba.cc, src/twaalgos/gtec/ce.cc, src/twaalgos/gv04.cc,
src/twaalgos/magic.cc, src/twaalgos/ndfs_result.hxx,
src/twaalgos/se05.cc, src/twaalgos/projrun.cc: Adjust.
* wrap/python/ajax/spotcgi.in: Add a __str__ function to twa_run_ptr.
* wrap/python/spot_impl.i: Adjust.
parent e7cc8926
...@@ -179,7 +179,7 @@ public: ...@@ -179,7 +179,7 @@ public:
{ {
auto run = res->accepting_run(); auto run = res->accepting_run();
assert(run); assert(run);
run = reduce_run(aut, run); run = reduce_run(run);
spot::tgba_word w(run); spot::tgba_word w(run);
w.simplify(); w.simplify();
std::ostringstream out; std::ostringstream out;
......
...@@ -703,7 +703,7 @@ namespace ...@@ -703,7 +703,7 @@ namespace
auto run = res->accepting_run(); auto run = res->accepting_run();
if (run) if (run)
{ {
run = reduce_run(prod, run); run = reduce_run(run);
std::cerr << "; both automata accept the infinite word\n" std::cerr << "; both automata accept the infinite word\n"
<< " "; << " ";
spot::tgba_word w(run); spot::tgba_word w(run);
......
...@@ -248,7 +248,7 @@ int main(int argc, char* argv[]) ...@@ -248,7 +248,7 @@ int main(int argc, char* argv[])
if (auto run = res->accepting_run()) if (auto run = res->accepting_run())
{ {
spot::print_dot(std::cout, ec->automaton()); spot::print_dot(std::cout, ec->automaton());
spot::print_twa_run(std::cout, ec->automaton(), run); std::cout << run;
} }
} }
else else
......
...@@ -1580,14 +1580,13 @@ checked_main(int argc, char** argv) ...@@ -1580,14 +1580,13 @@ checked_main(int argc, char** argv)
if (opt_reduce) if (opt_reduce)
{ {
tm.start("reducing accepting run"); tm.start("reducing accepting run");
run = spot::reduce_run(res->automaton(), run); run = spot::reduce_run(run);
tm.stop("reducing accepting run"); tm.stop("reducing accepting run");
} }
if (accepting_run_replay) if (accepting_run_replay)
{ {
tm.start("replaying acc. run"); tm.start("replaying acc. run");
if (!spot::replay_twa_run(std::cout, a, if (!spot::replay_twa_run(std::cout, run, true))
run, true))
exit_code = 1; exit_code = 1;
tm.stop("replaying acc. run"); tm.stop("replaying acc. run");
} }
...@@ -1601,7 +1600,7 @@ checked_main(int argc, char** argv) ...@@ -1601,7 +1600,7 @@ checked_main(int argc, char** argv)
} }
else else
{ {
spot::print_twa_run(std::cout, a, run); std::cout << run;
} }
tm.stop("printing accepting run"); tm.stop("printing accepting run");
} }
......
...@@ -1026,9 +1026,7 @@ main(int argc, char** argv) ...@@ -1026,9 +1026,7 @@ main(int argc, char** argv)
{ {
tm_ar.stop(algo); tm_ar.stop(algo);
std::ostringstream s; std::ostringstream s;
if (!spot::replay_twa_run(s, if (!spot::replay_twa_run(s, run))
res->automaton(),
run))
{ {
if (!opt_paper) if (!opt_paper)
std::cout << ", but could not replay " std::cout << ", but could not replay "
...@@ -1049,12 +1047,8 @@ main(int argc, char** argv) ...@@ -1049,12 +1047,8 @@ main(int argc, char** argv)
if (opt_reduce) if (opt_reduce)
{ {
auto redrun = auto redrun = spot::reduce_run(run);
spot::reduce_run(res->automaton(), run); if (!spot::replay_twa_run(s, redrun))
if (!spot::replay_twa_run(s,
res
->automaton(),
redrun))
{ {
if (!opt_paper) if (!opt_paper)
std::cout std::cout
......
...@@ -47,16 +47,15 @@ namespace spot ...@@ -47,16 +47,15 @@ namespace spot
twa_run::twa_run(const twa_run& run) twa_run::twa_run(const twa_run& run)
{ {
for (steps::const_iterator i = run.prefix.begin(); aut = run.aut;
i != run.prefix.end(); ++i) for (step s : run.prefix)
{ {
step s = { i->s->clone(), i->label, i->acc }; s.s = s.s->clone();
prefix.push_back(s); prefix.push_back(s);
} }
for (steps::const_iterator i = run.cycle.begin(); for (step s : run.cycle)
i != run.cycle.end(); ++i)
{ {
step s = { i->s->clone(), i->label, i->acc }; s.s = s.s->clone();
cycle.push_back(s); cycle.push_back(s);
} }
} }
...@@ -72,37 +71,27 @@ namespace spot ...@@ -72,37 +71,27 @@ namespace spot
return *this; return *this;
} }
// print_twa_run
//////////////////////////////////////////////////////////////////////
std::ostream& std::ostream&
print_twa_run(std::ostream& os, operator<<(std::ostream& os, const twa_run_ptr& run)
const const_twa_ptr& a,
const const_twa_run_ptr& run)
{ {
auto& a = run->aut;
bdd_dict_ptr d = a->get_dict(); bdd_dict_ptr d = a->get_dict();
auto pstep = [&](const twa_run::step& st)
{
os << " " << a->format_state(st.s) << "\n | ";
bdd_print_formula(os, d, st.label);
if (st.acc)
os << '\t' << st.acc;
os << '\n';
};
os << "Prefix:" << std::endl; os << "Prefix:" << std::endl;
for (twa_run::steps::const_iterator i = run->prefix.begin(); for (auto& s: run->prefix)
i != run->prefix.end(); ++i) pstep(s);
{
os << " " << a->format_state(i->s) << std::endl;
os << " | ";
bdd_print_formula(os, d, i->label);
os << '\t';
os << a->acc().format(i->acc);
os << std::endl;
}
os << "Cycle:" << std::endl; os << "Cycle:" << std::endl;
for (twa_run::steps::const_iterator i = run->cycle.begin(); for (auto& s: run->cycle)
i != run->cycle.end(); ++i) pstep(s);
{
os << " " << a->format_state(i->s) << std::endl;
os << " | ";
bdd_print_formula(os, d, i->label);
os << '\t';
os << a->acc().format(i->acc);
os << '\n';
}
return os; return os;
} }
......
...@@ -257,13 +257,12 @@ namespace spot ...@@ -257,13 +257,12 @@ namespace spot
/// \addtogroup emptiness_check_algorithms Emptiness-check algorithms /// \addtogroup emptiness_check_algorithms Emptiness-check algorithms
/// \ingroup emptiness_check /// \ingroup emptiness_check
/// \addtogroup twa_run TωA runs and supporting functions
/// \addtogroup twa_run TGBA runs and supporting functions
/// \ingroup emptiness_check /// \ingroup emptiness_check
/// @{ /// @{
/// An accepted run, for a tgba. /// An accepted run, for a twa.
struct SPOT_API twa_run struct SPOT_API twa_run final
{ {
struct step { struct step {
const state* s; const state* s;
...@@ -283,33 +282,34 @@ namespace spot ...@@ -283,33 +282,34 @@ namespace spot
steps prefix; steps prefix;
steps cycle; steps cycle;
const_twa_ptr aut;
~twa_run(); ~twa_run();
twa_run() twa_run(const const_twa_ptr& aut)
: aut(aut)
{ {
}; }
twa_run(const twa_run& run); twa_run(const twa_run& run);
twa_run& operator=(const twa_run& run); twa_run& operator=(const twa_run& run);
/// \brief Display a twa_run.
///
/// Output the prefix and cycle parts of the twa_run \a run on \a os.
///
/// The automaton object (stored by \a run) is used only to format
/// the states, and to know how to print the BDDs describing the
/// conditions and acceptance conditions of the run; it is
/// <b>not</b> used to replay the run. In other words this
/// function will work even if the twa_run you are trying to print
/// appears to connect states that are not connected.
///
/// This is unlike replay_twa_run(), which will ensure the run
/// actually exists in the automaton (and will also display any
/// transition annotation).
SPOT_API
friend std::ostream& operator<<(std::ostream& os, const twa_run_ptr& run);
}; };
/// \brief Display a twa_run.
///
/// Output the prefix and cycle parts of the twa_run \a run on \a os.
///
/// The automaton \a a is used only to format the states, and
/// to know how to print the BDDs describing the conditions and
/// acceptance conditions of the run; it is <b>not</b> used to
/// replay the run. In other words this function will work even if
/// the twa_run you are trying to print appears to connect states
/// of \a a that are not connected.
///
/// This is unlike replay_twa_run(), which will ensure the run
/// actually exists in the automaton (and will also display any
/// transition annotation).
SPOT_API std::ostream&
print_twa_run(std::ostream& os,
const const_twa_ptr& a,
const const_twa_run_ptr& run);
/// \brief Return an explicit_tgba corresponding to \a run (i.e. comparable /// \brief Return an explicit_tgba corresponding to \a run (i.e. comparable
/// states are merged). /// states are merged).
......
...@@ -94,7 +94,7 @@ namespace spot ...@@ -94,7 +94,7 @@ namespace spot
twa_run_ptr twa_run_ptr
couvreur99_check_result::accepting_run() couvreur99_check_result::accepting_run()
{ {
run_ = std::make_shared<twa_run>(); run_ = std::make_shared<twa_run>(ecs_->aut);
assert(!ecs_->root.empty()); assert(!ecs_->root.empty());
......
...@@ -287,7 +287,7 @@ namespace spot ...@@ -287,7 +287,7 @@ namespace spot
virtual twa_run_ptr virtual twa_run_ptr
accepting_run() accepting_run()
{ {
auto res = std::make_shared<twa_run>(); auto res = std::make_shared<twa_run>(automaton());
update_lowlinks(); update_lowlinks();
#ifdef TRACE #ifdef TRACE
......
...@@ -333,7 +333,7 @@ namespace spot ...@@ -333,7 +333,7 @@ namespace spot
assert(!ms_->st_blue.empty()); assert(!ms_->st_blue.empty());
assert(!ms_->st_red.empty()); assert(!ms_->st_red.empty());
auto run = std::make_shared<twa_run>(); auto run = std::make_shared<twa_run>(automaton());
typename stack_type::const_reverse_iterator i, j, end; typename stack_type::const_reverse_iterator i, j, end;
twa_run::steps* l; twa_run::steps* l;
......
...@@ -194,7 +194,7 @@ namespace spot ...@@ -194,7 +194,7 @@ namespace spot
assert(!acc_trans.empty()); assert(!acc_trans.empty());
auto run = std::make_shared<twa_run>(); auto run = std::make_shared<twa_run>(automaton());
// construct run->cycle from acc_trans. // construct run->cycle from acc_trans.
construct_cycle(run, acc_trans); construct_cycle(run, acc_trans);
// construct run->prefix (a minimal path from the initial state to any // construct run->prefix (a minimal path from the initial state to any
......
...@@ -32,7 +32,7 @@ namespace spot ...@@ -32,7 +32,7 @@ namespace spot
const const_twa_ptr& a_proj, const const_twa_ptr& a_proj,
const const_twa_run_ptr& run) const const_twa_run_ptr& run)
{ {
auto res = std::make_shared<twa_run>(); auto res = std::make_shared<twa_run>(a_proj);
for (auto& i: run->prefix) for (auto& i: run->prefix)
res->prefix.emplace_back(a_run->project_state(i.s, a_proj), res->prefix.emplace_back(a_run->project_state(i.s, a_proj),
i.label, i.acc); i.label, i.acc);
......
...@@ -88,9 +88,10 @@ namespace spot ...@@ -88,9 +88,10 @@ namespace spot
} }
twa_run_ptr twa_run_ptr
reduce_run(const const_twa_ptr& a, const const_twa_run_ptr& org) reduce_run(const const_twa_run_ptr& org)
{ {
auto res = std::make_shared<twa_run>(); auto& a = org->aut;
auto res = std::make_shared<twa_run>(a);
state_set ss; state_set ss;
shortest_path shpath(a); shortest_path shpath(a);
shpath.set_target(&ss); shpath.set_target(&ss);
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2010, 2013, 2014 Laboratoire de Recherche et // Copyright (C) 2010, 2013, 2014, 2015 Laboratoire de Recherche et
// Développement 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
...@@ -31,8 +31,8 @@ namespace spot ...@@ -31,8 +31,8 @@ namespace spot
/// \ingroup twa_run /// \ingroup twa_run
/// \brief Reduce an accepting run. /// \brief Reduce an accepting run.
/// ///
/// Return a run which is accepting for \a a and that is no longer /// Return a run which is still accepting for <code>org->aut</code>,
/// than \a org. /// but is no longer than \a org.
SPOT_API twa_run_ptr SPOT_API twa_run_ptr
reduce_run(const const_twa_ptr& a, const const_twa_run_ptr& org); reduce_run(const const_twa_run_ptr& org);
} }
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2011, 2013, 2014 Laboratoire de Recherche et // Copyright (C) 2011, 2013, 2014, 2015 Laboratoire de Recherche et
// Développement de l'Epita (LRDE). // 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
...@@ -44,9 +44,10 @@ namespace spot ...@@ -44,9 +44,10 @@ namespace spot
} }
bool bool
replay_twa_run(std::ostream& os, const const_twa_ptr& a, replay_twa_run(std::ostream& os,
const const_twa_run_ptr& run, bool debug) const const_twa_run_ptr& run, bool debug)
{ {
auto& a = run->aut;
const state* s = a->get_init_state(); const state* s = a->get_init_state();
int serial = 1; int serial = 1;
const twa_run::steps* l; const twa_run::steps* l;
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2013, 2014 Laboratoire de Recherche et Developpement // Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et Developpement
// de l'Epita (LRDE). // 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
...@@ -34,21 +34,19 @@ namespace spot ...@@ -34,21 +34,19 @@ namespace spot
/// \ingroup twa_run /// \ingroup twa_run
/// \brief Replay a twa_run on a tgba. /// \brief Replay a twa_run on a tgba.
/// ///
/// This is similar to print_twa_run(), except that the run is /// This is similar to <code>os << run;</code>, except that the run is
/// actually replayed on the automaton while it is printed. Doing /// actually replayed on the automaton while it is printed. Doing
/// so makes it possible to display transition annotations (returned /// so makes it possible to display transition annotations (returned
/// by spot::tgba::transition_annotation()). The output will stop /// by spot::twa::transition_annotation()). The output will stop
/// if the run cannot be completed. /// if the run cannot be completed.
/// ///
/// \param run the run to replay /// \param run the run to replay
/// \param a the automata on which to replay that run
/// \param os the stream on which the replay should be traced /// \param os the stream on which the replay should be traced
/// \param debug if set the output will be more verbose and extra /// \param debug if set the output will be more verbose and extra
/// debugging informations will be output on failure /// debugging informations will be output on failure
/// \return true iff the run could be completed /// \return true iff the run could be completed
SPOT_API bool SPOT_API bool
replay_twa_run(std::ostream& os, replay_twa_run(std::ostream& os,
const const_twa_ptr& a, const const_twa_run_ptr& run,
const const_twa_run_ptr& run, bool debug = false);
bool debug = false);
} }
...@@ -339,7 +339,7 @@ namespace spot ...@@ -339,7 +339,7 @@ namespace spot
assert(!ms_->st_blue.empty()); assert(!ms_->st_blue.empty());
assert(!ms_->st_red.empty()); assert(!ms_->st_red.empty());
auto run = std::make_shared<twa_run>(); auto run = std::make_shared<twa_run>(automaton());
typename stack_type::const_reverse_iterator i, j, end; typename stack_type::const_reverse_iterator i, j, end;
twa_run::steps* l; twa_run::steps* l;
......
...@@ -840,11 +840,8 @@ if output_type == 'r': ...@@ -840,11 +840,8 @@ if output_type == 'r':
unbufprint('<div class="ec">An accepting run was found.<br/>') unbufprint('<div class="ec">An accepting run was found.<br/>')
if ec_run: if ec_run:
if print_acc_run: if print_acc_run:
s = spot.ostringstream()
spot.print_twa_run(s, ec_a, ec_run)
unbufprint('<div class="accrun">%s</div>' % unbufprint('<div class="accrun">%s</div>' %
cgi.escape(s.str())) cgi.escape(str(ec_run)))
del s
if draw_acc_run: if draw_acc_run:
render_automaton(spot.twa_run_to_tgba(ec_a, ec_run), False) render_automaton(spot.twa_run_to_tgba(ec_a, ec_run), False)
del ec_run del ec_run
......
...@@ -383,6 +383,15 @@ namespace std { ...@@ -383,6 +383,15 @@ namespace std {
} }
} }
%extend spot::twa_run_ptr {
std::string __str__()
{
std::ostringstream os;
os << *self;
return os.str();
}
}
%nodefaultctor std::ostream; %nodefaultctor std::ostream;
namespace std { namespace std {
class ostream {}; class ostream {};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment