Preliminary implementation of Testing Automata.

* configure.ac: Generate src/ta/Makefile and src/taalgos/Makefile.
* src/Makefile.am (SUBDIRS): Add them.
* src/tgbatest/ltl2tgba.cc (main): Add option -TA.
* src/ta/Makefile.am, src/ta/ta.hh, src/ta/taexplicit.cc,
src/ta/taexplicit.hh, src/taalgos/Makefile.am,
src/taalgos/dotty.cc, src/taalgos/dotty.hh,
src/taalgos/reachiter.cc, src/taalgos/reachiter.hh,
src/taalgos/sba2ta.cc, src/taalgos/sba2ta.hh: New files.
This commit is contained in:
Ala Eddine 2010-12-02 12:04:29 +01:00 committed by Alexandre Duret-Lutz
parent c373a2f35e
commit ba47b821c6
14 changed files with 1738 additions and 8 deletions

379
src/ta/taexplicit.cc Normal file
View file

@ -0,0 +1,379 @@
// Copyright (C) 2010 Laboratoire de Recherche et Developpement
// de l Epita (LRDE).
//
// 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.
#include "ltlast/atomic_prop.hh"
#include "ltlast/constant.hh"
#include "taexplicit.hh"
#include "tgba/formula2bdd.hh"
#include "misc/bddop.hh"
#include <cassert>
#include "ltlvisit/tostring.hh"
#include "tgba/bddprint.hh"
namespace spot
{
////////////////////////////////////////
// ta_explicit_succ_iterator
ta_explicit_succ_iterator::ta_explicit_succ_iterator(const state_ta_explicit* s)
{
transitions_ = s->get_transitions();
}
void
ta_explicit_succ_iterator::first()
{
i_ = transitions_->begin();
}
void
ta_explicit_succ_iterator::next()
{
++i_;
}
bool
ta_explicit_succ_iterator::done() const
{
return i_ == transitions_->end();
}
state*
ta_explicit_succ_iterator::current_state() const
{
assert(!done());
state_ta_explicit* s = (*i_)->dest;
return s;
}
bdd
ta_explicit_succ_iterator::current_condition() const
{
assert(!done());
return (*i_)->condition;
}
////////////////////////////////////////
// state_ta_explicit
state_ta_explicit::transitions*
state_ta_explicit::get_transitions() const
{
return transitions_;
}
void
state_ta_explicit::add_transition(state_ta_explicit::transition* t){
if(transitions_ == 0)
transitions_= new transitions;
transitions_->push_back(t);
}
const state*
state_ta_explicit::get_tgba_state() const
{
return tgba_state_;
}
const bdd
state_ta_explicit::get_tgba_condition() const
{
return tgba_condition_;
}
bool
state_ta_explicit::is_accepting_state() const
{
return is_accepting_state_;
}
bool
state_ta_explicit::is_initial_state() const
{
return is_initial_state_;
}
void
state_ta_explicit::set_accepting_state(bool is_accepting_state)
{
is_accepting_state_ = is_accepting_state;
}
bool
state_ta_explicit::is_livelock_accepting_state() const
{
return is_livelock_accepting_state_;
}
void
state_ta_explicit::set_livelock_accepting_state(bool is_livelock_accepting_state)
{
is_livelock_accepting_state_ = is_livelock_accepting_state;
}
void
state_ta_explicit::set_initial_state(bool is_initial_state)
{
is_initial_state_ = is_initial_state;
}
int
state_ta_explicit::compare(const spot::state* other) const
{
const state_ta_explicit* o = dynamic_cast<const state_ta_explicit*> (other);
assert(o);
int compare_value = tgba_state_->compare(o->tgba_state_);
if (compare_value != 0)
return compare_value;
return tgba_condition_.id() - o->tgba_condition_.id();
}
size_t
state_ta_explicit::hash() const
{
return wang32_hash(tgba_state_->hash()) ^ wang32_hash(tgba_condition_.id());
}
state_ta_explicit*
state_ta_explicit::clone() const
{
return new state_ta_explicit(*this);
}
sscc_stack::connected_component::connected_component(int i)
{
index = i;
is_accepting = false;
is_initial = false;
}
sscc_stack::connected_component&
sscc_stack::top()
{
return s.front();
}
const sscc_stack::connected_component&
sscc_stack::top() const
{
return s.front();
}
void
sscc_stack::pop()
{
// assert(rem().empty());
s.pop_front();
}
void
sscc_stack::push(int index)
{
s.push_front(connected_component(index));
}
std::list<state*>&
sscc_stack::rem()
{
return top().rem;
}
size_t
sscc_stack::size() const
{
return s.size();
}
bool
sscc_stack::empty() const
{
return s.empty();
}
////////////////////////////////////////
// ta_explicit
ta_explicit::ta_explicit(const tgba* tgba_) :
tgba_(tgba_)
{
}
ta_explicit::~ta_explicit()
{
ta::states_set_t::iterator it;
for (it = states_set_.begin(); it != states_set_.end(); it++)
{
const state_ta_explicit* s = dynamic_cast<const state_ta_explicit*> (*it);
state_ta_explicit::transitions* trans = s->get_transitions();
state_ta_explicit::transitions::iterator it_trans;
// We don't destroy the transitions in the state's destructor because
// they are not cloned.
for (it_trans = trans->begin(); it_trans != trans->end(); it_trans++)
{
delete *it_trans;
}
delete trans;
delete s->get_tgba_state();
delete s;
}
}
state_ta_explicit*
ta_explicit::add_state(state_ta_explicit* s)
{
std::pair<ta::states_set_t::iterator, bool> add_state_to_ta =
states_set_.insert(s);
if (is_initial_state(*add_state_to_ta.first))
initial_states_set_.insert(*add_state_to_ta.first);
return dynamic_cast<state_ta_explicit*> (*add_state_to_ta.first);
}
state_ta_explicit*
ta_explicit::add_initial_state(state_ta_explicit* s)
{
s->set_initial_state(true);
return add_state(s);
}
void
ta_explicit::create_transition(state_ta_explicit* source, bdd condition, state_ta_explicit* dest)
{
state_ta_explicit::transition* t = new state_ta_explicit::transition;
t->dest = dest;
t->condition = condition;
source->add_transition(t);
}
const ta::states_set_t*
ta_explicit::get_initial_states_set() const
{
return &initial_states_set_;
}
bdd
ta_explicit::get_state_condition(const spot::state* initial_state) const
{
const state_ta_explicit* sta = dynamic_cast<const state_ta_explicit*> (initial_state);
return sta->get_tgba_condition();
}
bool
ta_explicit::is_accepting_state(const spot::state* s) const
{
const state_ta_explicit* sta = dynamic_cast<const state_ta_explicit*> (s);
return sta->is_accepting_state();
}
bool
ta_explicit::is_initial_state(const spot::state* s) const
{
const state_ta_explicit* sta = dynamic_cast<const state_ta_explicit*> (s);
return sta->is_initial_state();
}
bool
ta_explicit::is_livelock_accepting_state(const spot::state* s) const
{
const state_ta_explicit* sta = dynamic_cast<const state_ta_explicit*> (s);
return sta->is_livelock_accepting_state();
}
ta_succ_iterator*
ta_explicit::succ_iter(const spot::state* state) const
{
const state_ta_explicit* s = dynamic_cast<const state_ta_explicit*> (state);
assert(s);
return new ta_explicit_succ_iterator(s);
}
bdd_dict*
ta_explicit::get_dict() const
{
return tgba_->get_dict();
}
const tgba*
ta_explicit::get_tgba() const
{
return tgba_;
}
std::string
ta_explicit::format_state(const spot::state* s) const
{
const state_ta_explicit* sta = dynamic_cast<const state_ta_explicit*> (s);
assert(sta);
return tgba_->format_state(sta->get_tgba_state()) + "\n"
+ bdd_format_formula(get_dict(), sta->get_tgba_condition());
}
void
ta_explicit::delete_stuttering_transitions()
{
ta::states_set_t::iterator it;
for (it = states_set_.begin(); it != states_set_.end(); it++)
{
const state_ta_explicit* source = dynamic_cast<const state_ta_explicit*> (*it);
state_ta_explicit::transitions* trans = source->get_transitions();
state_ta_explicit::transitions::iterator it_trans;
for (it_trans = trans->begin(); it_trans != trans->end();)
{
if (source->get_tgba_condition()
== ((*it_trans)->dest)->get_tgba_condition())
{
delete *it_trans;
it_trans = trans->erase(it_trans);
}
else
{
it_trans++;
}
}
}
}
}