LCOV - code coverage report
Current view: top level - builds/barbot/Cosmos/src/ModelGenerator/GspnParser - Gspn_gmlparser.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 472 765 61.7 %
Date: 2021-06-16 15:43:28 Functions: 16 23 69.6 %

          Line data    Source code
       1             : /*******************************************************************************
       2             :  *                                                                             *
       3             :  * Cosmos:(C)oncept et (O)utils (S)tatistique pour les (Mo)deles               *
       4             :  * (S)tochastiques                                                             *
       5             :  *                                                                             *
       6             :  * Copyright (C) 2009-2012 LSV & LACL                                          *
       7             :  * Authors: Paolo Ballarini BenoƮt Barbot & Hilal Djafri                       *
       8             :  * Website: http://www.lsv.ens-cachan.fr/Software/cosmos                       *
       9             :  *                                                                             *
      10             :  * This program is free software; you can redistribute it and/or modify        *
      11             :  * it under the terms of the GNU General Public License as published by        *
      12             :  * the Free Software Foundation; either version 3 of the License, or           *
      13             :  * (at your option) any later version.                                         *
      14             :  *                                                                             *
      15             :  * This program is distributed in the hope that it will be useful,             *
      16             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of              *
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
      18             :  * GNU General Public License for more details.                                *
      19             :  *                                                                             *
      20             :  * You should have received a copy of the GNU General Public License along     *
      21             :  * with this program; if not, write to the Free Software Foundation, Inc.,     *
      22             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                 *
      23             :  * file Gspn_gmlparser.cpp                                                     *
      24             :  * Created by Benoit Barbot on 05/10/12.                                       *
      25             :  *******************************************************************************
      26             :  */
      27             : 
      28             : #ifdef HAVE_CONFIG_H
      29             : #include <config.h>
      30             : #endif
      31             : 
      32             : #include <fstream>
      33             : #include <iostream>
      34             : #include <vector>
      35             : #include <string>
      36             : #include <algorithm>
      37             : #include <iomanip>
      38             : #include <boost/algorithm/string/replace.hpp>
      39             : 
      40             : //#include "tree.hh"
      41             : #include "tree/tree_util.hh"
      42             : 
      43             : 
      44             : #include "expatmodelparser.hh"
      45             : #include "modelhandler.hh"
      46             : #include "Gspn_gmlparser.hpp"
      47             : #include "Gspn-Reader.hpp"
      48             : 
      49             : 
      50          35 : Eval Evaluate_gml;
      51             : 
      52             : using namespace std;
      53             : using namespace text_output;
      54             : 
      55             : // Do not remove, sometime usefull for debugging
      56             : /*void print_tree(const tree<string>& tr, tree<string>::pre_order_iterator it, tree<string>::pre_order_iterator end)
      57             :  {
      58             :  if(!tr.is_valid(it)) return;
      59             :  int rootdepth=tr.depth(it);
      60             :  while(it!=end) {
      61             :  cout << "    ";
      62             :  for(int i=0; i<tr.depth(it)-rootdepth; ++i)
      63             :  cout << "  ";
      64             :  cout << (*it) << endl << flush;
      65             :  ++it;
      66             :  }
      67             :  }*/
      68             : 
      69        4377 : string MyModelHandler::simplifyString(string str) {
      70        4377 :     size_t n1 = str.find_first_not_of(" \n\t");
      71        4377 :     size_t n2 = str.find_last_not_of(" \n\t");
      72        4377 :     if (n1 == std::string::npos)return "";
      73        8514 :     auto str2 = str.substr(n1, n2 - n1 + 1);
      74             :     using boost::algorithm::replace_all;
      75        4257 :     replace_all(str2, "&amp;", "&");
      76        4257 :     replace_all(str2, "&lt;", "<");
      77        4257 :     replace_all(str2, "&gt;", ">");
      78             : 
      79        4257 :     return str2;
      80             : }
      81             : 
      82        2499 : expr MyModelHandler::eval_expr(tree<string>::pre_order_iterator it) {
      83        2499 :     if ((P.verbose - 3) > 1)cout << *it << endl;
      84        2499 :     if (*it == "function") {
      85          16 :         return eval_expr(it.begin());
      86        2483 :     } else if (*it == "expr") {
      87         165 :         return eval_expr(it.begin());
      88        2318 :     } else if (*it == "intValue" || *it == "numValue") {
      89        4186 :         const auto str = simplifyString(it.node->first_child->data);
      90        2093 :         if (*it == "intValue")return expr(stoi(str));
      91        1700 :         else return expr(stod(str));
      92         225 :     } else if (*it == "unParsed") {
      93           0 :         const auto str = simplifyString(it.node->first_child->data);
      94           0 :         return expr(str);
      95         225 :     } else if (*it == "name") {
      96         210 :         string var = simplifyString(it.node->first_child->data);
      97         210 :         if (MyGspn->IntConstant.count(var) > 0
      98          84 :             || MyGspn->RealConstant.count(var) > 0
      99           0 :             || MyGspn->ExternalConstant.count(var) > 0
     100         105 :             || any_of(MyGspn->hybridVars.begin(), MyGspn->hybridVars.end(), [&](const hybridVariable &v){return v.name == var;})){
     101         105 :             return expr(Constant, var);
     102             :         } else {
     103           0 :             if ((P.verbose - 3) > 1)cout << "\t" << var << endl;
     104           0 :             if (MyGspn->PlacesId.count(var) == 0) {
     105           0 :                 throw GrmlInputException("Identifier " + var + " unbound");
     106             :             }
     107           0 :             if (MyGspn->placeStruct[MyGspn->PlacesId[var]].colorDom != 0) {
     108           0 :                 return expr(PlaceName, var + ".card()");
     109           0 :             } else return expr(PlaceName, var);
     110             :         }
     111         360 :     } else if (*it == "+" || *it == "*"
     112         114 :                || *it == "min" || *it == "max"
     113         114 :                || *it == "floor" || *it == "minus" || *it == "-"
     114         234 :                || *it == "/" || *it == "power" || *it == "exp") {
     115             : 
     116          32 :         expr rhs;
     117          32 :         expr lhs;
     118             : 
     119          48 :         for (treeSI it2 = (it.begin()); it2 != (it.end()); ++it2) {
     120          32 :             if (it2 != it.begin()) {
     121          16 :                 rhs = eval_expr(it2);
     122             :             } else {
     123          16 :                 lhs = eval_expr(it2);
     124             :             };
     125             : 
     126             :         }
     127             : 
     128          16 :         if (!rhs.empty()){
     129          16 :             if (*it == "ceil") {
     130           0 :                 return expr(Ceil, lhs, rhs);
     131          16 :             } else if (*it == "exp") {
     132           0 :                 return expr(Exp, lhs, rhs);
     133          16 :             } else if (*it == "floor") {
     134           0 :                 return expr(Floor, lhs, rhs);
     135          16 :             } else if(!lhs.empty()){
     136          16 :                 if (*it == "+") {
     137           0 :                     return expr(Plus, lhs, rhs);
     138          16 :                 } else if (*it == "*") {
     139           6 :                     return expr(Times, lhs, rhs);
     140          10 :                 } else if (*it == "minus" || *it == "-") {
     141           0 :                     return expr(Minus, lhs, rhs);
     142          10 :                 } else if (*it == "/") {
     143          10 :                     return expr(Div, lhs, rhs);
     144           0 :                 } else if (*it == "power") {
     145           0 :                     return expr(Pow, lhs, rhs);
     146           0 :                 } else if (*it == "min") {
     147           0 :                     return expr(Min, lhs, rhs);
     148           0 :                 } else if (*it == "max") {
     149           0 :                     return expr(Max, lhs, rhs);
     150             :                 }
     151             :             }
     152             :         }
     153           0 :         throw GrmlInputException("fail to eval expr: '" + *it + "'");
     154         104 :     } else if (simplifyString(*it).empty()){
     155          96 :         return expr(0);
     156           8 :     } else if (it.node->parent->data =="function" ){
     157           0 :         if ((P.verbose - 3) > 1)cout << "newfunction:'" << *it << "'" << endl;
     158           0 :         expr lhs(*it);
     159           0 :         expr rhs;
     160           0 :         for (treeSI it2 = (it.begin()); it2 != (it.end()); ++it2) {
     161           0 :             if (it2 != it.begin()) {
     162           0 :                 expr rhs2 = rhs;
     163           0 :                 expr interm = eval_expr(it2);
     164           0 :                 rhs = expr(ListContinuation,rhs2,interm);
     165             :             } else {
     166           0 :                 rhs = eval_expr(it2);
     167             :             };
     168             : 
     169             :         }
     170           0 :         return expr(App, lhs, rhs);
     171             :     }
     172             : 
     173             : 
     174             :     try {
     175          16 :         const auto str = simplifyString(*it);
     176           8 :         int ival = stoi(str);
     177           8 :         double rval = stod(str);
     178           8 :         if( (double)ival == rval )return expr(ival);
     179           0 :         return expr(rval);
     180           0 :     } catch (const invalid_argument& ia) {
     181           0 :         throw GrmlInputException("fail to evaluate expr: '" + *it + "'");
     182             :     }
     183             : }
     184             : 
     185         860 : void MyModelHandler::eval_tokenProfileArc(coloredToken& tok, bool &markingdependant, set<size_t>& vardom, tree<string>::pre_order_iterator it, bool isInitialMarking) {
     186         860 :     if ((P.verbose - 3) > 1)cout << ">" << (*it) << endl;
     187         860 :     if (*it == "function") {
     188          23 :         eval_tokenProfileArc(tok, markingdependant, vardom, it.begin(),isInitialMarking);
     189         837 :     } else if (*it == "++" || *it == "--") {
     190           6 :         int incr = 1;
     191          18 :         for (treeSI it2 = it.begin(); it2 != it.end(); ++it2) {
     192          12 :             if (*it2 == "name") {
     193           6 :                 eval_tokenProfileArc(tok, markingdependant, vardom, it2,isInitialMarking);
     194           6 :             } else incr = atoi(simplifyString(*(it2).begin()).c_str());
     195             :         }
     196           6 :         tok.varIncrement.back() += ( *it== "++" ? 1 :-1 )* incr;
     197         831 :     } else if (*it == "all") {
     198          34 :         for (treeSI it2 = it.begin(); it2 != it.end(); ++it2) {
     199          17 :             if (*it2 == "type") {
     200          34 :                 string colname = simplifyString(*(it2.begin()));
     201          17 :                 vector<colorClass>::const_iterator cols;
     202          53 :                 for (cols = MyGspn->colClasses.begin();
     203          54 :                      (cols != MyGspn->colClasses.end() && cols->name != colname); ++cols);
     204          17 :                 if (cols != MyGspn->colClasses.end()) {
     205          17 :                     tok.field.push_back((int)(cols - MyGspn->colClasses.begin()));
     206          17 :                     tok.Flags.push_back(CT_ALL);
     207          17 :                     tok.varIncrement.push_back(0);
     208          17 :                     tok.hasAll = true;
     209             :                 } else {
     210           0 :                     throw GrmlInputException("Unknown colorClasse '" + colname + "'");
     211             :                 }
     212             :             }
     213             :         }
     214             : 
     215         814 :     } else if (*it == "expr") {
     216         283 :         eval_tokenProfileArc(tok, markingdependant, vardom, it.begin(),isInitialMarking);
     217         531 :     } else if (*it == "token") {
     218         795 :         for (treeSI it2 = it.begin(); it2 != it.end(); ++it2) {
     219         530 :             if ((P.verbose - 3) > 1)cout << ">" <<(*it2) << endl;
     220         530 :             if (*it2 == "occurs") {
     221         530 :                 const auto e = eval_expr(it2.begin());
     222         265 :                 markingdependant |= e.is_markDep();
     223         265 :                 tok.mult = e;
     224             :             }
     225         530 :             if (*it2 == "tokenProfile") {
     226         548 :                 for (treeSI it3 = it2.begin(); it3 != it2.end(); ++it3) {
     227         283 :                     eval_tokenProfileArc(tok, markingdependant, vardom, it3,isInitialMarking);
     228             :                 }
     229             :             }
     230             :         }
     231         266 :     } else if (*it == "type") {
     232           0 :         string colname = simplifyString(*(it.begin()));
     233           0 :         vector<colorClass>::const_iterator cols;
     234           0 :         for (cols = MyGspn->colClasses.begin();
     235           0 :              cols != MyGspn->colClasses.end() && cols->name != colname; ++cols);
     236           0 :         if (cols != MyGspn->colClasses.end()) {
     237           0 :             expr e((int)(cols - MyGspn->colClasses.begin()));
     238           0 :             tok.field.push_back(e);
     239           0 :             tok.Flags.push_back(CT_SINGLE_COLOR);
     240           0 :             tok.varIncrement.push_back(0);
     241             :         } else {
     242           0 :             throw GrmlInputException("Unknown color '" + colname + "'");
     243             :         }
     244         266 :     } else if (*it == "name" && !isInitialMarking) {
     245         532 :         string varname = simplifyString(*(it.begin()));
     246         266 :         vector<colorVariable>::const_iterator vars;
     247         838 :         for (vars = MyGspn->colVars.begin();
     248         858 :              vars != MyGspn->colVars.end() && vars->name != varname; ++vars);
     249         266 :         if (vars != MyGspn->colVars.end()) {
     250         266 :             tok.field.push_back((int)(vars - MyGspn->colVars.begin()));
     251         266 :             tok.Flags.push_back(CT_VARIABLE);
     252         266 :             tok.varIncrement.push_back(0);
     253         266 :             vardom.insert(vars - MyGspn->colVars.begin());
     254             :         } else {
     255           0 :             throw GrmlInputException("Unknown variable '" + varname + "'");
     256             :         }
     257           0 :     } else if ( (*it == "intConst" || *it== "colorConst") /*&& isInitialMarking*/ ) { //should be color Const only for initial Marking
     258           0 :         colorClass cc;
     259           0 :         size_t value = 0;
     260             :         varType vt;
     261           0 :         for (treeSI it2 = it.begin(); it2 != it.end(); ++it2) {
     262           0 :             if ((P.verbose - 3) > 1)cout << ">" <<(*it2) << endl;
     263           0 :             if (*it2 == "type") {
     264           0 :                 string colname = simplifyString(*(it2.begin()));
     265           0 :                 vector<colorClass>::const_iterator cols;
     266           0 :                 for (cols = MyGspn->colClasses.begin();
     267           0 :                      (cols != MyGspn->colClasses.end() && cols->name != colname); ++cols);
     268           0 :                 if (cols != MyGspn->colClasses.end()) {
     269             :                     //tok.field.push_back(cols - MyGspn->colClasses.begin());
     270           0 :                     cc = *cols;
     271             :                 } else {
     272           0 :                     cerr << "Unknown colorClasse '" + colname + "'" << endl;
     273             :                 }
     274           0 :             } else if (*it2 == "intValue") {
     275           0 :                 auto e = eval_expr(it2);
     276           0 :                 e.eval();
     277           0 :                 vt = CT_SINGLE_COLOR;
     278           0 :                 value=e.intVal;
     279           0 :             } else if (*it2 =="name"){
     280           0 :                 string cname = simplifyString(*(it2.begin()));
     281           0 :                 const auto c = find_if(cc.colors.begin(), cc.colors.end(), [&cname](const color &c){return c.name==cname;});
     282           0 :                 if(c != cc.colors.end()){
     283           0 :                     vt = CT_SINGLE_COLOR;
     284           0 :                     value = c->id;
     285             :                 } else {
     286             :                     const auto ssc = find_if(cc.staticSubclasses.begin(), cc.staticSubclasses.end(),
     287           0 :                                              [&cname](const colorStaticSubclass &scc){return scc.name == cname;});
     288           0 :                     if(ssc != cc.staticSubclasses.end()){
     289           0 :                         vt = CT_ALL_SUBCLASS;
     290           0 :                         tok.hasAll = true;
     291           0 :                         value = ssc->id;
     292             :                     } else {
     293           0 :                         cerr << "Unknown color or static subclasse \""<< cname << "\" inside \""<< cc.cname() << "\" !" << endl;
     294             :                     }
     295             :                 }
     296             :             }
     297             :         }
     298           0 :         tok.Flags.push_back(vt);
     299           0 :         tok.varIncrement.push_back(0);
     300           0 :         tok.field.push_back((int)value);
     301           0 :     } else if (*it == "realConst") {
     302           0 :         for (treeSI it2 = it.begin(); it2 != it.end(); ++it2) {
     303           0 :             auto e = eval_expr(it2);
     304           0 :             e.eval();
     305           0 :             tok.Flags.push_back(CT_SINGLE_REAL);
     306           0 :             tok.varIncrement.push_back(0);
     307           0 :             tok.field.push_back(e.get_real());
     308             : 
     309             :         }
     310             :     } else {
     311           0 :         cerr << "Ill formed Expression \""<< *it << "\" ! " << endl;
     312             :     }
     313         860 : }
     314             : 
     315         304 : int MyModelHandler::eval_intFormula(tree<string>::pre_order_iterator it) {
     316         608 :     expr ex = eval_expr(it);
     317         304 :     ex.eval(MyGspn->IntConstant, MyGspn->RealConstant);
     318         304 :     if (ex.t == Int) {
     319         109 :         return ex.intVal;
     320             :     } else {
     321         195 :         if (ex.t == Real) {
     322         195 :             double r = ex.get_real();
     323         195 :             if (r == ceil(r)) {
     324         195 :                 return (int) r;
     325             :             } else {
     326           0 :                 throw GrmlInputException("Marking should be an integer: " + ex.to_string());
     327             :             }
     328             :         } else {
     329           0 :             throw GrmlInputException("Marking can not be marking dependant:\n" + ex.to_string());
     330             :         }
     331             :     }
     332             : }
     333             : 
     334          57 : double MyModelHandler::eval_realFormula(tree<string>::pre_order_iterator it) {
     335         114 :     expr ex = eval_expr(it);
     336          57 :     ex.eval(MyGspn->IntConstant, MyGspn->RealConstant);
     337          57 :     if (ex.t == Int) {
     338           0 :         return (double) ex.intVal;
     339             :     } else {
     340          57 :         if (ex.t == Real) {
     341          57 :             return ex.get_real();
     342             :         } else {
     343           0 :             throw GrmlInputException("Should not be marking dependant:\n" + ex.to_string());
     344             :         }
     345             :     }
     346             : }
     347             : 
     348         197 : treeSI MyModelHandler::findbranch(treeSI t, string branch) {
     349         197 :     if (branch == "")return t;
     350         171 :     size_t nextnode = branch.find_first_of("/");
     351         393 :     for (treeSI it = (t.begin()); it != (t.end()); ++it) {
     352         287 :         if (it->compare(branch.substr(0, nextnode)) == 0) {
     353          65 :             return findbranch(it, branch.substr(nextnode + 1, branch.length() - nextnode - 1));
     354             :         }
     355             :     }
     356         106 :     return t.end();
     357             : }
     358             : 
     359         510 : expr MyModelHandler::eval_guard(tree<string>::pre_order_iterator it) {
     360         510 :     if ((P.verbose - 3) > 1)cout << (*it) << endl;
     361         510 :     if (*it == "boolExpr") {
     362         109 :         return eval_guard(it.begin());
     363         401 :     } else if (*it == "boolValue") {
     364         186 :         const auto s = simplifyString(*(it.begin()));
     365          93 :         if ((P.verbose - 3) > 1)cout << "\t" << s << endl;
     366          93 :         if (s == "true")return expr(true);
     367           0 :         else return expr(false);
     368         308 :     } else if (*it == "equal") {
     369         160 :         expr lhs = eval_guard(it.begin());
     370         160 :         expr rhs = eval_guard(++it.begin());
     371          80 :         return expr(Eq, lhs, rhs);
     372         228 :     } else if (*it == "notEqual") {
     373           0 :         expr lhs = eval_guard(it.begin());
     374           0 :         expr rhs = eval_guard(++it.begin());
     375           0 :         return expr(Neq, lhs, rhs);
     376         228 :     } else if (*it == "stless") {
     377           0 :         expr lhs = eval_guard(it.begin());
     378           0 :         expr rhs = eval_guard(++it.begin());
     379           0 :         return expr(Sl, lhs, rhs);
     380         228 :     } else if (*it == "lesseq") {
     381           0 :         expr lhs = eval_guard(it.begin());
     382           0 :         expr rhs = eval_guard(++it.begin());
     383           0 :         return expr(Leq, lhs, rhs);
     384         228 :     }else if (*it == "stmore") {
     385           0 :         expr lhs = eval_guard(it.begin());
     386           0 :         expr rhs = eval_guard(++it.begin());
     387           0 :         return expr(SG, lhs, rhs);
     388         228 :     }else if (*it == "moreeq") {
     389           0 :         expr lhs = eval_guard(it.begin());
     390           0 :         expr rhs = eval_guard(++it.begin());
     391           0 :         return expr(Geq, lhs, rhs);
     392         228 :     }else if (*it == "and") {
     393           0 :         expr lhs = eval_guard(it.begin());
     394           0 :         expr rhs = eval_guard(++it.begin());
     395           0 :         return expr(And, lhs, rhs);
     396         228 :     } else if (*it == "or") {
     397         136 :         expr lhs = eval_guard(it.begin());
     398         136 :         expr rhs = eval_guard(++it.begin());
     399          68 :         return expr(Or, lhs, rhs);
     400         160 :     } else if (*it == "in") {
     401           0 :         expr lhs = eval_guard(it.begin());
     402           0 :         expr rhs = eval_guard(++it.begin());
     403           0 :         return expr(In, lhs, rhs);
     404         160 :     } else if (*it == "notin") {
     405           0 :         expr lhs = eval_guard(it.begin());
     406           0 :         expr rhs = eval_guard(++it.begin());
     407           0 :         return expr(NotIn, lhs, rhs);
     408         160 :     } else if (*it == "not") {
     409           0 :         expr lhs = eval_guard(it.begin());
     410           0 :         expr rhs;
     411           0 :         return expr(Neg, lhs, rhs);
     412         160 :     } else if (*it == "expr") {
     413           0 :         return eval_guard(it.begin());
     414         160 :     } else if (*it == "name") {
     415          80 :         string varname = simplifyString(*(it.begin()));
     416         160 :         auto vars = find_if(MyGspn->colVars.begin(),MyGspn->colVars.end(),
     417         320 :                             [&](const colorVariable &vars){return (vars.name==varname);});
     418          80 :         if (vars != MyGspn->colVars.end()) {
     419          80 :             return expr(ColorVarName, varname);
     420             :         } else {
     421           0 :             for( const auto& cc: MyGspn->colClasses)
     422           0 :                 for( const auto& css: cc.staticSubclasses)
     423           0 :                     if (css.name == varname) return expr(cc.name + "_SubClass_"+css.name );
     424             : 
     425           0 :             cerr << "Unknown variable or color subclasse '" << varname << "'" << endl;
     426             :         }
     427          80 :     } else if (*it == "enumConst") {
     428         160 :         string typestr;
     429         160 :         string colorstr;
     430         240 :         for (treeSI it2 = it.begin(); it2 != it.end(); ++it2) {
     431         160 :             if (*it2 == "type") {
     432          80 :                 typestr = simplifyString(*(it2.begin()));
     433             :             }
     434         160 :             if (*it2 == "enumValue") {
     435          80 :                 colorstr = simplifyString(*(it2.begin()));
     436             :             }
     437             :         }
     438          80 :         return expr("Color_" + typestr + "_" + colorstr);
     439           0 :     } else if (*it == "intConst" || *it== "colorConst") {
     440           0 :         auto colorclass = MyGspn->colClasses.end() ;
     441           0 :         string colorstr;
     442           0 :         int colindex = -1;
     443           0 :         for (treeSI it2 = it.begin(); it2 != it.end(); ++it2) {
     444           0 :             if (*it2 == "type") {
     445           0 :                 string typestr = simplifyString(*(it2.begin()));
     446           0 :                 colorclass = find_if(MyGspn->colClasses.begin(), MyGspn->colClasses.end(),
     447           0 :                                      [&typestr](const colorClass &cc){return cc.name==typestr; } );
     448           0 :             } else if (*it2 == "intValue") {
     449           0 :                 const auto str = simplifyString(*(it2.begin()));
     450           0 :                 colindex = stoi(str);
     451           0 :             } else if (*it2 == "name") {
     452           0 :                 colorstr = simplifyString(*(it2.begin()));
     453             :             }
     454             :         }
     455           0 :         if( colorclass != MyGspn->colClasses.end() && (colindex>=0 || !colorstr.empty()) ){
     456           0 :             if(colindex >=0){
     457           0 :                 return expr("Color_" + colorclass->name +"_"+ colorclass->colors[ colindex ].name);
     458             :             }else{
     459           0 :                 const auto col = find_if(colorclass->colors.begin(),colorclass->colors.end(),
     460           0 :                         [&colorstr](const color& c){return c.name==colorstr;} );
     461           0 :                 if(col != colorclass->colors.end()){
     462           0 :                     return expr("Color_" + colorclass->name +"_"+ colorstr);
     463             :                 }else{
     464           0 :                     cerr << "Unknown color "<< colorstr << " in class " << colorclass->name << endl;
     465             :                 }
     466             :             };
     467             :         }else{
     468           0 :             cerr << "Unknown colorclass \n";
     469           0 :             return expr();
     470             :         }
     471             : 
     472             :     }
     473           0 :     cerr << "Unknown attribute " << *it << "\n";
     474           0 :     return expr();
     475             : }
     476             : 
     477          23 : MyModelHandler::MyModelHandler(GspnType &MyGspn2) : MyGspn(&MyGspn2) {
     478          23 :     MyGspn->tr = 0;
     479          23 :     ParsePl = true;
     480          23 :     if (MyGspn->nbpass == 0) {
     481             :         //Initialisation
     482          23 :         MyGspn->pl = 0;
     483             :     }
     484          23 : }
     485             : //~MyModelHandler() { }
     486             : 
     487          23 : MyModelHandler::MyModelHandler(GspnType &MyGspn2, map<int, bool> &mip, map<int, int> &mgp, map<int, int> &mgt) : IsPlace(mip), Gml2Place(mgp), Gml2Trans(mgt), MyGspn(&MyGspn2) {
     488          23 :     MyGspn->tr = 0;
     489          23 :     ParsePl = true;
     490          23 :     if (MyGspn->nbpass == 0) {
     491             :         //Initialisation
     492           0 :         MyGspn->pl = 0;
     493             :     }
     494          23 : }
     495             : 
     496          46 : void MyModelHandler::on_read_model(const XmlString& formalismUrl) {
     497             :     // output used formalism
     498          46 :     ParsePl = true;
     499          46 :     if ((P.verbose - 3) > 0)cout << "read model : formalism = " << formalismUrl << endl;
     500          46 : }
     501             : 
     502          94 : void MyModelHandler::on_read_model_attribute(const Attribute& attribute) {
     503          94 :     if (MyGspn->nbpass == 1){
     504          94 :         for (treeSI it = attribute.begin(); it != attribute.end(); ++it) {
     505          47 :             if (*it == "externalMainFile") {
     506           0 :                 const auto extdef = simplifyString(*(it.begin()));
     507           0 :                 if ((P.verbose - 3) > 1)cout <<  extdef << endl;
     508           0 :                 P.PathGspn = extdef;
     509           0 :                 P.modelType = External;
     510             :             }
     511          47 :             if (*it == "Hybrid_GSPN_Simulink"){
     512           0 :                 if ((P.verbose - 3) > 1)cout << "Model type: GSPN_Simulink" << endl;
     513           0 :                 P.modelType = GSPN_Simulink;
     514             :             }
     515             :         }
     516          47 :         return;
     517             :     }
     518             : 
     519             :     // read model attribute
     520             :     // If the file is well formed the only attributes are constant declaration.
     521             : 
     522          94 :     for (treeSI it = attribute.begin(); it != attribute.end(); ++it) {
     523          47 :         if ((P.verbose - 3) > 1)cout << *it << ":" << endl;
     524             : 
     525          47 :         if (*it == "externalDeclaration" && P.magic_values.empty() ) {
     526           0 :             const auto extdef = simplifyString(*(it.begin()));
     527           0 :             if ((P.verbose - 3) > 1)cout <<  extdef << endl;
     528           0 :             P.magic_values = "magic.hpp";
     529           0 :             ofstream extdefhand( P.tmpPath+"/magic.hpp", ios::out | ios::trunc);
     530           0 :             extdefhand << "#include <string>\nusing namespace std;\n" << extdef << endl;
     531           0 :             extdefhand.close();
     532           0 :             if(P.lightSimulator){
     533           0 :               auto cmd = "sed -ibackup -e 's/return \\(\"[^\"]*\"\\);/print(\\1);break;/g' -e 's/return to_string2(v)/print((TR_PL_ID)v);break;/g' -e 's/ string / void /g' "+ P.tmpPath+"/magic.hpp";
     534           0 :                 if(P.verbose>2)cout << cmd << endl;
     535           0 :                 if(system(cmd.c_str()) != 0){
     536           0 :                   cerr << "Fail to copy files to tmp directory" << endl;
     537           0 :                   exit( EXIT_FAILURE);
     538             :                 }
     539             :             }
     540             :         }
     541             : 
     542          47 :         if (*it == "declaration") {
     543          22 :             treeSI t1 = findbranch(it, "constants/intConsts/");
     544          22 :             if (t1 != it.end())
     545          26 :                 for (treeSI it2 = (t1.begin()); it2 != (t1.end()); ++it2) {
     546          13 :                     if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     547          13 :                     if (*it2 == "intConst") { // const is int or double
     548          16 :                         string constname = simplifyString((find(it2.begin(), it2.end(), "name")).node->first_child->data);
     549           8 :                         int constvalue = eval_intFormula(find(it2.begin(), it2.end(), "expr"));
     550           8 :                         if ((P.verbose - 3) > 1)cout << "const int " << constname << "=" << constvalue << endl;
     551           8 :                         if (P.constants.count(constname) > 0) {
     552           4 :                             constvalue = stoi(P.constants[constname]);
     553           4 :                             if ((P.verbose - 3) > 0)cout << "const int " << constname << " overwrite to " << constvalue << endl;
     554             :                             ;
     555             :                         }
     556           8 :                         MyGspn->IntConstant[constname] = constvalue;
     557           8 :                         MyGspn->RealConstant[constname] = constvalue;
     558             :                     }
     559             :                 }
     560             : 
     561          22 :             treeSI t2 = findbranch(it, "constants/realConsts/");
     562          22 :             if (t2 != it.end())
     563          71 :                 for (treeSI it2 = (t2.begin()); it2 != (t2.end()); ++it2) {
     564          58 :                     if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     565          58 :                     if (*it2 == "realConst") {
     566          57 :                         if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     567         114 :                         string constname = simplifyString((find(it2.begin(), it2.end(), "name")).node->first_child->data);
     568          57 :                         double constvalue = eval_realFormula(find(it2.begin(), it2.end(), "expr").begin());
     569          57 :                         if (P.constants.count(constname) > 0) {
     570           0 :                             constvalue = stod(P.constants[constname]);
     571           0 :                             if ((P.verbose - 3) > 0)cout << "const double " << constname << " overwrite to " << constvalue << endl;
     572             :                             ;
     573             :                         }
     574          57 :                         MyGspn->RealConstant[constname] = constvalue;
     575          57 :                         if ((P.verbose - 3) > 1)cout << "\tconst double " << constname << "=" << MyGspn->RealConstant[constname] << endl;
     576             : 
     577             :                     }
     578             :                 }
     579             : 
     580          22 :             t2 = findbranch(it, "constants/extConsts/");
     581          22 :             if (t2 != it.end())
     582           0 :                 for (treeSI it2 = (t2.begin()); it2 != (t2.end()); ++it2) {
     583           0 :                     if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     584           0 :                     if (*it2 == "extConst") {
     585           0 :                         if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     586           0 :                         string constname = simplifyString((find(it2.begin(), it2.end(), "name")).node->first_child->data);
     587           0 :                         MyGspn->ExternalConstant.emplace(constname);
     588           0 :                         if ((P.verbose - 3) > 1)cout << "\tconst External " << constname << endl;
     589             : 
     590             :                     }
     591             :                 }
     592          22 :             t2 = findbranch(it, "variables/clocks/");
     593          22 :             if (t2 != it.end())
     594           0 :                 for (treeSI it2 = (t2.begin()); it2 != (t2.end()); ++it2) {
     595           0 :                     if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     596           0 :                     if (*it2 == "clock") {
     597           0 :                         if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     598           0 :                         hybridVariable cl;
     599           0 :                         cl.name = simplifyString((find(it2.begin(), it2.end(), "name")).node->first_child->data);
     600           0 :                         cl.initialValue = "0";
     601           0 :                         cl.type = CV_CLOCK;
     602           0 :                         MyGspn->hybridVars.push_back(cl);
     603           0 :                         if ((P.verbose - 3) > 1)cout << "\tclock " << cl.name << endl;
     604             : 
     605             :                     }
     606             :                 }
     607          22 :             t2 = findbranch(it, "variables/reals/");
     608          22 :             if (t2 != it.end())
     609           0 :                 for (treeSI it2 = (t2.begin()); it2 != (t2.end()); ++it2) {
     610           0 :                     if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     611           0 :                     if (*it2 == "real") {
     612           0 :                         if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     613           0 :                         hybridVariable cl;
     614           0 :                         cl.name = simplifyString((find(it2.begin(), it2.end(), "name")).node->first_child->data);
     615           0 :                         cl.initialValue = simplifyString(*((find(it2.begin(), it2.end(), "value").begin())));
     616           0 :                         cl.type = CV_REAL;
     617           0 :                         MyGspn->hybridVars.push_back(cl);
     618           0 :                         if ((P.verbose - 3) > 1)cout << "\treal " << cl.name << endl;
     619             : 
     620             :                     }
     621             :                 }
     622             : 
     623          22 :             t2 = findbranch(it, "variables/ints/");
     624          22 :             if (t2 != it.end())
     625           0 :                 for (treeSI it2 = (t2.begin()); it2 != (t2.end()); ++it2) {
     626           0 :                     if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     627           0 :                     if (*it2 == "int") {
     628           0 :                         if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ":" << endl;
     629           0 :                         hybridVariable cl;
     630           0 :                         cl.name = simplifyString((find(it2.begin(), it2.end(), "name")).node->first_child->data);
     631           0 :                         cl.initialValue = simplifyString(*((find(it2.begin(), it2.end(), "value").begin())));
     632           0 :                         cl.type = CV_INT;
     633           0 :                         MyGspn->hybridVars.push_back(cl);
     634           0 :                         if ((P.verbose - 3) > 1)cout << "\tint " << cl.name << endl;
     635             : 
     636             :                     }
     637             :                 }
     638             : 
     639          62 :             for (t2 = it.begin(); t2 != it.end(); ++t2) {
     640          40 :                 if ((P.verbose - 3) > 1)cout << endl << *t2 << ": " << endl;
     641          40 :                 if (*t2 == "classDeclaration") {
     642          26 :                     colorClass cc;
     643          13 :                     cc.type = ColorClassType::Asymmetric;
     644          52 :                     for (treeSI it2 = (t2.begin()); it2 != (t2.end()); ++it2) {
     645          39 :                         if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ": ";
     646          39 :                         if (*it2 == "name") {
     647          13 :                             cc.name = simplifyString(*(it2.begin()));
     648          13 :                             if ((P.verbose - 3) > 1)cout << *(it2.begin());
     649             :                         }
     650          39 :                         if (*it2 == "classType") {
     651          13 :                             treeSI tclasstypeenum = find(it2.begin(), it2.end(), "classEnum");
     652          13 :                             if (tclasstypeenum != it2.end())
     653         276 :                                 for (treeSI it3 = (tclasstypeenum.begin());
     654         184 :                                      it3 != (tclasstypeenum.end()); ++it3) {
     655         172 :                                     string col = simplifyString(*(it3.begin()));
     656          86 :                                     if ((P.verbose - 3) > 1)cout << "\t\t\t" << col << endl;
     657          86 :                                     cc.colors.push_back(color(col, cc.colors.size(), MyGspn->colClasses.size()));
     658             :                                 }
     659             : 
     660          13 :                             tclasstypeenum = find(it2.begin(), it2.end(), "classIntInterval");
     661          13 :                             if (tclasstypeenum != it2.end()) {
     662             :                                 int low, high;
     663           7 :                                 treeSI intBound = find(tclasstypeenum.begin(), tclasstypeenum.end(), "lowerBound");
     664           7 :                                 low = eval_intFormula(intBound.begin());
     665           7 :                                 intBound = find(tclasstypeenum.begin(), tclasstypeenum.end(), "higherBound");
     666           7 :                                 high = eval_intFormula(intBound.begin());
     667             : 
     668           7 :                                 cc.intIntervalName = cc.name+"_IC_";
     669          55 :                                 for (int i = low; i <= high; i++) {
     670          96 :                                     stringstream ss;
     671          48 :                                     ss << cc.name << "_IC_" << i;
     672          48 :                                     cc.colors.push_back(color(ss.str(), cc.colors.size(), MyGspn->colClasses.size()));
     673             :                                 }
     674             : 
     675             :                             }
     676          13 :                             tclasstypeenum = find(it2.begin(), it2.end(), "classReal");
     677          13 :                             if (tclasstypeenum != it2.end()) {
     678           0 :                                 cc.type = ColorClassType::Continuous;
     679           0 :                                 cc.colors.push_back(color("Dummy_Real_Color", cc.colors.size(), MyGspn->colClasses.size()));
     680             :                             }
     681             : 
     682             :                         }
     683          39 :                         if (*it2 == "staticSubclass") {
     684           0 :                             colorStaticSubclass css;
     685           0 :                             for (treeSI it3 = it2.begin(); it3 != it2.end(); ++it3){
     686           0 :                                 if(*it3=="name"){
     687           0 :                                     css.name = *(it3.begin());
     688             :                                 }else {
     689           0 :                                     auto col = simplifyString(*(it3.begin()));
     690           0 :                                     auto colit = find_if(cc.colors.begin(),cc.colors.end(), [&](color c) {return (c.name == col);});
     691           0 :                                     if(colit != cc.colors.end())css.colors.push_back(*colit);
     692             :                                     //css.colors.push_back();
     693             :                                 }
     694             :                             }
     695           0 :                             css.id = cc.staticSubclasses.size();
     696           0 :                             cc.staticSubclasses.push_back(css);
     697             :                         }
     698          39 :                         if (*it2 == "circular") {
     699          13 :                             if (simplifyString(*(it2.begin())) == "true")
     700           5 :                                 cc.type = ColorClassType::Cyclic;
     701          13 :                             if ((P.verbose - 3) > 1)cout << *(it2.begin());
     702             :                         }
     703          39 :                         if (*it2 == "continuous") {
     704           0 :                             if (simplifyString(*(it2.begin())) == "true")
     705           0 :                                 cc.type = ColorClassType::Continuous;
     706           0 :                                 if ((P.verbose - 3) > 1)cout << *(it2.begin());
     707             :                         }
     708             :                     }
     709          26 :                     colorDomain cd;
     710          13 :                     cd.isBounded=true;
     711          13 :                     if(cc.type == ColorClassType::Continuous)cd.isBounded=false;
     712          13 :                     cd.name = cc.name;
     713          13 :                     cd.colorClassIndex.push_back(MyGspn->colClasses.size());
     714          13 :                     MyGspn->colClasses.push_back(cc);
     715          13 :                     MyGspn->colDoms.push_back(cd);
     716             :                 }
     717             : 
     718          40 :                 if (*t2 == "domainDeclaration") {
     719           2 :                     colorDomain cd;
     720           1 :                     cd.isBounded =true;
     721           3 :                     for (treeSI it2 = (t2.begin()); it2 != (t2.end()); ++it2) {
     722           2 :                         if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ": ";
     723           2 :                         if (*it2 == "name") {
     724           1 :                             cd.name = simplifyString(*(it2.begin()));
     725           1 :                             if ((P.verbose - 3) > 1)cout << *(it2.begin());
     726             :                         }
     727           2 :                         if (*it2 == "domainType") {
     728           1 :                             treeSI tclasstypeenum = find(it2.begin(), it2.end(), "cartesianProduct");
     729           1 :                             if (tclasstypeenum != it2.end())
     730           9 :                                 for (treeSI it3 = (tclasstypeenum.begin());
     731           6 :                                      it3 != (tclasstypeenum.end()); ++it3) {
     732           4 :                                     string colclass = simplifyString(*(it3.begin()));
     733           2 :                                     if ((P.verbose - 3) > 1)cout << endl << "\t\t\t" << colclass;
     734           2 :                                     size_t colorc = 0;
     735           5 :                                     for (colorc = 0; colorc < MyGspn->colClasses.size() &&
     736           3 :                                          MyGspn->colClasses[colorc].name != colclass; colorc++);
     737           2 :                                     if (colorc == MyGspn->colClasses.size())
     738           0 :                                         cerr << "Unknown classe '" << colclass << "'" << endl;
     739             :                                     else {
     740           2 :                                         if( MyGspn->colClasses[colorc].type == ColorClassType::Continuous)cd.isBounded=false;
     741           2 :                                         cd.colorClassIndex.push_back(colorc);
     742             :                                     }
     743             :                                 }
     744             :                         }
     745             :                     }
     746           1 :                     MyGspn->colDoms.push_back(cd);
     747             :                 }
     748          40 :                 if (*t2 == "variableDeclaration") {
     749          26 :                     colorVariable cv;
     750          39 :                     for (treeSI it2 = (t2.begin()); it2 != (t2.end()); ++it2) {
     751          26 :                         if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ": ";
     752          26 :                         if (*it2 == "name") {
     753          13 :                             cv.name = simplifyString(*(it2.begin()));
     754          13 :                             if ((P.verbose - 3) > 1)cout << *(it2.begin());
     755             :                         }
     756          26 :                         if (*it2 == "type") {
     757          26 :                             string colclass = simplifyString(*(it2.begin()));
     758          13 :                             if ((P.verbose - 3) > 1)cout << "\t\t" << colclass << endl;
     759             :                             ;
     760          13 :                             size_t colorc = 0;
     761          40 :                             for (colorc = 0; colorc < MyGspn->colDoms.size() &&
     762          27 :                                  MyGspn->colDoms[colorc].name != colclass; colorc++);
     763          13 :                             if (colorc == MyGspn->colDoms.size())
     764           0 :                                 cerr << "Unknown Domaine '" << colclass << "'" << endl;
     765          13 :                             else cv.type = colorc;
     766             : 
     767             :                         }
     768             :                     }
     769          13 :                     MyGspn->colVars.push_back(cv);
     770             :                 }
     771             : 
     772          40 :                 if (*t2 == "UserDefineDistribution" || *t2 == "UserDefineDistributionPoly") {
     773           0 :                     userDefineDistribution dist;
     774           0 :                     dist.lowerBound = "0";
     775           0 :                     dist.upperBound = "0";
     776           0 :                     for (treeSI it2 = (t2.begin()); it2 != (t2.end()); ++it2) {
     777           0 :                         string val = simplifyString(*(it2.begin()));
     778           0 :                         if ((P.verbose - 3) > 1)cout << "\t" << *it2 << ": " << val << endl;
     779           0 :                         if(*it2=="polyDataFile"){
     780           0 :                             dist.polyfile = val;
     781             :                         }
     782           0 :                         if (*it2 == "name") {
     783           0 :                             dist.name = val;                        }
     784           0 :                         if (*it2 == "var") {
     785           0 :                             dist.var = val;
     786             :                         }
     787           0 :                         if (*it2 == "cdf") {
     788           0 :                             dist.cdf = val;
     789             :                         }
     790           0 :                         if (*it2 == "norm") {
     791           0 :                             dist.norm = val;
     792             :                         }
     793           0 :                         if (*it2 == "pdf") {
     794           0 :                             dist.pdf = val;
     795             :                         }
     796           0 :                         if (*it2 == "nbParam") {
     797           0 :                             dist.nbparam = stol(val);
     798             :                         }
     799           0 :                         if (*it2 == "lowerBound") {
     800           0 :                             dist.lowerBound = val;
     801             :                         }
     802           0 :                         if (*it2 == "upperBound") {
     803           0 :                             dist.upperBound = val;
     804             :                         }
     805             :                     }
     806           0 :                     MyGspn->distribStruct.push_back(dist);
     807           0 :                     if ((P.verbose - 3) > 1)cout << dist << endl;
     808             :                 }
     809             :             }
     810             :         }
     811             :     }
     812             : }
     813             : 
     814        1338 : void MyModelHandler::on_read_node(const XmlString& id,
     815             :                                   const XmlString& nodeType,
     816             :                                   const AttributeMap& attributes,
     817             :                                   const XmlStringList&) {
     818             :     // Read node of the graph. If the file is well formed it
     819             :     // contain only place and transition.
     820             : 
     821        1338 :     if ((P.verbose - 3) > 1)cout << "read node : " << id << ", " << nodeType << endl;
     822        1338 :     if (nodeType == "place") {
     823         460 :         if (MyGspn->nbpass == 1)return;
     824             : 
     825             :         // Read a Place:
     826             : 
     827         230 :         MyGspn->pl++;
     828         230 :         int id2 = atoi(id.c_str());
     829         230 :         IsPlace[id2] = true;
     830         230 :         Gml2Place[id2] = MyGspn->pl - 1;
     831         460 :         place p;
     832         230 :         p.name = id;
     833         230 :         p.id = MyGspn->placeStruct.size();
     834         230 :         bool hasAll = false;
     835             : 
     836         821 :         for (AttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it) {
     837         591 :             treeSI it2 = it->second.begin();
     838         591 :             if (*it2 == "marking") {
     839         460 :                 vector<coloredToken> inMark;
     840         230 :                 bool markdep = false;
     841             : 
     842         460 :                 for (treeSI ittok = it2.begin(); ittok != it2.end(); ++ittok) {
     843         230 :                     if (*ittok == "token") {
     844          30 :                         coloredToken tok;
     845          15 :                         bool markingdependant = false;
     846          30 :                         set<size_t> varset;
     847          15 :                         eval_tokenProfileArc(tok, markingdependant, varset, ittok,true);
     848          15 :                         inMark.push_back(tok);
     849          15 :                         hasAll |= tok.hasAll;
     850             :                     }
     851             :                 }
     852         230 :                 if (markdep) {
     853           0 :                     throw GrmlInputException("Marking can not be marking dependant");
     854             :                 }
     855         460 :                 string st;
     856         230 :                 if (inMark.empty()) {
     857         215 :                     int mark = 0;
     858         215 :                     mark = eval_intFormula(it2.begin());
     859         215 :                     if(mark !=0)inMark.push_back(coloredToken(mark));
     860         215 :                     st.append(to_string(mark));
     861             :                 }
     862             : 
     863         230 :                 if ((P.verbose - 3) > 1)cout << "\tmarking:" << st << endl;
     864         230 :                 p.Marking=st;
     865         230 :                 p.initMarking=inMark;
     866             : 
     867         361 :             } else if (*it2 == "name") {
     868         460 :                 string Plname = simplifyString(*(it2.begin()));
     869         230 :                 if ((P.verbose - 3) > 1)cout << "\tname:" << Plname << endl;
     870         230 :                 p.name = Plname;
     871         230 :                 if (MyGspn->PlacesId.count(Plname) > 0) {
     872           0 :                     throw GrmlInputException("Two places with the name: "+ Plname);
     873             :                 }
     874         230 :                 MyGspn->PlacesId[Plname] = MyGspn->pl - 1;
     875             : 
     876         131 :             } else if ((*(it->second.begin())) == "domain") {
     877         262 :                 string Pldomain = simplifyString(*(it2.begin().begin()));
     878         131 :                 if ((P.verbose - 3) > 1)cout << "\tdomain:" << Pldomain << endl;
     879         131 :                 size_t colord = 0;
     880         386 :                 for (colord = 0; colord < MyGspn->colDoms.size() &&
     881         255 :                      MyGspn->colDoms[colord].name != Pldomain; colord++);
     882         131 :                 if (colord == MyGspn->colDoms.size())
     883           0 :                     cerr << "Unknown Domain '" << Pldomain << "'" << endl;
     884             :                 else {
     885         131 :                     p.colorDom = colord;
     886             :                 }
     887             : 
     888           0 :             } else if (*it2 == "bound") {
     889             : 
     890           0 :             } else throw GrmlInputException("Unexpected:" + *it2);
     891             : 
     892             :         }
     893         318 :         for(auto &cd: p.initMarking){
     894          88 :             cd.coldom = make_shared<colorDomain>( MyGspn->colDoms[p.colorDom]);
     895             :         }
     896         230 :         if(P.verbose>3)cout << p;
     897         230 :         if(!MyGspn->colDoms[p.colorDom].isBounded && hasAll ){
     898           0 :             throw GrmlInputException("Error, using ALL construct on an unbounded domain.");
     899             :         }
     900             : 
     901         230 :         MyGspn->placeStruct.push_back(p);
     902             : 
     903             :     } else {
     904             : 
     905         878 :         if (nodeType == "transition") {
     906         878 :             if (MyGspn->nbpass == 0)return;
     907             : 
     908             :             //Read a transition:
     909         439 :             MyGspn->tr++;
     910         439 :             int id2 = atoi(id.c_str());
     911         439 :             IsPlace[id2] = false;
     912         439 :             Gml2Trans[id2] = MyGspn->tr - 1;
     913             : 
     914         878 :             transition trans;
     915         439 :             trans.id = MyGspn->transitionStruct.size();
     916         439 :             trans.name = id;
     917         439 :             trans.type = Timed;
     918         439 :             trans.priority = expr(1);
     919         439 :             trans.weight = expr(1.0);
     920         439 :             trans.singleService = true;
     921         439 :             trans.markingDependant = false;
     922         439 :             trans.ageMemory = false;
     923         439 :             trans.nbServers = 1;
     924             : 
     925        1635 :             for (AttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it) {
     926        1196 :                 if ((*(it->second.begin())) == "name") {
     927         878 :                     string Trname = simplifyString(*(++(it->second.begin())));
     928         439 :                     if ((P.verbose - 3) > 1)cout << "\tname:" << Trname << endl;
     929         439 :                     MyGspn->TransList.insert(Trname);
     930         439 :                     trans.name = Trname;
     931         439 :                     if (MyGspn->TransId.count(Trname) > 0) {
     932           0 :                         throw GrmlInputException("Two transitions with the name: "+ Trname );
     933             :                     }
     934         439 :                     MyGspn->TransId[Trname] = MyGspn->tr - 1;
     935         757 :                 } else if ((*(it->second.begin())) == "guard") {
     936         105 :                     trans.guard = eval_guard(it->second.begin().begin());
     937             :                     //if(trans.guard == "")trans.guard = "true";
     938         652 :                 } else if ((*(it->second.begin())) == "distribution") {
     939         439 :                     if ((P.verbose - 3) > 1)cout << "\tdistribution:" << endl;
     940        1319 :                     for (treeSI it2 = (it->second.begin()).begin(); it2 != (it->second.begin()).end(); ++it2) {
     941         880 :                         if ((P.verbose - 3) > 1)cout << "\t" << (*it2) << ":" << endl;
     942         880 :                         if (*it2 == "type") {
     943         878 :                             string Trtype = simplifyString(*(it2.begin()));
     944         439 :                             if (Trtype == "IMDT")trans.type = unTimed;
     945         439 :                             trans.dist.name = Trtype;
     946         439 :                             if ((P.verbose - 3) > 1)cout << "\t\t" << Trtype << endl;
     947         441 :                         } else if (*it2 == "param") {
     948             : 
     949             :                             //int number = 0;
     950        1250 :                             for (treeSI it3 = it2.begin(); it3 != it2.end(); ++it3) {
     951             :                                 //string* leaf = simplifyString(*(it3.begin()));
     952         809 :                                 if (*it3 == "number") {
     953             :                                     //number = atoi((*leaf).c_str());
     954         441 :                                 } else if (*it3 == "expr") {
     955         882 :                                     expr pe;
     956         441 :                                     if(trans.dist.Param.size()==0 && trans.dist.name == "USERDEFINE" ){
     957           0 :                                         string distname = simplifyString(*(it3.begin()));
     958           0 :                                         auto did = find_if(MyGspn->distribStruct.begin(), MyGspn->distribStruct.end(), [&](userDefineDistribution &d){
     959           0 :                                             return (d.name == distname);});
     960           0 :                                         if( did != MyGspn->distribStruct.end()){
     961           0 :                                             pe = expr((int)(did - MyGspn->distribStruct.begin()));
     962             :                                         } else {
     963           0 :                                             pe = eval_expr(it3.begin());
     964           0 :                                             trans.markingDependant |= pe.is_markDep();
     965             :                                             //cerr << "Unkown distribution " << distname << endl;
     966             :                                             //throw gmlioexc;
     967             :                                         }
     968             :                                     }else {
     969         441 :                                         pe = eval_expr(it3.begin());
     970         441 :                                         trans.markingDependant |= pe.is_markDep();
     971             :                                     }
     972         441 :                                     trans.dist.Param.push_back(pe);
     973         441 :                                     if ((P.verbose - 3) > 1)cout << "\tDistrib Param:'" << setw(0) << pe << "'" << endl;
     974           0 :                                 } else throw GrmlInputException("Unexpected: "+ *it3);
     975             :                             }
     976           0 :                         } else throw GrmlInputException("Unexpected: "+ *it2);
     977             :                     }
     978             : 
     979         213 :                 } else if ((*(it->second.begin())) == "service") {
     980          67 :                     if ((*(++(it->second.begin()))) == "expr") {
     981          67 :                         const auto nserv = eval_intFormula((++(it->second.begin())).begin());
     982          67 :                         if (nserv == 1) {
     983          67 :                             trans.nbServers = 1;
     984             :                         } else {
     985           0 :                             trans.singleService = false;
     986           0 :                             trans.nbServers = nserv;
     987             :                         }
     988           0 :                     } else cout << " Fail to parse GML: transition,service" << endl;
     989             : 
     990             :                     /*if ((*(++(it->second.begin()))) == "Infinite") {
     991             :                      singleservice=false;
     992             :                      nbserver=INT_MAX;
     993             :                      } else {
     994             :                      int nbsrv = atoi((*(++(it->second.begin()))).c_str());
     995             :                      if (nbsrv!=1) {
     996             :                      singleservice=false;
     997             :                      nbserver=nbserver;
     998             :                      }
     999             :                      }*/
    1000         146 :                 } else if ((*(it->second.begin())) == "weight") {
    1001          79 :                     if ((*(++(it->second.begin()))) == "expr") {
    1002         158 :                         expr e = eval_expr((++(it->second.begin())).begin());
    1003          79 :                         if (!e.is_markDep()) {
    1004          79 :                             trans.weight = e;
    1005             :                         } else {
    1006           0 :                             cout << "Weight is not marking dependent " << endl;
    1007             :                         }
    1008           0 :                     } else cout << " Fail to parse GML: transition,weight" << endl;
    1009             : 
    1010             : 
    1011          67 :                 } else if ((*(it->second.begin())) == "priority") {
    1012          67 :                     if ((*(++(it->second.begin()))) == "expr") {
    1013         134 :                         expr e = eval_expr((++(it->second.begin())).begin());
    1014          67 :                         if (!e.is_markDep()) {
    1015          67 :                             trans.priority = e;
    1016             :                         } else {
    1017           0 :                             cout << "Priority is not marking dependent " << endl;
    1018             :                         }
    1019           0 :                     } else cout << " Fail to parse GML: transition,priority" << endl;
    1020             : 
    1021           0 :                 } else if ((*(it->second.begin())) == "ageMemory") {
    1022           0 :                     trans.ageMemory = true;
    1023           0 :                 } else if ((*(it->second.begin())) == "update") {
    1024           0 :                     trans.update = simplifyString(*(++(it->second.begin())));
    1025             : 
    1026           0 :                 } else cout << "fail to parse gml transition attribute" << endl;
    1027             : 
    1028             :             }
    1029             : 
    1030         439 :             if (trans.dist.name == "") {
    1031           0 :                 trans.type = Timed;
    1032           0 :                 trans.dist.name = "EXPONENTIAL";
    1033           0 :                 trans.dist.Param.push_back(expr(1.0));
    1034           0 :                 if ((P.verbose - 3) >= 0) {
    1035           0 :                     cout << "[Warning] Transition " << trans.name;
    1036           0 :                     cout << " have no distribution.";
    1037           0 :                     cout << " Assigne exponential with parameter 1" << endl;
    1038             :                 }
    1039             :             }
    1040             : 
    1041         439 :             if(P.verbose>3)cout << trans ;
    1042         439 :             MyGspn->transitionStruct.push_back(trans);
    1043           0 :         } else cout << "fail to parse gml" << endl;
    1044             :     }
    1045             : 
    1046             : 
    1047             :     /*for(AttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it) {
    1048             :      print_tree(it->second, it->second.begin(), it->second.end());
    1049             :      }
    1050             :      for(XmlStringList::const_iterator it = references.begin(); it != references.end(); ++it) {
    1051             :      cout << "    ref => " << *it << endl;
    1052             :      }*/
    1053             : }
    1054             : 
    1055        2636 : void MyModelHandler::on_read_arc(const XmlString& id,
    1056             :                                  const XmlString& arcType,
    1057             :                                  const XmlString& source,
    1058             :                                  const XmlString& target,
    1059             :                                  const AttributeMap& attributes,
    1060             :                                  const XmlStringList&) {
    1061        2636 :     if (MyGspn->nbpass == 0)return;
    1062             : 
    1063        1318 :     if (ParsePl) {
    1064          23 :         ParsePl = false;
    1065             : 
    1066          23 :         if (P.RareEvent) {
    1067           1 :             if (P.BoundedContinuous || P.BoundedRE > 0) {
    1068             :                 //add a transition for self-loop due to uniformization
    1069           0 :                 transition trans(MyGspn->transitionStruct.size(), "selfloop", expr(0.0), true);
    1070           0 :                 MyGspn->transitionStruct.push_back(trans);
    1071             : 
    1072           0 :                 MyGspn->TransId["selfloop"] = MyGspn->tr;
    1073           0 :                 MyGspn->TransList.insert(trans.name);
    1074           0 :                 MyGspn->tr++;
    1075             :             }
    1076             : 
    1077             :             //Add a place
    1078           2 :             place p;
    1079           1 :             p.Marking = expr(0);
    1080           2 :             coloredToken ctok(0);
    1081           1 :             p.initMarking=vector<coloredToken>(1, ctok);
    1082             : 
    1083           2 :             string Plname = "Puit";
    1084           1 :             p.name = Plname;
    1085           1 :             p.id = MyGspn->pl;
    1086           1 :             MyGspn->placeStruct.push_back(p);
    1087           1 :             MyGspn->PlacesId[Plname] = MyGspn->pl;
    1088           1 :             MyGspn->pl++;
    1089             : 
    1090             : 
    1091             :             //Add a transition
    1092           2 :             transition trans(MyGspn->transitionStruct.size(), "Puittrans", expr(0.0), true);
    1093           1 :             MyGspn->transitionStruct.push_back(trans);
    1094             : 
    1095           1 :             MyGspn->TransList.insert(trans.name);
    1096           1 :             MyGspn->tr++;
    1097             :         }
    1098             :     }
    1099             : 
    1100        1318 :     if ((P.verbose - 3) > 1)cout << "read arc : " << id << ", " << arcType << ", " << source << " -> " << target << endl;
    1101        2636 :     expr valuation;
    1102        2636 :     vector<coloredToken> toklist;
    1103             :     //cout << arcType << endl;
    1104        1318 :     int sourceGML = atoi(source.c_str());
    1105        2636 :     for (AttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it) {
    1106        1318 :         treeSI it2 = it->second.begin();
    1107        1318 :         if (*it2 == "valuation") {
    1108        1318 :             bool markingdependant = false;
    1109        2641 :             for (treeSI it3 = it2.begin(); it3 != it2.end(); ++it3) {
    1110        1323 :                 if (*it3 == "expr") {
    1111        1073 :                     valuation = eval_expr(it3.begin());
    1112             :                     /*stringstream ss;
    1113             :                      ss << e;
    1114             :                      valuation = ss.str();*/
    1115        1073 :                     markingdependant |= valuation.is_markDep();
    1116         250 :                 } else if (*it3 == "token") {
    1117         500 :                     coloredToken tokenType;
    1118         250 :                     tokenType.hasAll = false;
    1119         250 :                     if (IsPlace[sourceGML]) {
    1120         121 :                         eval_tokenProfileArc(tokenType, markingdependant, MyGspn->transitionStruct[Gml2Trans[atoi(target.c_str())]].varDomain, it3,false);
    1121             :                     } else {
    1122         129 :                         eval_tokenProfileArc(tokenType, markingdependant, MyGspn->transitionStruct[Gml2Trans[atoi(source.c_str())]].varDomain, it3,false);
    1123             :                     }
    1124             : 
    1125         250 :                     toklist.push_back(tokenType);
    1126           0 :                 } else cout << " Fail to parse GML: arc,valuation" << endl;
    1127             :             }
    1128        1318 :             if (toklist.empty()) {
    1129        1073 :                 toklist.push_back(coloredToken(valuation));
    1130             :             } else {
    1131         245 :                 valuation = expr(ColouredPlaceHolder, "");
    1132             :             }
    1133           0 :         } else cout << "fail to parse gml" << endl;
    1134             :     }
    1135             : 
    1136        1318 :     if (IsPlace[sourceGML]) {
    1137         756 :         let t = Gml2Trans[atoi(target.c_str())];
    1138         756 :         let p = Gml2Place[sourceGML];
    1139         756 :         if (arcType == "inhibitorarc") {
    1140           4 :             MyGspn->inhibArcsStruct.insert(make_pair<pair<size_t, size_t>, arc>(MyGspn->arckey(t, p), arc(valuation,toklist)));
    1141             :         } else {
    1142         752 :             MyGspn->inArcsStruct.insert(make_pair<pair<size_t, size_t>, arc>(MyGspn->arckey(t, p), arc(valuation,toklist)));
    1143             :         }
    1144             :     } else {
    1145         562 :         MyGspn->outArcsStruct.insert(make_pair<pair<size_t, size_t>, arc>(MyGspn->arckey(Gml2Trans[sourceGML], Gml2Place[atoi(target.c_str())]), arc(valuation,toklist)));
    1146             : 
    1147             :     }
    1148             : 
    1149         105 : }

Generated by: LCOV version 1.13