rename src/tgbaalgos/ as src/twaalgos/
Automatic mass renaming. * src/tgbaalgos/: Rename as... * src/twaalgos/: ... this. * README, configure.ac, iface/ltsmin/modelcheck.cc, src/Makefile.am, src/bin/autfilt.cc, src/bin/common_aoutput.cc, src/bin/common_aoutput.hh, src/bin/common_output.hh, src/bin/common_post.hh, src/bin/dstar2tgba.cc, src/bin/ltl2tgba.cc, src/bin/ltl2tgta.cc, src/bin/ltlcross.cc, src/bin/ltldo.cc, src/bin/ltlfilt.cc, src/bin/randaut.cc, src/dstarparse/dra2ba.cc, src/dstarparse/nra2nba.cc, src/dstarparse/nsa2tgba.cc, src/graphtest/twagraph.cc, src/kripke/kripkeprint.cc, src/ltlvisit/contain.cc, src/ltlvisit/contain.hh, src/ltlvisit/exclusive.cc, src/taalgos/emptinessta.hh, src/tgbatest/checkpsl.cc, src/tgbatest/checkta.cc, src/tgbatest/complementation.cc, src/tgbatest/emptchk.cc, src/tgbatest/ltl2tgba.cc, src/tgbatest/ltlprod.cc, src/tgbatest/randtgba.cc, src/tgbatest/taatgba.cc, src/twa/twa.cc, src/twa/twagraph.hh, src/twa/twasafracomplement.cc, wrap/python/spot_impl.i: Adjust.
This commit is contained in:
parent
703fbd0e99
commit
de529df59f
159 changed files with 260 additions and 272 deletions
236
src/twaalgos/gtec/ce.cc
Normal file
236
src/twaalgos/gtec/ce.cc
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2010, 2011, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2004, 2005 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 3 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "ce.hh"
|
||||
#include "twaalgos/bfssteps.hh"
|
||||
#include "misc/hash.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
namespace
|
||||
{
|
||||
class shortest_path: public bfs_steps
|
||||
{
|
||||
public:
|
||||
shortest_path(const state_set* t,
|
||||
const std::shared_ptr<const couvreur99_check_status>& ecs,
|
||||
couvreur99_check_result* r)
|
||||
: bfs_steps(ecs->aut), target(t), ecs(ecs), r(r)
|
||||
{
|
||||
}
|
||||
|
||||
const state*
|
||||
search(const state* start, tgba_run::steps& l)
|
||||
{
|
||||
return this->bfs_steps::search(filter(start), l);
|
||||
}
|
||||
|
||||
const state*
|
||||
filter(const state* s)
|
||||
{
|
||||
r->inc_ars_prefix_states();
|
||||
auto i = ecs->h.find(s);
|
||||
s->destroy();
|
||||
// Ignore unknown states ...
|
||||
if (i == ecs->h.end())
|
||||
return nullptr;
|
||||
// ... as well as dead states.
|
||||
if (i->second == -1)
|
||||
return nullptr;
|
||||
return i->first;
|
||||
}
|
||||
|
||||
bool
|
||||
match(tgba_run::step&, const state* dest)
|
||||
{
|
||||
return target->find(dest) != target->end();
|
||||
}
|
||||
|
||||
private:
|
||||
state_set seen;
|
||||
const state_set* target;
|
||||
std::shared_ptr<const couvreur99_check_status> ecs;
|
||||
couvreur99_check_result* r;
|
||||
};
|
||||
}
|
||||
|
||||
couvreur99_check_result::couvreur99_check_result
|
||||
(const std::shared_ptr<const couvreur99_check_status>& ecs,
|
||||
option_map o)
|
||||
: emptiness_check_result(ecs->aut, o), ecs_(ecs)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned
|
||||
couvreur99_check_result::acss_states() const
|
||||
{
|
||||
int scc_root = ecs_->root.top().index;
|
||||
unsigned count = 0;
|
||||
for (auto i: ecs_->h)
|
||||
if (i.second >= scc_root)
|
||||
++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
tgba_run_ptr
|
||||
couvreur99_check_result::accepting_run()
|
||||
{
|
||||
run_ = std::make_shared<tgba_run>();
|
||||
|
||||
assert(!ecs_->root.empty());
|
||||
|
||||
// Compute an accepting cycle.
|
||||
accepting_cycle();
|
||||
|
||||
// Compute the prefix: it's the shortest path from the initial
|
||||
// state of the automata to any state of the cycle.
|
||||
|
||||
// Register all states from the cycle as target of the BFS.
|
||||
state_set ss;
|
||||
for (tgba_run::steps::const_iterator i = run_->cycle.begin();
|
||||
i != run_->cycle.end(); ++i)
|
||||
ss.insert(i->s);
|
||||
shortest_path shpath(&ss, ecs_, this);
|
||||
|
||||
const state* prefix_start = ecs_->aut->get_init_state();
|
||||
// There are two cases: either the initial state is already on
|
||||
// the cycle, or it is not. If it is, we will have to rotate
|
||||
// the cycle so it begins on this position. Otherwise we will shift
|
||||
// the cycle so it begins on the state that follows the prefix.
|
||||
// cycle_entry_point is that state.
|
||||
const state* cycle_entry_point;
|
||||
state_set::const_iterator ps = ss.find(prefix_start);
|
||||
if (ps != ss.end())
|
||||
{
|
||||
// The initial state is on the cycle.
|
||||
prefix_start->destroy();
|
||||
cycle_entry_point = *ps;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This initial state is outside the cycle. Compute the prefix.
|
||||
cycle_entry_point = shpath.search(prefix_start, run_->prefix);
|
||||
}
|
||||
|
||||
// Locate cycle_entry_point on the cycle.
|
||||
tgba_run::steps::iterator cycle_ep_it;
|
||||
for (cycle_ep_it = run_->cycle.begin();
|
||||
cycle_ep_it != run_->cycle.end()
|
||||
&& cycle_entry_point->compare(cycle_ep_it->s); ++cycle_ep_it)
|
||||
continue;
|
||||
assert(cycle_ep_it != run_->cycle.end());
|
||||
|
||||
// Now shift the cycle so it starts on cycle_entry_point.
|
||||
run_->cycle.splice(run_->cycle.end(), run_->cycle,
|
||||
run_->cycle.begin(), cycle_ep_it);
|
||||
|
||||
return run_;
|
||||
}
|
||||
|
||||
void
|
||||
couvreur99_check_result::accepting_cycle()
|
||||
{
|
||||
acc_cond::mark_t acc_to_traverse =
|
||||
ecs_->aut->acc().accepting_sets(ecs_->root.top().condition);
|
||||
// Compute an accepting cycle using successive BFS that are
|
||||
// restarted from the point reached after we have discovered a
|
||||
// transition with a new acceptance conditions.
|
||||
//
|
||||
// This idea is taken from Product<T>::findWitness in LBTT 1.1.2,
|
||||
// which in turn is probably inspired from
|
||||
// @Article{ latvala.00.fi,
|
||||
// author = {Timo Latvala and Keijo Heljanko},
|
||||
// title = {Coping With Strong Fairness},
|
||||
// journal = {Fundamenta Informaticae},
|
||||
// year = {2000},
|
||||
// volume = {43},
|
||||
// number = {1--4},
|
||||
// pages = {1--19},
|
||||
// publisher = {IOS Press}
|
||||
// }
|
||||
const state* substart = ecs_->cycle_seed;
|
||||
do
|
||||
{
|
||||
struct scc_bfs: bfs_steps
|
||||
{
|
||||
const couvreur99_check_status* ecs;
|
||||
couvreur99_check_result* r;
|
||||
acc_cond::mark_t& acc_to_traverse;
|
||||
int scc_root;
|
||||
|
||||
scc_bfs(const couvreur99_check_status* ecs,
|
||||
couvreur99_check_result* r, acc_cond::mark_t& acc_to_traverse)
|
||||
: bfs_steps(ecs->aut), ecs(ecs), r(r),
|
||||
acc_to_traverse(acc_to_traverse),
|
||||
scc_root(ecs->root.top().index)
|
||||
{
|
||||
}
|
||||
|
||||
virtual const state*
|
||||
filter(const state* s)
|
||||
{
|
||||
auto i = ecs->h.find(s);
|
||||
s->destroy();
|
||||
// Ignore unknown states.
|
||||
if (i == ecs->h.end())
|
||||
return 0;
|
||||
// Stay in the final SCC.
|
||||
if (i->second < scc_root)
|
||||
return 0;
|
||||
r->inc_ars_cycle_states();
|
||||
return i->first;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
match(tgba_run::step& st, const state* s)
|
||||
{
|
||||
acc_cond::mark_t less_acc =
|
||||
acc_to_traverse - st.acc;
|
||||
if (less_acc != acc_to_traverse
|
||||
|| (acc_to_traverse == 0U
|
||||
&& s == ecs->cycle_seed))
|
||||
{
|
||||
acc_to_traverse = less_acc;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} b(ecs_.get(), this, acc_to_traverse);
|
||||
|
||||
substart = b.search(substart, run_->cycle);
|
||||
assert(substart);
|
||||
}
|
||||
while (acc_to_traverse != 0U || substart != ecs_->cycle_seed);
|
||||
}
|
||||
|
||||
void
|
||||
couvreur99_check_result::print_stats(std::ostream& os) const
|
||||
{
|
||||
ecs_->print_stats(os);
|
||||
// FIXME: This is bogusly assuming run_ exists. (Even if we
|
||||
// created it, the user might have deleted it.)
|
||||
os << run_->prefix.size() << " states in run_->prefix" << std::endl;
|
||||
os << run_->cycle.size() << " states in run_->cycle" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue