OpenASIP 2.2
Loading...
Searching...
No Matches
FiniteStateAutomaton.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file FiniteStateAutomaton.cc
26 *
27 * Definition of FiniteStateAutomaton class.
28 *
29 * @author Pekka Jääskeläinen 2006 (pekka.jaaskelainen-no.spam-tut.fi)
30 * @note rating: red
31 */
32
33#include <sstream>
34#include "Application.hh"
36#include "Conversion.hh"
37#include "boost/format.hpp"
38#include "FunctionUnit.hh"
39
42
45
46
47/**
48 * Constructor.
49 *
50 * @param defaultState The default state for state transitions (either
51 * ILLEGAL_STATE or UNKNOWN_STATE, as no other states are known at this
52 * point).
53 * @param transitionCount The initial count of transitions.
54 */
56 FSAStateTransitionIndex defaultState,
57 int transitionCount) :
58 stateCount_(0),
59 transitionTypeCount_(transitionCount), transitionNames_(transitionCount),
60 defaultState_(defaultState) {
61}
62
63/**
64 * Destructor.
65 */
67#if 0
68 Application::logStream() << stateCount_ << " states" << std::endl;
69#endif
70}
71
72/**
73 * Returns the textual description of the transition at the given index.
74 *
75 * For example, returns the name of the operation in case of an FU FSA.
76 *
77 * @param transition The index of the transition of which name to return.
78 * @return The name of the transition.
79 */
80const std::string&
82 FSAStateTransitionIndex transition) const {
83 return transitionNames_.at(transition);
84}
85
86/**
87 * Sets a name for the given transition.
88 *
89 * @param transition The index of the transition of which name to return.
90 * @param name The name of the transition.
91 */
92void
94 FSAStateTransitionIndex transition, const std::string& name) {
95 transitionNames_.at(transition) = name;
96 transitionIndices_[name] = transition;
97}
98
99/**
100 * Returns the textual description of the state at the given index.
101 *
102 * @param state The index of the state of which name to return.
103 * @return The name of the state.
104 */
105std::string
109
110/**
111 * Returns the index of the transition with given name.
112 *
113 * Returns the transition index for an operation in case of an FU FSA.
114 *
115 * @param transitionName The name of the transition of index to return.
116 * @return The index.
117 * @exception KeyNotFound In case no transition with given is found.
118 */
120FiniteStateAutomaton::transitionIndex(const std::string& transitionName) const {
121 TransitionNameIndex::const_iterator i =
123
124 if (i == transitionIndices_.end())
125 throw KeyNotFound(
126 __FILE__, __LINE__, __func__,
127 (boost::format("No transition '%s'") % transitionName).str());
128
129 return (*i).second;
130}
131
132/**
133 * Returns the index of the state resulting from the given transition from
134 * the given source state.
135 *
136 * This method is called often, thus should be as fast as possible.
137 * Therefore, all range checking etc. is disabled. Method is not const
138 * due to possibility of lazy initialization of states in derived
139 * classes.
140 *
141 * @param source The source state.
142 * @param transition The transition.
143 * @return The index of the destination state.
144 */
147 FSAStateIndex source, FSAStateTransitionIndex transition) {
148 return transitions_[source][transition];
149}
150
151/**
152 * Returns true in case the given transition is legal (accepted by the
153 * state machine) from the given state.
154 *
155 * This method is called often, thus should be as fast as possible.
156 * Therefore, all range checking etc. is disabled. Method is not const
157 * due to possibility of lazy initialization of states in derived
158 * classes.
159 *
160 * @param source The source state.
161 * @param transition The transition.
162 * @return True in case the transition is legal.
163 */
164bool
166 FSAStateIndex source,
167 FSAStateTransitionIndex transition) {
168 return transitions_[source][transition] != ILLEGAL_STATE;
169}
170
171
172/**
173 * Adds a new state to the automaton.
174 *
175 * @return Returns the index of the new state. Indexing starts from 0.
176 */
179 // add transition vector with no transitions for the new state
180 transitions_.push_back(
182 return stateCount_++;
183}
184
185/**
186 * Adds a new transition type to the automaton.
187 *
188 * @param name Name of the transition type. Must be unique within all
189 * transition types.
190 * @return Returns the index of the new transition type. Indexing starts
191 * from 0.
192 */
195
196 transitionNames_.push_back(name.c_str());
197 transitionIndices_.insert(
198 TransitionNameIndex::value_type(name, transitionTypeCount_));
199
200 // increment the size of each state's transition vectors to
201 // match the new count of transition types
202 for (TransitionMap::iterator i = transitions_.begin();
203 i != transitions_.end(); ++i) {
204 TransitionVector& vec = *i;
205 vec.resize(transitionTypeCount_ + 1, defaultState_);
206 }
207
208 return transitionTypeCount_++;
209}
210
211/**
212 * Set a transition between two states.
213 *
214 * @param source The source state.
215 * @param destination The destination state.
216 * @param transition The type of transition.
217 */
218void
220 FSAStateIndex source,
221 FSAStateIndex destination,
222 FSAStateTransitionIndex transition) {
223
224 transitions_.at(source).at(transition) = destination;
225}
226
227/**
228 * Creates a string that represents the FSA as a graph in GraphViz dot format.
229 *
230 * This string can be rendered to a visual graph using the 'dot' tool.
231 *
232 * @return The FSA in dot graph format.
233 */
234std::string
236
237 std::ostringstream s;
238 s << "digraph G {" << std::endl;
239
240 // first print all the states as nodes
241 for (int i = 0; i < stateCount_; ++i) {
242 s << "\tS" << i << " [label=\"S" << i << "\\n" << stateName(i)
243 << "\"]; " << std::endl;
244 }
245
246 // print transitions as edges
247 for (int i = 0; i < stateCount_; ++i) {
248 const TransitionVector& vec = transitions_.at(i);
249 for (int t = 0; t < transitionTypeCount_; ++t) {
250 std::string edgeLabel = transitionName(t);
251 if (edgeLabel == "")
252 edgeLabel = "[NOP]";
253 edgeLabel = edgeLabel + " (" + Conversion::toString(t) + ")";
254 switch (vec.at(t)) {
255 case ILLEGAL_STATE:
256 s << "\t/* No transition " << edgeLabel << " from S" << i
257 << " possible */" << std::endl;
258 break;
259 case UNKNOWN_STATE:
260 s << "\t/* Transition " << edgeLabel << " from S" << i
261 << " not initialized yet */" << std::endl;
262 break;
263 default:
264 s << "\tS" << i << " -> " << "S" << vec.at(t) << "[label=\""
265 << edgeLabel << "\"];" << std::endl;
266 break;
267 }
268 }
269 }
270 s << "}" << std::endl;
271 return s.str();
272}
273
274/**
275 * Returns the starting state of the automaton.
276 *
277 * By default the starting state is assumed to be the state 0.
278 *
279 * @return The starting state.
280 */
283 return 0;
284}
285
#define __func__
static std::ostream & logStream()
static std::string toString(const T &source)
virtual void setTransition(FSAStateIndex source, FSAStateIndex destination, FSAStateTransitionIndex transition)
int transitionTypeCount_
Count of different transition types in the automaton.
virtual FSAStateTransitionIndex transitionIndex(const std::string &transitionName) const
const FSAStateTransitionIndex defaultState_
The default target state for state transitions.
TransitionMap transitions_
The state transitions. In protected to allow fast access from derived classes.
virtual void setTransitionName(FSAStateTransitionIndex transition, const std::string &name)
virtual FSAStateTransitionIndex addTransitionType(const std::string &name)
virtual std::string toDotString() const
virtual const std::string & transitionName(FSAStateTransitionIndex transition) const
virtual FSAStateIndex startState() const
FiniteStateAutomaton(FSAStateTransitionIndex defaultState=ILLEGAL_STATE, int transitionCount=0)
virtual bool isLegalTransition(FSAStateIndex source, FSAStateTransitionIndex transition)
int FSAStateIndex
Type used for indexing the states.
virtual std::string stateName(FSAStateIndex state) const
TransitionNameIndex transitionIndices_
Indices of the state transition types.
static const FSAStateIndex ILLEGAL_STATE
A state id which denotes an illegal state.
static const FSAStateIndex UNKNOWN_STATE
A state id which denotes an unknown (unresolved) state. Used for lazy construction of states.
virtual FSAStateIndex addState()
std::vector< FSAStateIndex > TransitionVector
Vector which stores the target states of for each transition type.
virtual FSAStateIndex destinationState(FSAStateIndex source, FSAStateTransitionIndex transition)
std::vector< std::string > transitionNames_
Names of the state transitions types (indexed from 0).
int stateCount_
Count of states in the automaton.
int FSAStateTransitionIndex
Type used for indexing the transitions.