You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
319 lines
8.6 KiB
319 lines
8.6 KiB
/*
|
|
* This file is part of the program ltl2dstar (http://www.ltl2dstar.de/).
|
|
* Copyright (C) 2005-2007 Joachim Klein <j.klein@ltl2dstar.de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program 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, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
|
|
#ifndef NBA_STATE_H
|
|
#define NBA_STATE_H
|
|
|
|
/** @file
|
|
* Provides class NBA_State for storing a state of a nondeterministic Büchi automaton.
|
|
*/
|
|
|
|
|
|
#include "common/Exceptions.hpp"
|
|
#include "common/Indexable.hpp"
|
|
#include "common/BitSet.hpp"
|
|
#include "common/BitSetIterator.hpp"
|
|
#include "common/nested_iterator.hpp"
|
|
#include "APSet.hpp"
|
|
#include "APElement.hpp"
|
|
#include "APMonom2APElements.hpp"
|
|
|
|
#include <iostream>
|
|
|
|
// forward declaration
|
|
template <typename Label,
|
|
template <typename State> class EdgeContainer> class NBA;
|
|
|
|
|
|
|
|
// forward declaration
|
|
template <typename State,
|
|
typename Label,
|
|
typename EdgeContainer >
|
|
struct NBA_State_EdgeManager;
|
|
|
|
/**
|
|
* A state of a deterministic omega-automaton.
|
|
* For a description of the template parameters, see class NBA.
|
|
*/
|
|
template <typename Label, template <typename N> class EdgeContainer >
|
|
class NBA_State : public Indexable<NBA_State<Label,EdgeContainer> > {
|
|
public:
|
|
/** The type of the automaton containing this state */
|
|
typedef NBA<Label, EdgeContainer> graph_type;
|
|
|
|
/** The type of the edges in the NBA. */
|
|
typedef typename graph_type::edge_type edge_type;
|
|
|
|
/** The type of the states in the NBA (ie this NBA_State class). */
|
|
typedef typename graph_type::state_type state_type;
|
|
|
|
/** The type of the EdgeContainer for the DA_State. */
|
|
typedef EdgeContainer<BitSet> edge_container_type;
|
|
|
|
/**
|
|
* Constructor.
|
|
* @param graph The automaton (NBA) that contains this state.
|
|
*/
|
|
NBA_State(graph_type& graph)
|
|
: _graph(graph),
|
|
_isFinal(false),
|
|
_edge_manager(*this, graph.getAPSet()) {
|
|
}
|
|
|
|
/** Destructor */
|
|
~NBA_State() {
|
|
}
|
|
|
|
/**
|
|
* Add an edge from this state to the other state
|
|
* @param label the label for the edge
|
|
* @param state the target state
|
|
*/
|
|
void addEdge(APElement label, state_type& state) {
|
|
_edge_manager.addEdge(label, state);
|
|
}
|
|
|
|
|
|
/**
|
|
* Add edge(s) from this state to the other state
|
|
* @param monom an APMonom for the label(s)
|
|
* @param to_state the target state
|
|
*/
|
|
void addEdge(APMonom monom, state_type& to_state) {
|
|
_edge_manager.addEdge(monom, to_state);
|
|
}
|
|
|
|
/*
|
|
edge_container_type& edges() {return _edges;}
|
|
const edge_container_type& edges() const {return _edges;}
|
|
*/
|
|
|
|
/**
|
|
* Get the target states of the labeled edge.
|
|
* @return a pointer to a BitSet with the indizes of the target states.
|
|
*/
|
|
BitSet* getEdge(APElement label) {
|
|
return _edge_manager.getEdge(label);
|
|
};
|
|
|
|
/**
|
|
* Get the target states of the labeled edge.
|
|
* @return a pointer to a BitSet with the indizes of the target states.
|
|
*/
|
|
BitSet* getEdge(APMonom monom) {
|
|
return _edge_manager.getEdge(monom);
|
|
};
|
|
|
|
/** Get the name (index) of this state. */
|
|
unsigned int getName() const {
|
|
return _graph.getIndexForState(this);
|
|
};
|
|
|
|
/** Print the name of this state on the output stream. */
|
|
friend std::ostream& operator<<(std::ostream& out, NBA_State& state) {
|
|
out << state.getName();
|
|
return out;
|
|
}
|
|
|
|
/** Is this state accepting (final)? */
|
|
bool isFinal() {return _isFinal;}
|
|
|
|
/** Set the value of the final flag for this state */
|
|
void setFinal(bool final) {
|
|
_isFinal=final;
|
|
_graph.getFinalStates().set(_graph.getIndexForState(this), final);
|
|
}
|
|
|
|
/** Returns an iterator over the edges pointing to the first edge. */
|
|
typename edge_container_type::EdgeIterator
|
|
edges_begin() {
|
|
return _edge_manager.getEdgeContainer().begin();
|
|
}
|
|
|
|
/** Returns an iterator over the edges pointing after the last edge. */
|
|
typename edge_container_type::EdgeIterator
|
|
edges_end() {
|
|
return _edge_manager.getEdgeContainer().end();
|
|
}
|
|
|
|
/**
|
|
* Calls operator(state_type*) on the functor UnaryFunction
|
|
* for all states that are reachable in one step from this
|
|
* state.
|
|
*/
|
|
template <class UnaryFunction>
|
|
void forEachSuccessor(UnaryFunction& unary_function) {
|
|
for (typename edge_container_type::EdgeIterator edge_it=edges_begin();
|
|
edge_it!=edges_end();
|
|
++edge_it) {
|
|
BitSet *bs=*edge_it;
|
|
for (BitSetIterator bs_it(*bs);
|
|
bs_it!=BitSetIterator::end(*bs);
|
|
++bs_it) {
|
|
unary_function(_graph[*bs_it]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** A helper that provides iterators over the set bits for an edge */
|
|
struct edge_to_bitset_iterator {
|
|
BitSetIterator begin(edge_type const& edge) {
|
|
return BitSetIterator(*edge.second);
|
|
}
|
|
|
|
BitSetIterator end(edge_type const& edge) {
|
|
return BitSetIterator::end(*edge.second);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* The type of an iterator over the names (indizes) of the
|
|
* states that are reachable in one step from this state.
|
|
* Note: A state can occur multiple times!
|
|
*/
|
|
typedef nested_iterator<typename edge_container_type::EdgeIterator,
|
|
BitSetIterator,
|
|
edge_to_bitset_iterator> successor_iterator;
|
|
|
|
/**
|
|
* Returns an iterator over the names of the successors, pointing to the first.
|
|
* Note: A state can occur multiple times!
|
|
*/
|
|
successor_iterator successors_begin() {
|
|
// typename edge_container_type::EdgeIterator b=edges.begin(),
|
|
//e=edges().end();
|
|
return successor_iterator(edges_begin(), edges_end());
|
|
}
|
|
|
|
/**
|
|
* Returns an iterator over the names of the successors, pointing after the last.
|
|
* Note: A state can occur multiple times!
|
|
*/
|
|
successor_iterator successors_end() {
|
|
return successor_iterator(edges_end(), edges_end());
|
|
}
|
|
|
|
/** Set the description for this state. */
|
|
void setDescription(const std::string& s) {_description=s;}
|
|
/** Get the description for this state. */
|
|
const std::string& getDescription() {return _description;}
|
|
|
|
/** Check if this state has a description. */
|
|
bool hasDescription() {return _description.length()!=0;}
|
|
|
|
/** Get the automaton owning this state. */
|
|
graph_type& getGraph() {return _graph;}
|
|
|
|
private:
|
|
/** The automaton */
|
|
graph_type& _graph;
|
|
|
|
/** Is this state accepting */
|
|
bool _isFinal;
|
|
|
|
/** A description. */
|
|
std::string _description;
|
|
|
|
/** The EdgeManager*/
|
|
NBA_State_EdgeManager<NBA_State, Label, edge_container_type> _edge_manager;
|
|
};
|
|
|
|
|
|
|
|
#include "EdgeContainerExplicit_APElement.hpp"
|
|
|
|
/** The EdgeManager for the NBA_State */
|
|
template <typename State>
|
|
struct NBA_State_EdgeManager<State,
|
|
APElement,
|
|
EdgeContainerExplicit_APElement<BitSet> > {
|
|
public:
|
|
/** The type of the EdgeContainer*/
|
|
typedef EdgeContainerExplicit_APElement<BitSet> edge_container_type;
|
|
|
|
private:
|
|
/** The state owning this EdgeManager */
|
|
State& _state;
|
|
/** The EdgeContainer */
|
|
edge_container_type _container;
|
|
|
|
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
* @param state the NBA_State owning this EdgeManager
|
|
* @param apset the underlying APSet
|
|
*/
|
|
NBA_State_EdgeManager(State& state, const APSet& apset)
|
|
: _state(state),
|
|
_container(apset.size()) {
|
|
|
|
for (APSet::element_iterator eit=apset.all_elements_begin();
|
|
eit!=apset.all_elements_end();
|
|
++eit) {
|
|
_container.addEdge(*eit, new BitSet());
|
|
}
|
|
}
|
|
|
|
/** Destructor */
|
|
~NBA_State_EdgeManager() {
|
|
const APSet& ap_set=_state.getGraph().getAPSet();
|
|
for (APSet::element_iterator eit=ap_set.all_elements_begin();
|
|
eit!=ap_set.all_elements_end();
|
|
++eit) {
|
|
delete _container.get(*eit);
|
|
}
|
|
}
|
|
|
|
/** Get the target states */
|
|
BitSet* getEdge(APElement label) {
|
|
return _container.get(label);
|
|
}
|
|
|
|
/** Get the target states */
|
|
BitSet* getEdge(APMonom monom) {
|
|
THROW_EXCEPTION(Exception, "Not implemented!");
|
|
}
|
|
|
|
/** Add an edge. */
|
|
void addEdge(APElement label, State& state) {
|
|
_container.get(label)->set(state.getName());
|
|
}
|
|
|
|
/** Add an edge. */
|
|
void addEdge(APMonom label, State& state) {
|
|
const APSet& ap_set=_state.getGraph().getAPSet();
|
|
|
|
for (APMonom2APElements it=APMonom2APElements::begin(ap_set, label);
|
|
it!=APMonom2APElements::end(ap_set, label);
|
|
++it) {
|
|
addEdge(*it, state);
|
|
}
|
|
}
|
|
|
|
/** Get the EdgeContainer. */
|
|
edge_container_type& getEdgeContainer() {
|
|
return _container;
|
|
}
|
|
};
|
|
|
|
#endif
|
|
|
|
|