tools.hxx

00001 // tools.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2005, 2006 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 
00018 #ifndef VCSN_XML_TOOLS_HXX
00019 # define VCSN_XML_TOOLS_HXX
00020 
00032 namespace vcsn
00033 {
00034   namespace xml
00035   {
00036 
00037     namespace tools
00038     {
00039 
00040     /*--------------------------------------.
00041     | Extract information about the types.  |
00042     `--------------------------------------*/
00043 
00049       // Default.
00050       template <class S, class T>
00051       const char* get_semiring_set(const S&, const T&)
00052       { return "undefined"; }
00053 
00054 # define GET_SEMIRING_SET(T, Value)                     \
00055       template <class S>                                \
00056       const char* get_semiring_set(const S&, const T&)  \
00057       { return Value; }
00058 
00059       GET_SEMIRING_SET(bool, "B")
00060       GET_SEMIRING_SET(double, "R")
00061       GET_SEMIRING_SET(float, "R")
00062       GET_SEMIRING_SET(int, "Z")
00063 # undef GET_SEMIRING_SET
00064 
00065       // Transducer on P(B*).
00066       template <class S, class U, class V>
00067       const char* get_semiring_set(const S&,
00068                                    const vcsn::rat::exp<U, V>&)
00069       { return "ratSeries"; }
00070 
00071 
00072 
00073       // Deals with the "operation" attribute of <semiring> tag.
00074       // Default.
00075       template <class S>
00076       const char* get_semiring_operations(const S&)
00077       { return "undefined"; }
00078 
00079 # define GET_SEMIRING_OPERATIONS(S, Value)                      \
00080       template <>                                               \
00081       inline const char* get_semiring_operations<S>(const S&)   \
00082       { return Value; }
00083 
00084       GET_SEMIRING_OPERATIONS(vcsn::algebra::NumericalSemiring,
00085                               "numerical")
00086       GET_SEMIRING_OPERATIONS(vcsn::z_max_plus_automaton::semiring_t,
00087                               "tropicalMax")
00088       GET_SEMIRING_OPERATIONS(vcsn::z_min_plus_automaton::semiring_t,
00089                               "tropicalMin")
00090 # undef GET_SEMIRING_OPERATIONS
00091 
00092 
00093 
00094       // Deal with the "type" attribute of <monoid> tag.
00095       // Default.
00096       template <class S>
00097       const char* get_monoid_type(const S&)
00098       { return "undefined"; }
00099 
00100       template <class S>
00101       const char* get_monoid_type(const vcsn::algebra::FreeMonoid<S>&)
00102       { return "free"; }
00103 
00104       template <class S1, class S2>
00105       const char*
00106       get_monoid_type(const vcsn::algebra::FreeMonoidProduct<S1, S2>&)
00107       { return "product"; }
00108 
00109 
00110     /*---------.
00111     | Automata |
00112     `---------*/
00113 
00114       inline
00115       void
00116       set_attribute (xercesc::DOMElement* e, std::string k, std::string v)
00117       {
00118         e->setAttribute (transcode(k), transcode(v));
00119       }
00120 
00121       inline
00122       void
00123       xset_attribute (xercesc::DOMElement* e, std::string k, std::string v)
00124       {
00125         if (v != "")
00126           set_attribute (e, k, v);
00127       }
00128 
00129 
00130       // Add the label as a string attribute.
00131       template <class S, class T, class U>
00132       void add_label(xercesc::DOMElement* elt,
00133                      const Element<S, T>&,
00134                      const U& series)
00135       {
00136         xset_attribute(elt, "label", get_label(series));
00137       }
00138 
00139       // Add the label as an xml node
00140       template <class S, class T, class U>
00141       void add_xml_label(xercesc::DOMDocument* doc,
00142                          xercesc::DOMElement* elt,
00143                          const Element<S, T>& a,
00144                          const U& series)
00145       {
00146         typedef Element<S,T> automaton_t;
00147         typedef typename
00148           rat::exp<typename automaton_t::monoid_elt_value_t,
00149           typename automaton_t::semiring_elt_value_t> krat_exp_impl_t;
00150         typedef Element<typename automaton_t::series_set_t, krat_exp_impl_t> krat_exp_t;
00151 
00152 
00153         std::string label = get_label(series);
00154         if (label.size())
00155         {
00156           krat_exp_t res (a.structure().series());
00157           parse(label, res);
00158           elt->appendChild(res.value().xml_tree(doc, "label"));
00159         }
00160       }
00161 
00162 
00163       /*----------------.
00164       | FMP Transducers |
00165       `----------------*/
00166 
00167 # define FMPtype                                                          \
00168     Element<                                                              \
00169       Automata<                                                           \
00170       vcsn::algebra::Series<S, vcsn::algebra::FreeMonoidProduct<M1, M2> > \
00171       >, T                                                                \
00172     >
00173       // Add the label as a string attribute
00174       template <class S, class T, class U, class M1, class M2>
00175       void add_label(xercesc::DOMElement* elt,
00176                      const FMPtype&,
00177                      const U& series)
00178       {
00179         if (series.supp().size() > 1)
00180         {
00181           xset_attribute(elt, "label", get_label(series));
00182         }
00183         else
00184         {
00185           std::string in_word = get_label((*(series.supp().begin())).first);
00186           std::string out_word = get_label((*(series.supp().begin())).second);
00187           std::string mult = get_label(series.get(*(series.supp().begin())));
00188           std::string out;
00189           if (mult.size())
00190             out = mult;
00191           if (out != "" && out_word.size())
00192             out += " ";
00193           if (out_word.size())
00194             out += out_word;
00195 
00196           xset_attribute(elt, "in", in_word);
00197           xset_attribute(elt, "out", out);
00198         }
00199       }
00200 
00201       // Add the label as an xml node
00202       template <class S, class T, class U, class M1, class M2>
00203       void add_xml_label(xercesc::DOMDocument* doc,
00204                          xercesc::DOMElement* elt,
00205                          const FMPtype& a,
00206                          const U& series)
00207       {
00208         std::string out;
00209         if (series.supp().size() > 1)
00210         {
00211           xset_attribute(elt, "label", get_label(series));
00212         }
00213         else
00214         {
00215           std::string in_word = get_label((*(series.supp())).first);
00216           std::string out_word = get_label((*(series.supp())).second);
00217           std::string mult = get_label(series.get(*(series.supp().begin())));
00218 
00219           if (in_word.size() && in_word != "1")
00220           {
00221             using namespace vcsn::r_automaton;
00222             automaton_t bin = make_automaton(
00223               a.structure().series().monoid().first_monoid().alphabet());
00224             rat_exp_t res_in(bin.structure().series());
00225             parse(in_word, res_in);
00226             elt->appendChild(res_in.value().xml_tree(doc, "in"));
00227           }
00228           if (out_word.size() && out_word != "1")
00229           {
00230             using namespace vcsn::r_automaton;
00231             automaton_t bout = make_automaton(
00232               a.structure().series().monoid().second_monoid().alphabet());
00233             rat_exp_t res_out(bout.structure().series());
00234             parse(out_word, res_out);
00235             xercesc::DOMElement* out_node =
00236               res_out.value().xml_tree(doc, "out");
00237             xset_attribute(out_node, "weight", mult);
00238             elt->appendChild(out_node);
00239           }
00240         }
00241       }
00242 
00243 
00244       /*---------------------.
00245       | Transducers on P(B*) |
00246       `---------------------*/
00247 
00248       // Add the label as a string attribute
00249       template <class S, class T, class U>
00250       void add_label(xercesc::DOMElement* elt,
00251                      const Element<Transducer<S>, T>&,
00252                      const U& series)
00253       {
00254         std::string in = get_label(*(series.supp().begin()));
00255         std::string out = get_label(series.get(*(series.supp().begin())));
00256 
00257         if (in.size() && in != "1")
00258           set_attribute(elt, "in", in);
00259         if (out.size() && out != "1")
00260           set_attribute(elt, "out", out);
00261       }
00262 
00263       // Add the label as an xml node
00264       template <class S, class T, class U>
00265       void add_xml_label(xercesc::DOMDocument* doc,
00266                          xercesc::DOMElement* elt,
00267                          const Element<Transducer<S>, T>& a,
00268                          const U& series)
00269       {
00270         std::string in = get_label(*(series.supp().begin()));
00271         std::string out = get_label(series.get(*(series.supp().begin())));
00272 
00273         if (in.size() && in != "1")
00274         {
00275           using namespace vcsn::r_automaton;
00276           automaton_t bin = make_automaton(
00277             a.structure().series().monoid().alphabet());
00278           rat_exp_t res_in(bin.structure().series());
00279           parse(in, res_in);
00280           elt->appendChild(res_in.value().xml_tree(doc, "in"));
00281         }
00282         if (out.size() && out != "1")
00283         {
00284           using namespace vcsn::r_automaton;
00285           automaton_t bout = make_automaton(
00286             a.structure().series().semiring().monoid().alphabet());
00287           rat_exp_t res_out(bout.structure().series());
00288           parse(out, res_out);
00289           elt->appendChild(res_out.value().xml_tree(doc, "out"));
00290         }
00291       }
00292 
00293 
00294       template <class L>
00295       const std::string get_label(const L& l)
00296       {
00297         std::ostringstream os;
00298         os << l;
00299         return os.str();
00300       }
00301 
00302       inline const std::string get_label(const bool& l)
00303       {
00304         if (l)
00305           return "";
00306         return "0";
00307       }
00308 
00309 
00310       inline const std::string get_label(const std::pair<std::string, std::string>& l)
00311       {
00312         std::ostringstream os;
00313         os << "(" << l.first << ", " << l.second << ")";
00314         return os.str().c_str();
00315       }
00316 
00317       template <class S, class Series>
00318       const std::string get_label(const Element<Series,
00319                                   vcsn::algebra::polynom<S, bool> >& l)
00320       {
00321         std::ostringstream os;
00322         os << l;
00323         if (os.str() == "1")
00324           return "";
00325         return os.str();
00326       }
00327 
00328 
00329       template <class A>
00330       void create_alphabet(const A& alphabet, xercesc::DOMDocument* doc,
00331                            xercesc::DOMElement* root)
00332       {
00333         typedef typename A::const_iterator alphabet_iterator;
00334         for_all_letters(l, alphabet)
00335         {
00336           std::ostringstream letter;
00337           xercesc::DOMElement* gen =
00338             doc->createElement(transcode("generator"));
00339           letter << *l;
00340           set_attribute(gen, "value", letter.str().c_str());
00341           root->appendChild(gen);
00342         }
00343       }
00344 
00345       template <class M>
00346       xercesc::DOMElement* create_monoid(const M& monoid,
00347                                          xercesc::DOMDocument* doc,
00348                                          xercesc::DOMElement* elt)
00349       {
00350         xercesc::DOMElement* m = doc->createElement(transcode("monoid"));
00351         set_attribute(m, "type", get_monoid_type(monoid));
00352         set_attribute(m, "generators", "letters");
00353         elt->appendChild(m);
00354 
00355         return m;
00356       }
00357 
00358       template <class A, class S>
00359       xercesc::DOMElement* create_semiring(const A&,
00360                                            const S& semiring,
00361                                            xercesc::DOMDocument* doc,
00362                                            xercesc::DOMElement* elt)
00363       {
00364         typedef typename A::series_set_elt_t::semiring_elt_t::value_t value_t;
00365 
00366         xercesc::DOMElement* s = doc->createElement(transcode("semiring"));
00367 
00368         if (get_semiring_set(semiring, value_t()) != "ratSeries")
00369           set_attribute(s, "operations", get_semiring_operations(semiring));
00370         set_attribute(s, "set", get_semiring_set(semiring, value_t()));
00371         elt->appendChild(s);
00372 
00373         return s;
00374       }
00375 
00376       template <class S, class T>
00377       xercesc::DOMElement*
00378       create_semiring(const Element<Transducer<S>, T>&,
00379                       const vcsn::algebra::NumericalSemiring& semiring,
00380                       xercesc::DOMDocument* doc,
00381                       xercesc::DOMElement* elt)
00382       {
00383         typedef typename
00384           Element<Transducer<S>, T>::series_set_elt_t::semiring_elt_t::semiring_elt_t::value_t
00385           value_t;
00386 
00387         xercesc::DOMElement* s = doc->createElement(transcode("semiring"));
00388         set_attribute(s, "operations", "numerical");
00389         set_attribute(s, "set", get_semiring_set(semiring, value_t()));
00390         elt->appendChild(s);
00391 
00392         return s;
00393       }
00394 
00395       template <class T>
00396       Element<typename T::series_set_t, rat::exp<typename T::monoid_elt_value_t,
00397                                                  typename T::semiring_elt_value_t> >
00398       get_rec_xml_series(xercesc::DOMNode* n, T& aut)
00399       {
00400         typedef  rat::exp<typename T::monoid_elt_value_t,
00401                           typename T::semiring_elt_value_t> krat_exp_impl_t;
00402         typedef Element<typename T::series_set_t, krat_exp_impl_t> krat_exp_t;
00403         krat_exp_t krat_exp (aut.structure().series());
00404         typename T::semiring_elt_value_t weight =
00405           typename T::semiring_elt_value_t();
00406 
00407         xercesc::DOMElement* element_n;
00408         xercesc::DOMNode* ntmp;
00409 
00410         if (!n)
00411           return vcsn::algebra::identity_as<krat_exp_impl_t>::
00412 	    of(krat_exp.structure());
00413 
00414         for (; n ; n = n->getNextSibling())
00415         {
00416           if (n->getNodeType() == xercesc::DOMNode::ELEMENT_NODE)
00417           {
00418             element_n = (static_cast<xercesc::DOMElement*>(n));
00419 
00420             if ((xml2str(n->getNodeName()) == "label") ||
00421                 (xml2str(n->getNodeName()) == "in") ||
00422                 (xml2str(n->getNodeName()) == "out"))
00423               return get_rec_xml_series(n->getFirstChild(), aut);
00424 
00425             // Add weight
00426             if (element_n->hasAttribute(transcode("weight")))
00427             {
00428               std::stringstream ss;
00429               ss << xml2str(element_n->getAttribute(transcode("weight")));
00430               ss >> weight;
00431             }
00432 
00433             // Explore the terms of a sum
00434             if (xml2str(n->getNodeName()) == "sum")
00435             {
00436               ntmp = n->getFirstChild()->getNextSibling();
00437               krat_exp = get_rec_xml_series(ntmp, aut);
00438               if (ntmp)
00439                 for (ntmp = ntmp->getNextSibling();
00440                      ntmp && ntmp->getNextSibling();
00441                      ntmp = ntmp->getNextSibling()->getNextSibling())
00442                   krat_exp += get_rec_xml_series(ntmp, aut);
00443               return (weight != typename T::semiring_elt_t ())?
00444                 typename T::semiring_elt_t (weight) * krat_exp : krat_exp;
00445             }
00446 
00447             // Explore the terms of a product
00448             if (xml2str(n->getNodeName()) == "product")
00449             {
00450               ntmp = n->getFirstChild()->getNextSibling();
00451               krat_exp = get_rec_xml_series(ntmp, aut);
00452               if (ntmp)
00453                 for (ntmp = ntmp->getNextSibling();
00454                      ntmp && ntmp->getNextSibling();
00455                      ntmp = ntmp->getNextSibling()->getNextSibling())
00456                   krat_exp *= get_rec_xml_series(ntmp, aut);
00457               return (weight != typename T::semiring_elt_t ())?
00458                 typename T::semiring_elt_t (weight) * krat_exp : krat_exp;
00459             }
00460 
00461             // Word, zero or identity
00462             if (xml2str(n->getNodeName()) == "word")
00463               krat_exp = typename T::monoid_elt_t (
00464                 krat_exp.structure().monoid(),
00465                 xml2str(element_n->getAttribute(transcode("value"))));
00466 
00467             if (xml2str(n->getNodeName()) == "zero")
00468               krat_exp = vcsn::algebra::
00469 		zero_as<krat_exp_impl_t>::of(krat_exp.structure());
00470 
00471             if (xml2str(n->getNodeName()) == "identity")
00472               krat_exp =  vcsn::algebra::
00473 		identity_as<krat_exp_impl_t>::of(krat_exp.structure());
00474 
00475             // Add star
00476             if (xml2str(n->getNodeName()) == "star")
00477               krat_exp = (get_rec_xml_series(n->getFirstChild(), aut)).star();
00478 
00479             return (weight != typename T::semiring_elt_t ())?
00480               typename T::semiring_elt_t (weight) * krat_exp : krat_exp;
00481           }
00482         }
00483         return krat_exp;
00484       }
00485 
00486 
00498       template <class T>
00499       typename T::series_set_elt_t
00500       get_series(xercesc::DOMElement* node, T& aut)
00501       {
00502         typedef typename
00503           rat::exp<typename T::monoid_elt_value_t,
00504           typename T::semiring_elt_value_t> krat_exp_impl_t;
00505         typedef Element<typename T::series_set_t, krat_exp_impl_t> krat_exp_t;
00506         krat_exp_t res (aut.structure().series());
00507         xercesc::DOMNode* n = node->getFirstChild();
00508         if (n && n->getNextSibling()
00509             && (xml2str(n->getNextSibling()->getNodeName()) == "label"))
00510           res = get_rec_xml_series(n, aut);
00511         if (res == vcsn::algebra::
00512             zero_as<krat_exp_impl_t>::of(res.structure()))
00513         {
00514           if (xml2str(node->getAttribute(transcode("label"))) == "")
00515             return
00516               vcsn::algebra::identity_as<typename T::series_set_elt_t::value_t>
00517 	      ::of(aut.structure().series());
00518           else
00519             parse(xml2str(node->getAttribute(transcode("label"))), res);
00520         }
00521         return res;
00522       }
00523 
00524 
00525       template <class S, class T, class M1, class M2>
00526       typename FMPtype::series_set_elt_t
00527       get_series(xercesc::DOMElement* node, FMPtype& a)
00528       {
00529         typename FMPtype::series_set_elt_t res(a.structure().series());
00530 
00531         parse_label(node, a,
00532                     a.structure().series().monoid().first_monoid().alphabet(),
00533                     a.structure().series().monoid().second_monoid().alphabet(),
00534                     res);
00535 
00536         return res;
00537       }
00538 
00539 
00540 # define TRANStype                              \
00541     Element<Transducer<S>, T>
00542 
00543       template <class S, class T>
00544       typename TRANStype::series_set_elt_t
00545       get_series(xercesc::DOMElement* node,
00546                  TRANStype& a)
00547       {
00548         typename TRANStype::series_set_elt_t res(a.structure().series());
00549 
00550         parse_label(node, a,
00551                     a.structure().series().monoid().alphabet(),
00552                     a.structure().series().semiring().monoid().alphabet(),
00553                     res);
00554 
00555         return res;
00556       }
00557 
00558 
00559       template <class S, class T, class E1, class E2, class R>
00560       void assoc_exp(TRANStype& a, E1& i_exp, E2& o_exp, R& res,
00561                      bool i_res, bool o_res)
00562       {
00563         typedef typename TRANStype::monoid_elt_t::value_t md_value_t;
00564         typedef typename TRANStype::semiring_elt_t::value_t sg_value_t;
00565         typename TRANStype::monoid_elt_t m(a.structure().series().monoid());
00566 
00567         if (! i_res && i_exp.supp().size())
00568           m = *(i_exp.supp().begin());
00569         else
00570           m = vcsn::algebra::identity_as<md_value_t>
00571 	    ::of(a.structure().series().monoid());
00572 
00573         if (! o_res && ! o_exp.supp().size())
00574           res.assoc(m,
00575                     vcsn::algebra::identity_as<sg_value_t>
00576                     ::of(a.structure().series().semiring()));
00577         else
00578           res.assoc(m, o_exp);
00579       }
00580 
00581 
00582       template <class S, class T, class M1, class M2,
00583                 class E1, class E2, class R>
00584       void assoc_exp(FMPtype& a, E1& i_exp, E2& o_exp, R& res,
00585                      bool i_res, bool o_res)
00586       {
00587         typename FMPtype::monoid_elt_t m(a.structure().series().monoid());
00588         typename FMPtype::monoid_elt_t::first_monoid_elt_value_t m1("");
00589         typename FMPtype::monoid_elt_t::second_monoid_elt_value_t m2("");
00590         typename FMPtype::semiring_elt_value_t sem = 1;
00591         typedef typename FMPtype::monoid_elt_t::first_monoid_elt_t::value_t
00592           md_value_t;
00593         typedef typename FMPtype::semiring_elt_value_t sg_value_t;
00594 
00595         if (! i_res && i_exp.supp().size())
00596           m1 = *(i_exp.supp().begin());
00597         else
00598           m1 = vcsn::algebra::identity_as<md_value_t>
00599 	    ::of(a.structure().series().monoid().first_monoid()).value();
00600 
00601         if (! o_res && o_exp.supp().size())
00602         {
00603           m2 = *(o_exp.supp().begin());
00604           sem = o_exp.get(m2);
00605         }
00606         else
00607         {
00608           m2 = vcsn::algebra::identity_as<md_value_t>
00609 	    ::of(a.structure().series().monoid().second_monoid()).value();
00610           sem = vcsn::algebra::identity_as<sg_value_t>
00611 	    ::of(a.structure().series().semiring()).value();
00612         }
00613         m = std::make_pair(m1, m2);
00614         res.assoc(m, sem);
00615       }
00616 
00617 
00618       template <class A, class A1, class A2, class S>
00619       void parse_label(xercesc::DOMElement* node, A& a,
00620                        const A1& alphabet1, const A2& alphabet2, S& res)
00621       {
00622         using namespace vcsn::r_automaton;
00623         automaton_t bin = make_automaton(alphabet1);
00624         automaton_t bout = make_automaton(alphabet2);
00625         rat_exp_t i_exp(bin.structure().series());
00626         rat_exp_t o_exp(bout.structure().series());
00627         std::string in, out;
00628 
00629         std::pair<bool, std::string> i_res;
00630         std::pair<bool, std::string> o_res;
00631 
00632         xercesc::DOMNode* n = node->getFirstChild();
00633 
00634         if (n)
00635           for (; n; n = n->getNextSibling())
00636           {
00637             if (xml2str(n->getNodeName()) == "in" && n->getFirstChild())
00638               i_exp = get_rec_xml_series(n->getFirstChild(), bin);
00639             if (xml2str(n->getNodeName()) == "out" && n->getFirstChild())
00640               o_exp = get_rec_xml_series(n->getFirstChild(), bout);
00641           }
00642         // No expression tag
00643         else
00644         {
00645           if (node->hasAttribute(transcode("label")))
00646           {
00647             std::string label = xml2str(node->getAttribute(transcode("label")));
00648             unsigned int pos = label.find("|");
00649             if (pos != std::string::npos)
00650             {
00651               in = label.substr(0, pos);
00652               out = label.substr(pos + 1);
00653               i_res = parse(in, i_exp);
00654               o_res = parse(out, o_exp);
00655             }
00656             else
00657               i_res = parse(label, i_exp);
00658             if (node->hasAttribute(transcode("weight")))
00659               o_res = parse(xml2str(node->getAttribute(transcode("weight"))),
00660                             o_exp);
00661           }
00662           // No expression tag, no label attribute.
00663           else
00664           {
00665             if (node->hasAttribute(transcode("in")))
00666               i_res = parse(xml2str(node->getAttribute(transcode("in"))),
00667                             i_exp);
00668             if (node->hasAttribute(transcode("out")))
00669               o_res = parse(xml2str(node->getAttribute(transcode("out"))),
00670                             o_exp);
00671           }
00672         }
00673         assoc_exp(a, i_exp, o_exp, res, i_res.first, o_res.first);
00674       }
00675 
00676 
00687       template <class U, class V>
00688       void insert_letter(Element<vcsn::algebra::AlphabetSet<U>, V>&,
00689                          const std::string&)
00690       {
00691         FAIL("No available implementation for this type of letter");
00692       }
00693 
00694       template <class V>
00695       void insert_letter(Element<vcsn::algebra::AlphabetSet<char>, V>& a,
00696                          const std::string& str)
00697       {
00698         a.insert(str[0]);
00699       }
00700 
00701 
00713       template <class T, class U>
00714       void ensure_semiring_type(const xercesc::DOMElement* node,
00715                                 const T&, const U& param)
00716       {
00717         typedef typename T::series_set_elt_t::semiring_elt_t::value_t value_t;
00718 
00719         std::string set(tools::get_semiring_set(param, value_t()));
00720         std::string set_ref;
00721 
00722         if (node && node->hasAttribute(transcode("set")))
00723           set_ref = xml2str(node->getAttribute(transcode("set")));
00724         else
00725           set_ref = "B";
00726         if (set_ref != set)
00727           FAIL("Bad semiring");
00728       }
00729 
00730 
00731       template <class S, class T>
00732       void ensure_semiring_type(const xercesc::DOMElement* node,
00733                                 const Element<Transducer<S>, T>&,
00734                                 const typename Element<Transducer<S>, T>
00735                                 ::semiring_t::semiring_t& param)
00736       {
00737         typedef Element<Transducer<S>, T> trans_t;
00738         typedef typename
00739           trans_t::series_set_elt_t::semiring_elt_t::semiring_elt_t::value_t
00740           value_t;
00741 
00742         std::string set(tools::get_semiring_set(param, value_t()));
00743         std::string set_ref;
00744 
00745         if (node && node->hasAttribute(transcode("set")))
00746           set_ref = xml2str(node->getAttribute(transcode("set")));
00747         else
00748           set_ref = "B";
00749         if (set_ref != set)
00750           FAIL("Bad semiring");
00751       }
00752 
00753 
00754       template <class S, class T, class U>
00755       void ensure_semiring_type(const xercesc::DOMElement* node,
00756                                 const Element<Transducer<S>, T>&,
00757                                 const typename Element<Transducer<S>, T>
00758                                 ::semiring_t& param)
00759       {
00760         typedef Element<Transducer<S>, T> trans_t;
00761         typedef typename
00762           trans_t::series_set_elt_t::semiring_elt_t::value_t value_t;
00763 
00764         std::string set(tools::get_semiring_set(param, value_t()));
00765         std::string set_ref;
00766 
00767         if (node && node->hasAttribute(transcode("set")))
00768           set_ref = xml2str(node->getAttribute(transcode("set")));
00769         else
00770           set_ref = "ratSeries";
00771         if (set_ref != set)
00772           FAIL("Bad semiring");
00773       }
00774 
00775 
00785       template <class U>
00786       void ensure_monoid_type(const xercesc::DOMElement* node, const U& param)
00787       {
00788         std::string monoid_type_ref = tools::get_monoid_type(param);
00789         std::string monoid_type;
00790 
00791         if (! node || ! node->hasAttribute(transcode("type")))
00792           monoid_type = "free";
00793         else
00794           monoid_type = xml2str(node->getAttribute(transcode("type")));
00795         if (monoid_type != monoid_type_ref)
00796           FAIL(std::string ("Bad monoid type: ")
00797                + monoid_type
00798                + ", expected: "
00799                + monoid_type_ref);
00800       }
00801 
00802 
00803       template <class S, class T, class U, class M1, class M2>
00804       void ensure_monoid_type(const xercesc::DOMElement* node,
00805                               const FMPtype& param)
00806       {
00807         std::string monoid_type_ref = tools::get_monoid_type(param);
00808         std::string monoid_type;
00809 
00810         if (! node || ! node->hasAttribute(transcode("type")))
00811           monoid_type = "product";
00812         else
00813           monoid_type = xml2str(node->getAttribute(transcode("type")));
00814         if (monoid_type != monoid_type_ref)
00815           FAIL(std::string ("Bad monoid type: ")
00816                + monoid_type
00817                + ", expected: "
00818                + monoid_type_ref);
00819       }
00820 
00821 
00822       template <class OStream>
00823       void print_transition(const xercesc::DOMElement* n,
00824                             OStream& os,
00825                             std::string& spacing)
00826       {
00827         os << spacing << "<" << xml2str(n->getNodeName());
00828 # define VCSN_TRANS_OUTPUT(What)                                        \
00829         if (n->hasAttribute(transcode(What)))                           \
00830           os << " " What "=\""                                          \
00831              << xml2str(n->getAttribute(transcode(What))) << "\""
00832         VCSN_TRANS_OUTPUT("src");
00833         VCSN_TRANS_OUTPUT("dst");
00834         VCSN_TRANS_OUTPUT("label");
00835         VCSN_TRANS_OUTPUT("weight");
00836         VCSN_TRANS_OUTPUT("in");
00837         VCSN_TRANS_OUTPUT("out");
00838 # undef VCSN_TRANS_OUTPUT
00839       }
00840 
00841 
00842       template <class OStream>
00843       void print_tree(const xercesc::DOMElement* node,
00844                       OStream& os,
00845                       std::string spacing)
00846       {
00847         using namespace xercesc;
00848         unsigned i;
00849         DOMNamedNodeMap* m;
00850 
00851         if (xml2str(node->getNodeName()) == "transition")
00852           print_transition(static_cast<const DOMElement*>(node), os, spacing);
00853         else
00854         {
00855           os << spacing << "<" << xml2str(node->getNodeName());
00856           for (m = node->getAttributes(), i = 0;
00857                i < m->getLength(); ++i)
00858           {
00859             os << " " << xml2str(m->item(i)->getNodeName())
00860                << "=\"" << xml2str(m->item(i)->getNodeValue())
00861                << "\"";
00862           }
00863         }
00864         if (node->hasChildNodes())
00865           os << ">";
00866         else
00867           os << "/>";
00868         os << std::endl;
00869         for (DOMNode* n = node->getFirstChild(); n; n = n->getNextSibling())
00870           if (n->getNodeType() == DOMNode::ELEMENT_NODE)
00871             print_tree(static_cast<const DOMElement*>(n), os, spacing + "  ");
00872         if (node->hasChildNodes())
00873           os << spacing << "</" << xml2str(node->getNodeName()) << ">"
00874              << std::endl;
00875       }
00876 
00877 
00887       template <class OStream>
00888       void print_document(xercesc::DOMElement* node, OStream& os)
00889       {
00890         set_attribute(node, "xmlns", "http://vaucanson.lrde.epita.fr");
00891         print_tree(node, os, "");
00892       }
00893 
00894 
00895     } // ! tools
00896 
00897   } // ! xml
00898 
00899 } // ! vcsn
00900 
00901 
00902 # undef TRANStype
00903 # undef FMPtype
00904 
00905 #endif // ! VCSN_XML_TOOLS_HXX

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