- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

# tools.hxx

Go to the documentation of this file.

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