Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

fsm.C

Go to the documentation of this file.
00001 // $Id: fsm.C,v 1.9 2001/08/20 05:23:40 dvermeir Exp $
00002 
00003 #include "fsm.h"
00004 
00005 ref<Fsm>
00006 Fsm::create(const State& s) {
00007 return ref<Fsm>(new Fsm(s));
00008 }
00009 
00010 Fsm::Fsm(const State& s): initial_state_(s) {
00011 // The initial state is also a state.
00012 add_state(s);
00013 }
00014 
00015 Fsm::~Fsm() {
00016 }
00017 
00018 const Fsm::Symbol&
00019 Fsm::epsilon() {
00020 // Return symbol used to represent empty string (for epsilon
00021 // transitions).
00022 static const string EPSILON("-");
00023 return EPSILON;
00024 }
00025 
00026 Fsm&
00027 Fsm::add_state(const State& s) {
00028 states_.insert(s);
00029 return *this;
00030 }
00031 
00032 Fsm&
00033 Fsm::add_final_state(const State& s) {
00034 final_states_.insert(s);
00035 // A final state is also a state.
00036 return add_state(s);
00037 }
00038 
00039 bool
00040 Fsm::is_final(const State& q) const {
00041 return final_states().count(q) > 0;
00042 }
00043 
00044 Fsm&
00045 Fsm::add_symbol(const Symbol& a) {
00046 alphabet_.insert(a);
00047 return *this;
00048 }
00049 
00050 Fsm&
00051 Fsm::add_transition(const State& q1,const Symbol& a, const State& q2) {
00052 add_state(q1);
00053 add_state(q2);
00054 transitions_[make_pair(q1,a)].insert(q2);
00055 return add_symbol(a);
00056 }
00057 
00058 const Fsm::STATES&          
00059 Fsm::delta(const State& q, const Symbol& a) const {
00060 static const STATES EMPTY_SET;
00061 
00062 // Try to find a transition for (q,a).
00063 TRANSITIONS::const_iterator     i(transitions_.find(make_pair(q,a)));
00064 
00065 if (i == end()) // no transition, return empty set
00066   return EMPTY_SET;
00067 else
00068   return (*i).second;
00069 }
00070 
00071 const Fsm::State&           
00072 Fsm::ddelta(const State& q, const Symbol& a) const throw(runtime_error) {
00073 // Deterministic version of delta(q,a). Works only for deterministic
00074 // automata.
00075 
00076 // First get the delta(q,a) set.
00077 const STATES& states(delta(q,a));
00078 
00079 // It must be a singleton.
00080 if (states.size() != 1) {
00081   // 2 things can go wrong: not a dfa or a not in alphabet.
00082   const string error_msg(string("Fsm::ddelta(") + q + ", " + a + ")");
00083 
00084   if (alphabet_.count(a) == 0) 
00085     throw runtime_error(error_msg + ": unknown symbol");
00086   else
00087     throw runtime_error(error_msg + ": not a dfa");
00088   }
00089 
00090 // Now, we are sure that there is a single elementg in states.
00091 return *(states.begin());
00092 }
00093 
00094 bool
00095 Fsm::is_deterministic() const {
00096 for (Fsm::STATES::const_iterator i = sbegin(); i != send(); ++i) 
00097   for (Fsm::SYMBOLS::const_iterator a = abegin(); a!= aend(); ++a) 
00098     if (delta(*i,*a).size() != 1)
00099       return false;
00100 return true;
00101 }
00102 
00103 ostream&
00104 operator<<(ostream& os, const Fsm& fsm) {
00105 os << fsm.initial_state() << "\n";
00106 
00107 os << fsm.final_states() << "\n";
00108 
00109 for (Fsm::TRANSITIONS::const_iterator i=fsm.begin(); i!=fsm.end(); ++i) 
00110   os << (*i).first.first << " " 
00111      << (*i).first.second << " " 
00112      << (*i).second
00113      << "\n";
00114 return os;
00115 }
00116 
00117 ostream&
00118 operator<<(ostream& os, const Fsm::STATES& Q) {
00119 os << "{ ";
00120 for (Fsm::STATES::const_iterator q = Q.begin(); q != Q.end(); ++q)
00121   os << (*q)<< " "; 
00122 os << "}";
00123 return os;
00124 }

FSM [ August, 2001]