00001
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
00012 add_state(s);
00013 }
00014
00015 Fsm::~Fsm() {
00016 }
00017
00018 const Fsm::Symbol&
00019 Fsm::epsilon() {
00020
00021
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
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
00063 TRANSITIONS::const_iterator i(transitions_.find(make_pair(q,a)));
00064
00065 if (i == end())
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
00074
00075
00076
00077 const STATES& states(delta(q,a));
00078
00079
00080 if (states.size() != 1) {
00081
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
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 }