fsm_dump.hxx

00001 // fsm_dump.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2004, 2005 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_TOOLS_FSM_DUMP_HXX
00018 # define VCSN_TOOLS_FSM_DUMP_HXX
00019 
00020 # include <vaucanson/tools/fsm_dump.hh>
00021 # include <map>
00022 # include <set>
00023 # include <vaucanson/automata/concept/handlers.hh>
00024 # include <vaucanson/misc/usual_macros.hh>
00025 # include <vaucanson/automata/concept/automata_base.hh>
00026 
00027 namespace vcsn {
00028 
00029   namespace tools {
00030 
00031     /*---------.
00032     | fsm_dump |
00033     `---------*/
00034     // Description :
00035     //   - Basic and non configurable pretty-printer in the 'fsm' format
00036     //
00037     // Constraints :
00038     //   - Every elements (series, state_content ...) must be printable
00039     //
00040     template <typename St, typename auto_t>
00041     void fsm_dump(St& out, const auto_t& a)
00042     {
00043       AUTOMATON_TYPES(auto_t);
00044       if (a.initial().size() > 1)
00045       {
00046         auto_t b(a);
00047         hstate_t i = b.add_state();
00048         for_all_initial_states(j, b)
00049           b.add_spontaneous(i, *j);
00050         b.clear_initial();
00051         b.set_initial(i);
00052         fsm_dump(out, b);
00053         return ;
00054       }
00055       if (a.states().size() == 0)
00056         return;
00057 
00058       typename auto_t::initial_iterator initial = a.initial().begin();
00059       std::set<htransition_t> succ;
00060 
00061       a.deltac(succ, *initial, delta_kind::transitions());
00062       for_all_const_(std::set<htransition_t>, e, succ)
00063         out << *initial << "\t" << a.dst_of(*e) << "\t"
00064             << a.series_of(*e) << "\t 0"
00065             << std::endl;
00066       for_all_states(s, a)
00067         if (!a.is_initial(*s))
00068         {
00069           succ.clear();
00070           a.deltac(succ, *s, delta_kind::transitions());
00071           for_all_const_(std::set<htransition_t>, e, succ)
00072             out << *s << "\t" << a.dst_of(*e) << "\t"
00073                 << a.series_of(*e) << "\t 0"
00074                 << std::endl;
00075         }
00076       for_all_final_states(f, a)
00077         out << *f << "\t 0" << std::endl;
00078     }
00079 
00080     /*---------.
00081     | fsm_load |
00082     `---------*/
00083     enum data_e
00084     {
00085       final,
00086       transition
00087     };
00088 
00089     struct line_data
00090     {
00091         data_e       type;
00092         unsigned int from;
00093         unsigned int to;
00094         char         letter;
00095         float        weight;
00096     };
00097 
00098     std::pair<std::string, std::string>
00099     next_token(std::string line)
00100     {
00101       std::string token;
00102       std::string::iterator i = line.begin();
00103       while ((i != line.end()) && ((*i == '\t')
00104                                    || (*i == ' ') || (*i == '\0')))
00105         ++i;
00106       for (;i != line.end();++i)
00107       {
00108         if ((*i == '\t') || (*i == ' ')
00109             || (*i == '\n') || (*i == '\0'))
00110           break;
00111         else
00112           token.push_back(*i);
00113       }
00114       if (i != line.end())
00115       {
00116         ++i;
00117         return std::make_pair(token,
00118                               std::string(line,
00119                                           (unsigned)(i - line.begin()),
00120                                           (unsigned)(line.end() - i + 1)));
00121       }
00122       else
00123         return std::make_pair(token, std::string());
00124     }
00125 
00126     template <typename St, typename AutoType_>
00127     void fsm_load(St& in, AutoType_& a)
00128     {
00129       AUTOMATON_TYPES(AutoType_);
00130       AUTOMATON_FREEMONOID_TYPES(AutoType_);
00131       // read everything and build the alphabet.
00132       alphabet_t                alpha;
00133       unsigned                  nb = 0;
00134       std::vector<line_data>    stock;
00135       std::string               line;
00136       std::pair<std::string,    std::string> tmp;
00137       std::vector<std::string>  tokens;
00138 
00139       while (!in.eof())
00140       {
00141         tokens.clear();
00142         ++nb;
00143         stock.resize(nb);
00144         getline(in, line);
00145         while (true)
00146         {
00147           tmp = next_token(line);
00148           line = tmp.second;
00149           if (tmp.first.length() != 0)
00150             tokens.push_back(tmp.first);
00151           if (line.length() == 0)
00152             break;
00153         }
00154         if (tokens.size() == 0)
00155         {
00156           nb--;
00157           stock.resize(nb);
00158           break;
00159         }
00160         if (tokens.size() == 1)
00161         {
00162           stock[nb-1].type = final;
00163           stock[nb-1].from = atoi(tokens[0].c_str());
00164           stock[nb-1].weight = 0.;
00165         }
00166         else if (tokens.size() == 2)
00167         {
00168           stock[nb-1].type = final;
00169           stock[nb-1].from = atoi(tokens[0].c_str());
00170           stock[nb-1].weight = atof(tokens[1].c_str());
00171         }
00172         else if (tokens.size() == 4)
00173         {
00174           stock[nb-1].type   = transition;
00175           stock[nb-1].from   = atoi(tokens[0].c_str());
00176           stock[nb-1].to     = atoi(tokens[1].c_str());
00177           stock[nb-1].letter = tokens[2][0];
00178           stock[nb-1].weight = atof(tokens[3].c_str());
00179           alpha.insert(stock[nb-1].letter);
00180         }
00181       }
00182       // construct the automaton.
00183       monoid_t    monoid(alpha);
00184       semiring_t   semiring;
00185       series_set_t        series(semiring, monoid);
00186       automata_set_t aset(series);
00187       automaton_t automaton(aset);
00188       std::map<int, hstate_t> to_h;
00189 
00190       for_all_const_(std::vector<line_data>, i, stock)
00191       {
00192         if (i->type == transition)
00193         {
00194           if (to_h.find(i->from) == to_h.end())
00195             to_h[i->from] = automaton.add_state();
00196           if (to_h.find(i->to) == to_h.end())
00197             to_h[i->to] = automaton.add_state();
00198           if (i == stock.begin())
00199             automaton.set_initial(to_h[i->from]);
00200           // FIXME: please be generic w.r.t spontaneous transition.
00201           if (i->letter == '1')
00202             automaton.add_spontaneous(to_h[i->from],
00203                                       to_h[i->to]);
00204           else
00205             automaton.add_letter_transition(to_h[i->from],
00206                                             to_h[i->to],
00207                                             letter_t(i->letter));
00208         }
00209         else if (i->type == final)
00210         {
00211           if (to_h.find(i->from) == to_h.end())
00212             to_h[i->from] = automaton.add_state();
00213           automaton.set_final(to_h[i->from]);
00214         }
00215       }
00216       a = automaton;
00217     }
00218 
00219   } // tools
00220 
00221 } // vcsn
00222 
00223 #endif // ! VCSN_TOOLS_FSM_DUMP_HXX

Generated on Sat Jul 29 17:12:59 2006 for Vaucanson by  doxygen 1.4.6