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:
{
auto run = res->accepting_run();
assert(run);
run = reduce_run(aut, run);
run = reduce_run(run);
spot::tgba_word w(run);
w.simplify();
std::ostringstream out;
......
......@@ -703,7 +703,7 @@ namespace
auto run = res->accepting_run();
if (run)
{
run = reduce_run(prod, run);
run = reduce_run(run);
std::cerr << "; both automata accept the infinite word\n"
<< " ";
spot::tgba_word w(run);
......
......@@ -248,7 +248,7 @@ int main(int argc, char* argv[])
if (auto run = res->accepting_run())
{
spot::print_dot(std::cout, ec->automaton());
spot::print_twa_run(std::cout, ec->automaton(), run);
std::cout << run;
}
}
else
......
......@@ -1580,14 +1580,13 @@ checked_main(int argc, char** argv)
if (opt_reduce)
{
tm.start("reducing accepting run");
run = spot::reduce_run(res->automaton(), run);
run = spot::reduce_run(run);
tm.stop("reducing accepting run");
}
if (accepting_run_replay)
{
tm.start("replaying acc. run");
if (!spot::replay_twa_run(std::cout, a,
run, true))
if (!spot::replay_twa_run(std::cout, run, true))
exit_code = 1;
tm.stop("replaying acc. run");
}
......@@ -1601,7 +1600,7 @@ checked_main(int argc, char** argv)
}
else
{
spot::print_twa_run(std::cout, a, run);
std::cout << run;
}
tm.stop("printing accepting run");
}
......
......@@ -1026,9 +1026,7 @@ main(int argc, char** argv)
{
tm_ar.stop(algo);
std::ostringstream s;
if (!spot::replay_twa_run(s,
res->automaton(),
run))
if (!spot::replay_twa_run(s, run))
{
if (!opt_paper)
std::cout << ", but could not replay "
......@@ -1049,12 +1047,8 @@ main(int argc, char** argv)
if (opt_reduce)
{
auto redrun =
spot::reduce_run(res->automaton(), run);
if (!spot::replay_twa_run(s,
res
->automaton(),
redrun))
auto redrun = spot::reduce_run(run);
if (!spot::replay_twa_run(s, redrun))
{
if (!opt_paper)
std::cout
......
......@@ -47,16 +47,15 @@ namespace spot
twa_run::twa_run(const twa_run& run)
{
for (steps::const_iterator i = run.prefix.begin();
i != run.prefix.end(); ++i)
aut = run.aut;
for (step s : run.prefix)
{
step s = { i->s->clone(), i->label, i->acc };
s.s = s.s->clone();
prefix.push_back(s);
}
for (steps::const_iterator i = run.cycle.begin();
i != run.cycle.end(); ++i)
for (step s : run.cycle)
{
step s = { i->s->clone(), i->label, i->acc };
s.s = s.s->clone();
cycle.push_back(s);
}
}
......@@ -72,37 +71,27 @@ namespace spot
return *this;
}
// print_twa_run
//////////////////////////////////////////////////////////////////////
std::ostream&
print_twa_run(std::ostream& os,
const const_twa_ptr& a,
const const_twa_run_ptr& run)
operator<<(std::ostream& os, const twa_run_ptr& run)
{
auto& a = run->aut;
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;
for (twa_run::steps::const_iterator i = run->prefix.begin();
i != run->prefix.end(); ++i)
{
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;
}
for (auto& s: run->prefix)
pstep(s);
os << "Cycle:" << std::endl;
for (twa_run::steps::const_iterator i = run->cycle.begin();
i != run->cycle.end(); ++i)
{
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';
}
for (auto& s: run->cycle)
pstep(s);
return os;
}
......
......@@ -257,13 +257,12 @@ namespace spot
/// \addtogroup emptiness_check_algorithms Emptiness-check algorithms
/// \ingroup emptiness_check
/// \addtogroup twa_run TGBA runs and supporting functions
/// \addtogroup twa_run TωA runs and supporting functions
/// \ingroup emptiness_check
/// @{
/// An accepted run, for a tgba.
struct SPOT_API twa_run
/// An accepted run, for a twa.
struct SPOT_API twa_run final
{
struct step {
const state* s;
......@@ -283,33 +282,34 @@ namespace spot
steps prefix;
steps cycle;
const_twa_ptr aut;
~twa_run();
twa_run()
twa_run(const const_twa_ptr& aut)
: aut(aut)
{
};
}
twa_run(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
/// states are merged).
......
......@@ -94,7 +94,7 @@ namespace spot
twa_run_ptr
couvreur99_check_result::accepting_run()
{
run_ = std::make_shared<twa_run>();
run_ = std::make_shared<twa_run>(ecs_->aut);
assert(!ecs_->root.empty());
......
......@@ -287,7 +287,7 @@ namespace spot
virtual twa_run_ptr
accepting_run()
{
auto res = std::make_shared<twa_run>();
auto res = std::make_shared<twa_run>(automaton());
update_lowlinks();
#ifdef TRACE
......
......@@ -333,7 +333,7 @@ namespace spot
assert(!ms_->st_blue.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;
twa_run::steps* l;
......
......@@ -194,7 +194,7 @@ namespace spot
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_cycle(run, acc_trans);
// construct run->prefix (a minimal path from the initial state to any
......
......@@ -32,7 +32,7 @@ namespace spot
const const_twa_ptr& a_proj,
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)
res->prefix.emplace_back(a_run->project_state(i.s, a_proj),
i.label, i.acc);
......
......@@ -88,9 +88,10 @@ namespace spot
}
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;
shortest_path shpath(a);
shpath.set_target(&ss);
......
// -*- 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.
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
......@@ -31,8 +31,8 @@ namespace spot
/// \ingroup twa_run
/// \brief Reduce an accepting run.
///
/// Return a run which is accepting for \a a and that is no longer
/// than \a org.
/// Return a run which is still accepting for <code>org->aut</code>,
/// but is no longer than \a org.
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 -*-
// 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).
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
......@@ -44,9 +44,10 @@ namespace spot
}
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)
{
auto& a = run->aut;
const state* s = a->get_init_state();
int serial = 1;
const twa_run::steps* l;
......
// -*- 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).
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
......@@ -34,21 +34,19 @@ namespace spot
/// \ingroup twa_run
/// \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
/// 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.
///
/// \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 debug if set the output will be more verbose and extra
/// debugging informations will be output on failure
/// \return true iff the run could be completed
SPOT_API bool
replay_twa_run(std::ostream& os,
const const_twa_ptr& a,
const const_twa_run_ptr& run,
bool debug = false);
const const_twa_run_ptr& run,
bool debug = false);
}
......@@ -339,7 +339,7 @@ namespace spot
assert(!ms_->st_blue.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;
twa_run::steps* l;
......
......@@ -840,11 +840,8 @@ if output_type == 'r':
unbufprint('<div class="ec">An accepting run was found.<br/>')
if ec_run:
if print_acc_run:
s = spot.ostringstream()
spot.print_twa_run(s, ec_a, ec_run)
unbufprint('<div class="accrun">%s</div>' %
cgi.escape(s.str()))
del s
cgi.escape(str(ec_run)))
if draw_acc_run:
render_automaton(spot.twa_run_to_tgba(ec_a, ec_run), False)
del ec_run
......
......@@ -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;
namespace std {
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