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, "&", "&");
76 4257 : replace_all(str2, "<", "<");
77 4257 : replace_all(str2, ">", ">");
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 : }
|