LCOV - code coverage report
Current view: top level - builds/barbot/Cosmos/src/ModelGenerator/GspnParser - Gspn-Writer.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 684 992 69.0 %
Date: 2021-06-16 15:43:28 Functions: 33 38 86.8 %

          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-Writer.cpp created by Benoit Barbot on 14/01/14.                  *
      24             :  *******************************************************************************
      25             :  */
      26             : 
      27             : 
      28             : #include <algorithm>
      29             : #include <sstream>
      30             : #include <limits.h>
      31             : 
      32             : #include "Gspn-Writer.hpp"
      33             : #include "../casesWriter.hpp"
      34             : 
      35             : 
      36             : using namespace std;
      37             : 
      38          33 : Gspn_Writer::Gspn_Writer(GspnType& mgspn,const parameters& Q):MyGspn(mgspn),P(Q){
      39          33 :     markingSize = 0;
      40         320 :     for( let p : MyGspn.placeStruct){
      41         287 :         size_t t =1;
      42         398 :         for ( let cd : MyGspn.colDoms[p.colorDom].colorClassIndex)
      43         111 :             t*= MyGspn.colClasses[cd].size();
      44         287 :         markingSize +=t;
      45             :     }
      46             : 
      47          33 :     if(P.lightSimulator){
      48           0 :         trId = "TR_PL_ID t";
      49             :     }
      50          33 : }
      51             : 
      52             : 
      53             : 
      54         198 : void Gspn_Writer::writeFunT(ostream &f,
      55             :                             const std::string &rtype,
      56             :                             const std::string &name,
      57             :                             const std::string &extraArg,
      58             :                             function<void(unsigned int,stringstream &)> ft,
      59             :                             const std::string init = "")const {
      60         198 :     f << rtype <<" "<< objName << name << trId << extraArg << "{" << endl;
      61         198 :     f << init << endl;
      62         396 :     casesHandler weightcases("t");
      63        3258 :     for (size_t t = 0; t < MyGspn.tr ; t++){
      64        6120 :         stringstream newcase;
      65             :         //newcase << "\t\t" <<
      66        3060 :         ft(t,newcase);
      67             :         //<< endl;
      68        3060 :         weightcases.addCase(t, newcase.str(),MyGspn.transitionStruct[t].name);
      69             :     }
      70         198 :     weightcases.writeCases(f);
      71         198 :     f << "}\n" << endl;
      72         198 : }
      73             : 
      74             : 
      75             : // Precompute effect of transitions over other transitions
      76          33 : void Gspn_Writer::EnabledDisabledTr(vector< set<int> > &PossiblyEnabled,
      77             :                                     vector< set<int> > &PossiblyDisabled,
      78             :                                     vector< set<int> > &FreeMarkDepT)const {
      79             : 
      80         543 :     for (size_t t1 = 0; t1 < MyGspn.tr; t1++) {
      81        1020 :         const auto trans1 = MyGspn.transitionStruct[t1];
      82        1020 :         set<int> S;
      83        1020 :         set<int> Sinhib;
      84        1020 :         set<int> INt1;
      85        4014 :         for(auto inarc= MyGspn.inArcsStruct.lower_bound(make_pair(t1, 0));
      86        4014 :             inarc != MyGspn.inArcsStruct.end() && inarc->first.first==t1; ++inarc )
      87         828 :             if(!inarc->second.isEmpty)INt1.insert(inarc->first.second);
      88             : 
      89       70404 :         for (size_t t2 = 0; t2 < MyGspn.tr; t2++){
      90      139788 :             const auto trans2 = MyGspn.transitionStruct[t2];
      91       69894 :             if (t1 != t2) {
      92       69384 :                 auto size = INt1.size();
      93      138768 :                 auto INt1t2 = INt1;
      94             : 
      95      552684 :                 for(auto inarc= MyGspn.inArcsStruct.lower_bound(make_pair(t2, 0));
      96      552684 :                     inarc != MyGspn.inArcsStruct.end() && inarc->first.first==t2; ++inarc){
      97             :                     //if(trans2.dist.name=="SYNC")Sinhib.insert(t2);
      98      126500 :                     if( !inarc->second.isEmpty){
      99      126500 :                         INt1t2.insert(inarc->first.second);
     100      126500 :                         if (size == INt1t2.size()) {
     101       11656 :                             S.insert(t2);
     102       11656 :                             if(trans2.dist.name=="SYNC")Sinhib.insert(t2);
     103       11656 :                             break;
     104      114844 :                         } else size = INt1t2.size();
     105             :                     }
     106             :                 }
     107             : 
     108       69384 :                 size = INt1.size();
     109      138768 :                 set<int> INt1t2Inhib = INt1;
     110      208368 :                 for(auto inhibarc= MyGspn.inhibArcsStruct.lower_bound(make_pair(t2, 0));
     111      208368 :                     inhibarc != MyGspn.inhibArcsStruct.end() && inhibarc->first.first==t2; ++inhibarc)
     112          80 :                     if(!inhibarc->second.isEmpty){
     113          80 :                         INt1t2Inhib.insert(inhibarc->first.second );
     114          80 :                         if (size == INt1t2Inhib.size()) {
     115           8 :                             Sinhib.insert(t2);
     116           8 :                             break;
     117          72 :                         } else size = INt1t2Inhib.size();
     118             :                     }
     119             :             }
     120             :         }
     121             : 
     122         510 :         PossiblyDisabled.push_back(S);
     123         510 :         PossiblyEnabled.push_back(Sinhib);
     124             :     }
     125         543 :     for (size_t t1 = 0; t1 < MyGspn.tr; t1++) {
     126        1020 :         const auto trans1 = MyGspn.transitionStruct[t1];
     127        1020 :         auto S = PossiblyEnabled[t1];
     128        1020 :         auto Sinhib = PossiblyDisabled[t1];
     129        1020 :         set<int> OUTt1;
     130        3465 :         for(auto outarc= MyGspn.outArcsStruct.lower_bound(make_pair(t1, 0));
     131        3465 :             outarc != MyGspn.outArcsStruct.end() && outarc->first.first==t1; ++outarc )
     132         645 :             if(!outarc->second.isEmpty)OUTt1.insert(outarc->first.second);
     133             : 
     134       70404 :         for (size_t t2 = 0; t2 < MyGspn.tr; t2++)
     135       69894 :             if (t1 != t2) {
     136       69384 :                 size_t size = OUTt1.size();
     137      138768 :                 set<int> OUTt1INt2 = OUTt1;
     138             : 
     139      577746 :                 for(auto inarc= MyGspn.inArcsStruct.lower_bound(make_pair(t2, 0));
     140      577746 :                     inarc != MyGspn.inArcsStruct.end() && inarc->first.first==t2; ++inarc){
     141             :                     //if(trans1.dist.name== "SYNC")S.insert(t2);
     142      129602 :                     if( !inarc->second.isEmpty){
     143      129602 :                         OUTt1INt2.insert(inarc->first.second);
     144      129602 :                         if (size == OUTt1INt2.size()) {
     145        6404 :                             S.insert(t2);
     146        6404 :                             break;
     147      123198 :                         } else size = OUTt1INt2.size();
     148             :                     }
     149             :                 }
     150       69384 :                 size = OUTt1.size();
     151      138768 :                 set<int> OUTt1t2Inhib = OUTt1;
     152      208380 :                 for(auto inhibarc= MyGspn.inhibArcsStruct.lower_bound(make_pair(t2, 0));
     153      208380 :                     inhibarc != MyGspn.inhibArcsStruct.end() && inhibarc->first.first==t2; ++inhibarc)
     154          80 :                     if(!inhibarc->second.isEmpty){
     155          80 :                         OUTt1t2Inhib.insert(inhibarc->first.second );
     156          80 :                         if (size == OUTt1t2Inhib.size()) {
     157           4 :                             Sinhib.insert(t2);
     158           4 :                             break;
     159          76 :                         } else size = OUTt1t2Inhib.size();
     160             :                     }
     161             :             }
     162         510 :         PossiblyEnabled[t1] = S;
     163         510 :         PossiblyDisabled[t1] = Sinhib;
     164             :     }
     165             : 
     166             :     // Prune with equal arcs
     167         543 :     for (size_t t1 = 0; t1 < MyGspn.tr; t1++) {
     168         510 :         auto &S = PossiblyEnabled[t1];
     169         510 :         auto &Sinhib = PossiblyDisabled[t1];
     170        1020 :         set<int> OUTt1Read;
     171        1020 :         set<int> OUTt1;
     172        3465 :         for(auto outarc= MyGspn.outArcsStruct.lower_bound(make_pair(t1, 0));
     173        3465 :             outarc != MyGspn.outArcsStruct.end() && outarc->first.first==t1; ++outarc )
     174         645 :             if(!outarc->second.isEmpty){
     175         645 :                 OUTt1.insert(outarc->first.second); // insert out place
     176        1290 :                 const auto ina = MyGspn.access(MyGspn.inArcsStruct, t1, outarc->first.second);
     177        1290 :                 const auto inhiba = MyGspn.access(MyGspn.inhibArcsStruct, t1, outarc->first.second);
     178             :                 //Check whether this is an equal arc
     179        1935 :                 if( ina.exprVal.is_concrete() && inhiba.exprVal.is_concrete()
     180        1290 :                    && ina.exprVal.intVal == inhiba.exprVal.intVal -1)
     181           0 :                     OUTt1Read.insert(outarc->first.second);
     182             :             }
     183             : 
     184       70404 :         for (size_t t2 = 0; t2 < MyGspn.tr; t2++)
     185       69894 :             if (t1 != t2) {
     186             :                 //Check whether all input places are output places of t1 with equal arc
     187       69384 :                 int count=0;
     188       69384 :                 int count2=0;
     189      607116 :                 for(auto inarc= MyGspn.inArcsStruct.lower_bound(make_pair(t2, 0));
     190      607116 :                     inarc != MyGspn.inArcsStruct.end() && inarc->first.first==t2; ++inarc){
     191      132988 :                     count2 += OUTt1Read.count(inarc->first.second);
     192      132988 :                     if(OUTt1.count(inarc->first.second)>0 && OUTt1Read.count(inarc->first.second)==0)count++;
     193             :                 }
     194      208392 :                 for(auto inhibarc= MyGspn.inhibArcsStruct.lower_bound(make_pair(t2, 0));
     195      208392 :                     inhibarc != MyGspn.inhibArcsStruct.end() && inhibarc->first.first==t2; ++inhibarc){
     196          80 :                     count2 += OUTt1Read.count(inhibarc->first.second);
     197          80 :                     if(OUTt1.count(inhibarc->first.second)>0 && OUTt1Read.count(inhibarc->first.second)==0)count++;
     198             :                 }
     199       69384 :                 if(count>0)continue;//One input place is not an equal arc place.
     200       62976 :                 if(count2==0)continue;//No input place is an equal arc place.
     201             : 
     202           0 :                 for(auto inarc= MyGspn.inArcsStruct.lower_bound(make_pair(t2, 0));
     203           0 :                     inarc != MyGspn.inArcsStruct.end() && inarc->first.first==t2; ++inarc)
     204           0 :                     if(OUTt1Read.count(inarc->first.second)>0 && inarc->second.exprVal.is_concrete()){
     205           0 :                         if(!(inarc->second.exprVal.intVal<=MyGspn.access(MyGspn.outArcsStruct, t1, inarc->first.second).exprVal.intVal)){
     206           0 :                             S.erase(t2);
     207             :                         }
     208           0 :                         if(!(inarc->second.exprVal.intVal<=MyGspn.access(MyGspn.inArcsStruct, t1, inarc->first.second).exprVal.intVal)){
     209           0 :                             Sinhib.erase(t2);
     210             :                         }
     211             :                     }
     212           0 :                 for(auto inhibarc= MyGspn.inhibArcsStruct.lower_bound(make_pair(t2, 0));
     213           0 :                     inhibarc != MyGspn.inhibArcsStruct.end() && inhibarc->first.first==t2; ++inhibarc)
     214           0 :                     if(OUTt1Read.count(inhibarc->first.second)>0 && inhibarc->second.exprVal.is_concrete()){
     215           0 :                         if(!(inhibarc->second.exprVal.intVal > MyGspn.access(MyGspn.outArcsStruct, t1, inhibarc->first.second).exprVal.intVal)){
     216           0 :                             S.erase(t2);
     217             :                         }
     218           0 :                         if(!(inhibarc->second.exprVal.intVal > MyGspn.access(MyGspn.inArcsStruct, t1, inhibarc->first.second).exprVal.intVal)){
     219           0 :                             Sinhib.erase(t2);
     220             :                         }
     221             :                     }
     222             :             }
     223             :     }
     224             : 
     225          66 :     set<int> MarkDepT;
     226         543 :     for (size_t t = 0; t < MyGspn.tr; t++){
     227        1020 :         const auto tr1 = MyGspn.transitionStruct[t];
     228         510 :         if (tr1.markingDependant)MarkDepT.insert(t);
     229             :     }
     230             : 
     231         543 :     for (size_t t = 0; t < MyGspn.tr; t++) {
     232        1020 :         set<int> S;
     233        1464 :         for (const auto  &it : MarkDepT) {
     234        4512 :             if ((PossiblyEnabled[t].find(it) == PossiblyEnabled[t].end()) &&
     235        3558 :                 (PossiblyDisabled[t].find(it) == PossiblyDisabled[t].end()))
     236         828 :                 S.insert(it);
     237             :         }
     238         510 :         FreeMarkDepT.push_back(S);
     239             :     }
     240          33 : }
     241             : 
     242          99 : void Gspn_Writer::writeUpdateVect(ofstream &SpnF,const string &name,const vector< set<int> > &vect)const{
     243             :     //SpnF << "\t"<< name << " = vector< vector<int> >("<< vect.size() << ");"<< endl;
     244        1629 :     for (size_t t = 0; t < vect.size(); t++)
     245        1530 :         if(vect[t].size()>0){
     246        1782 :             const auto tabname = "PE_"+name+"_"+ to_string(t);
     247         891 :             if(P.lightSimulator){
     248           0 :                 SpnF << "static const TR_PL_ID " << tabname << "[" << 1+vect[t].size() <<"]"<<"= {";
     249         891 :             } else SpnF << "static const int " << tabname << "[" << 1+vect[t].size() <<"]"<<"= {";
     250       19791 :             for (set<int>::iterator it = vect[t].begin(); it != vect[t].end(); it++) {
     251             :                 //SpnF << "\tPossiblyEnabled[" << t << "].insert( " << *it << " );"<< endl;
     252       18900 :                 SpnF << "TR_" << MyGspn.transitionStruct[*it].name << "_RT, ";
     253             :             }
     254         891 :             SpnF << "-1 }; /* " << MyGspn.transitionStruct[t].name << "*/"<< endl;
     255             :             // << "\t"<< name <<"[" << t << "] = vector<int>("<<tabname<<","<< tabname<<"+"<< vect[t].size()<< ");" << endl;
     256             :             /*}else if(vect[t].size()>0)
     257             :              for (set<int>::iterator it = vect[t].begin(); it != vect[t].end(); it++)
     258             :              SpnF << "\t"<< name << "[" << t << "].push_back( " << *it << " );"<< endl;*/
     259             :         }
     260          99 :     if(P.lightSimulator){
     261           0 :         SpnF << "const TR_PL_ID* SPN::"<< name << "[] = {";
     262          99 :     } else SpnF << "const int* SPN::"<< name << "[] = {";
     263        1629 :     for (size_t t = 0; t < vect.size(); t++) {
     264        1530 :         if(t != 0)SpnF << ", ";
     265        1530 :         if(vect[t].size()>0){ SpnF << "PE_"<<name<<"_"<< t;
     266         639 :         } else SpnF << "EMPTY_array";
     267             :     }
     268          99 :     SpnF << "};"<< endl;
     269          99 :     SpnF << endl;
     270          99 : }
     271             : 
     272          33 : void Gspn_Writer::writeEnabledDisabled(ofstream &SpnF)const{
     273          66 :     vector< set<int> > PossiblyEnabled;
     274          66 :     vector< set<int> > PossiblyDisabled;
     275          66 :     vector< set<int> > FreeMarkDepT;
     276             : 
     277          33 :     EnabledDisabledTr(PossiblyEnabled,PossiblyDisabled,FreeMarkDepT);
     278             : 
     279          33 :     if(P.lightSimulator){
     280           0 :         SpnF << "static const TR_PL_ID EMPTY_array[1]={-1};" << endl;
     281          33 :     } else SpnF << "static const int EMPTY_array[1]={-1};" << endl;
     282          33 :     writeUpdateVect(SpnF, "PossiblyEnabled", PossiblyEnabled);
     283          33 :     writeUpdateVect(SpnF, "PossiblyDisabled", PossiblyDisabled);
     284          33 :     writeUpdateVect(SpnF, "FreeMarkDepT", FreeMarkDepT);
     285          33 : }
     286             : 
     287           1 : int Gspn_Writer::varMultiplier(size_t var)const{
     288           1 :     int acc = 1;
     289           1 :     for (vector<colorVariable>::const_iterator colvar = MyGspn.colVars.begin() ; colvar != MyGspn.colVars.end()&& colvar != (MyGspn.colVars.begin() + var); ++colvar) {
     290           0 :         acc *= MyGspn.colClasses[colvar->type].colors.size();
     291             :     }
     292           1 :     return acc;
     293             : }
     294             : 
     295             : template <typename T1>
     296             : bool setinclusion(set<T1> s1,set<T1> s2){
     297             :     for (typename set<T1>::const_iterator it = s1.begin(); it!= s1.end(); ++it){
     298             :         if (s2.find(*it)==s2.end())return false;
     299             :     }
     300             : 
     301             :     return true;
     302             : }
     303             : 
     304             : /*template <typename T1>
     305             :  vector<T1> setofvect(vect<T1> s1){
     306             :  for (typename set<T1>::const_iterator it = s1.begin(); it!= s1.end(); ++it){
     307             :  if (s2.find(*it)==s2.end())return false;
     308             :  }
     309             : 
     310             :  return true;
     311             :  }*/
     312             : 
     313             : template <typename T1>
     314             : void printset(set<T1> s1){
     315             :     cerr<< "{";
     316             :     for (typename set<T1>::const_iterator it = s1.begin(); it!= s1.end(); ++it){
     317             :         if(it!=s1.begin())cerr << ";";
     318             :         cerr << *it;
     319             :     }
     320             :     cerr << "}";
     321             : }
     322             : 
     323         387 : void Gspn_Writer::writeTok(ostream &SpnF,const coloredToken &sct,const colorDomain &cd)const{
     324             :     using namespace text_output;
     325         387 :         if(!cd.isUncolored()){
     326         270 :             if(sct.hasAll && all_of(sct.Flags.begin(), sct.Flags.end(), [](varType v){return v == CT_ALL;} ) ){
     327          13 :                 SpnF << cd.cname() << "(1)";
     328             :             }else{
     329             :                 if( sct.hasAll && false){
     330             :                     SpnF << cd.cname();
     331             :                 }else{
     332         240 :                     SpnF << cd.tokname();
     333             :                 }
     334         240 :                 SpnF << "(" ;
     335         498 :                 for (size_t pr = 0; pr < sct.field.size() ; pr++) {
     336         516 :                     const auto cc = MyGspn.colClasses[cd.colorClassIndex[pr]];
     337         258 :                     if(pr>0)SpnF << ", ";
     338             : 
     339             :                     //if(sct.hasAll)SpnF << "ColorType<" << cc.cname() <<">(";
     340         258 :                     switch (sct.Flags[pr]) {
     341             :                         case CT_VARIABLE:
     342         256 :                             SpnF << "b.P->"+MyGspn.colVars[sct.field[pr].intVal].name;
     343         256 :                             if(sct.hasAll)SpnF << ".c0";
     344         256 :                             break;
     345             :                         case CT_SINGLE_COLOR:
     346           0 :                             SpnF<<"Color_"<<cc.name<<"_"<<cc.colors[sct.field[pr].intVal].name;
     347           0 :                             break;
     348             :                         case CT_SINGLE_REAL:
     349           0 :                             SpnF<< sct.field[pr].get_real();
     350           0 :                             break;
     351             :                         case CT_ALL:
     352           2 :                             SpnF << "Color_" << cc.name <<"_All";
     353           2 :                             break;
     354             :                         case CT_ALL_SUBCLASS:
     355           0 :                             SpnF << "Color_" << cc.name << "_SubClass_" << cc.staticSubclasses[sct.field[pr].intVal].name;
     356           0 :                             break;
     357             :                         case CV_INT:
     358             :                         case CV_REAL:
     359             :                         case CV_CLOCK :
     360           0 :                             cerr << "Variable value are not marking: ill formed token" << endl;
     361             :                     }
     362         258 :                     if(sct.varIncrement[pr] != 0){
     363           4 :                         SpnF << ".next(" << sct.varIncrement[pr] << ")";
     364             :                     }
     365             :                     //if(sct.hasAll)SpnF << ")";
     366             :                 }
     367         240 :                 SpnF << ")";
     368             :             }
     369         253 :             if( !sct.mult.is_concrete() || sct.mult.intVal != 1) SpnF << " * (" << sct.mult<< ")";
     370             : 
     371         134 :         }else SpnF << sct.mult ;
     372             : 
     373         387 : }
     374             : 
     375          99 : void Gspn_Writer::generateStringVal(arcStore& as){
     376        1576 :     for(auto &inarcit: as){
     377        1477 :         auto &inarc = inarcit.second;
     378        1477 :         if (inarc.isColored) {
     379         472 :             stringstream stringval;
     380         472 :             const auto cd = MyGspn.colDoms[MyGspn.placeStruct[inarcit.first.second].colorDom];
     381         476 :             for( auto it = inarc.coloredVal.begin(); it != inarc.coloredVal.end(); ++it){
     382         240 :                 if( it != inarc.coloredVal.begin())stringval << " + ";
     383         240 :                 writeTok(stringval, *it, cd);
     384             :             }
     385         236 :             inarc.exprVal = expr(stringval.str());
     386             :         }
     387             :     }
     388          99 : }
     389             : 
     390          33 : void Gspn_Writer::writeTransition(ofstream & spnF)const{
     391             :     using namespace text_output;
     392          33 :     size_t nbbinding = 1;
     393          45 :     for (size_t v = 0 ; v < MyGspn.colVars.size(); v++)
     394          12 :         nbbinding *= MyGspn.colClasses[MyGspn.colDoms[MyGspn.colVars[v].type].colorClassIndex[0]].colors.size();
     395         543 :     for (let tr : MyGspn.transitionStruct ) {
     396         510 :         if (P.verbose > 7) {
     397           0 :             spnF << "\t\t\t\tstd::cerr << \"TRANSITION " << tr.id << "\" << \" : \\n\";\n";
     398             :         }
     399         510 :         if(!P.is_domain_impl_set){
     400         484 :             spnF << "\t{ ";
     401             : 
     402         484 :             spnF << "//"<< tr.name << "\n\tabstractBinding bl;" << endl;
     403         484 :             spnF << "\tbl.idcount = static_cast<int>(Transition["<< tr.id <<"].bindingList.size());"<< endl;
     404         484 :             bool atleastone = false;
     405         568 :             for (size_t it=0; it < MyGspn.colVars.size(); ++it) {
     406          84 :                 if( tr.varDomain.count(it)==0){
     407           0 :                     spnF<< "\tbl.P->" << MyGspn.colVars[it].name<<".mult = -1;\n";
     408          84 :                 }else atleastone=true;
     409             :             }
     410         484 :             if( atleastone){
     411          76 :                 if (P.verbose > 7) {
     412             :                     //spnF << "\t\t\t\tstd::cerr << \"" << t << "\" << \" : \"; \n\t\t\t\tbl.print();\n";
     413           0 :                     spnF << "\t\t\t\tbl.print();\n";
     414           0 :                     spnF << "\t\t\t\tstd::cerr << \"\\n\";\n";
     415             :                 }
     416          76 :                 spnF << "\tdo{\n";
     417          76 :                 if(tr.guard.t == Bool && tr.guard.boolVal ){
     418          67 :                     spnF << "\t\t{\n";
     419             :                 } else {
     420           9 :                     spnF << "\t\tif(" << tr.guard << "){\n";
     421             :                 }
     422          76 :                 spnF << "\t\t\tbl.idcount = Transition["<< tr.id <<"].bindingList.size();\n";
     423          76 :                 spnF << "\t\t\tTransition["<< tr.id <<"].bindingList.push_back( bl );\n";
     424          76 :                 if (P.verbose > 7) {
     425             :                     //spnF << "\t\t\t\tstd::cerr << \"" << t << "\" << \" : \"; \n\t\t\t\tbl.print();\n";
     426           0 :                     spnF << "\t\t\t\tbl.print();\n";
     427           0 :                     spnF << "\t\t\t\tstd::cerr << \"\\n\";\n";
     428             :                 }
     429          76 :                 spnF << "\t\t\tTransition["<< tr.id <<"].bindingLinkTable[bl.idTotal()]= Transition["<< tr.id <<"].bindingList.size()-1; "<< endl;
     430          76 :                 spnF << "\t\t}\n\t}while(bl.next());\n\t}\n";
     431             :             } else {
     432         408 :                 spnF << "\tTransition["<< tr.id <<"].bindingList.push_back( bl );\n\t}\n";
     433             :             }
     434             :         }
     435             : 
     436             : 
     437         510 :         if (P.verbose > 7) {
     438           0 :             spnF << "\tstd::cerr << \"\\n\\n\";\n";
     439             :         }
     440             :     }
     441          33 : }
     442             : 
     443          33 : void Gspn_Writer::writeVariable(ofstream & spnF)const{
     444          45 :     for (size_t v = 0 ; v < MyGspn.colVars.size(); v++) {
     445          12 :         spnF << "\t" << MyGspn.colDoms[MyGspn.colVars[v].type].cname();
     446          12 :         spnF << " " << MyGspn.colVars[v].name << ";\n";
     447             :     }
     448          33 : }
     449             : 
     450          33 : void Gspn_Writer::writeDotFile(const string &file)const{
     451             :     using namespace text_output;
     452          66 :     ofstream df(file.c_str(), ios::out | ios::trunc);
     453          33 :     df << "digraph G {" << endl;
     454             : 
     455         320 :     for (const auto &p : MyGspn.placeStruct ) {
     456         287 :         df << "\t" << p.name;
     457         287 :         df << " [xlabel=\""<< p.name;
     458         287 :         df <<"\",label=\"$"<< p.name << "$\"];" << endl;
     459             :     }
     460             : 
     461         543 :     for (const auto &t : MyGspn.transitionStruct ) {
     462         510 :         df << "\t" << t.name;
     463         510 :         df << " [shape=rect,height=0.2,style=filled,fillcolor=$CF_";
     464         510 :         df << t.name << "$ ,xlabel=\"" << t.name << "\",label=\"$ET_";
     465         510 :         df << t.name << "$\"];"<< endl;
     466             :     }
     467             : 
     468         320 :     for (auto &p : MyGspn.placeStruct )
     469       11811 :         for(auto &t : MyGspn.transitionStruct){
     470       23048 :             const auto ia = MyGspn.access(MyGspn.inArcsStruct, t.id, p.id);
     471       11524 :             if(! ia.isEmpty) {
     472         828 :                 df << "\t" << p.name << "->" << t.name;
     473         828 :                 df << " [label=\""<< ia.exprVal << " \"];" << endl;
     474             :             }
     475       23048 :             const auto oa = MyGspn.access(MyGspn.outArcsStruct, t.id, p.id);
     476       11524 :             if(! oa.isEmpty) {
     477         645 :                 df << "\t" <<  t.name <<"->" << p.name ;
     478         645 :                 df << " [label=\""<< oa.exprVal << " \"];" << endl;
     479             :             }
     480       23048 :             const auto iha = MyGspn.access(MyGspn.inhibArcsStruct, t.id, p.id);
     481       11524 :             if(! iha.isEmpty) {
     482           4 :                 df << "\t" << p.name << "->" << t.name;
     483           4 :                 df << " [arrowhead=odot,label=\""<< iha.exprVal << " \"];" << endl;
     484             :             }
     485             :         }
     486          33 :     df << "}" << endl;
     487          33 : }
     488             : 
     489          33 : void Gspn_Writer::writeMacro(ofstream &f)const{
     490         320 :     for( auto &p : MyGspn.placeStruct)
     491         287 :         f << "#define PL_"<< p.name << "_LP " << p.id <<endl;
     492         543 :     for( auto &t : MyGspn.transitionStruct)
     493         510 :         f << "#define TR_"<< t.name << "_RT " << t.id <<endl;
     494          33 :     f<< endl;
     495          33 : }
     496             : 
     497             : 
     498           0 : void Gspn_Writer::writeMarkingUpdateIn(stringstream &f,const arcStore &as, size_t t,const place &p , size_t t2, bool pos, const arcStore &as2, bool direct)const{
     499           0 :     if (!MyGspn.access(as,t2,p.id).isEmpty) {
     500           0 :         if(!MyGspn.access(as2,t,p.id).isMarkDep && !MyGspn.access(as,t2,p.id).isMarkDep){
     501           0 :             int decrement = MyGspn.access(as2,t,p.id).exprVal.intVal;
     502           0 :             int seuil = MyGspn.access(as,t2,p.id).exprVal.intVal;
     503           0 :             if(seuil-decrement >0){
     504           0 :                 f << "\t\t\tif(Marking.P->_PL_" << p.name <<" < "<< seuil+ (direct? decrement: 0);
     505           0 :                 f << " && Marking.P->_PL_" << p.name <<"+"<< (direct? 0: decrement)<<" >=" << seuil <<")";
     506           0 :                 f << "TransitionConditions["<< t2 << (pos? "]++ ;":"]-- ;") << endl;
     507             :             } else
     508           0 :                 f << "\t\t\tif(Marking.P->_PL_" << p.name <<" < "<< seuil+(direct? decrement: 0) << ")TransitionConditions["<< t2 << (pos? "]++ ;":"]-- ;") << endl;
     509             :         } else {
     510           0 :             string decrement;
     511           0 :             searchreplace(MyGspn.access(as2,t,p.id).exprVal.to_string(), "Marking.P->_PL_", "tmpMark_" , decrement);
     512           0 :             string seuil;
     513           0 :             searchreplace(MyGspn.access(as,t2,p.id).exprVal.to_string(), "Marking.P->_PL_", "tmpMark_" , seuil);
     514             : 
     515           0 :             f << "\t\t\tif(Marking.P->_PL_" << p.name << (direct? "": "+"+decrement) <<" >= "<< seuil;
     516           0 :             f << " && Marking.P->_PL_" << p.name <<" < " << seuil << (direct? "+"+decrement: "") <<")";
     517           0 :             f << "TransitionConditions["<< t2 <<(pos? "]++ ;":"]-- ;") << endl;
     518             :         }
     519             :     }
     520           0 : }
     521             : 
     522        1519 : void Gspn_Writer::writeMarkingUpdate(stringstream &f, size_t t,const place &p,const arcStore &as2,bool direct)const{
     523             : 
     524        1519 :     if(P.localTesting)for (size_t t2 = 0; t2 < MyGspn.tr; t2++) {
     525           0 :         if (!MyGspn.access(MyGspn.inArcsStruct,t2,p.id).isEmpty)
     526           0 :             writeMarkingUpdateIn(f, MyGspn.inArcsStruct, t, p, t2, direct  ,as2,direct);
     527             : 
     528           0 :         if (!MyGspn.access(MyGspn.inhibArcsStruct,t2,p.id).isEmpty)
     529           0 :             writeMarkingUpdateIn(f, MyGspn.inhibArcsStruct, t, p, t2, !direct ,as2,direct);
     530             :     }
     531        3038 :     string decrement;
     532        1519 :     searchreplace(MyGspn.access(as2,t,p.id).exprVal.to_string(), "Marking.P->_PL_", "tmpMark_" , decrement);
     533        1519 :     f << "\t\t\tMarking.P->_PL_" << p.name << (direct? " -= " : " += ") << decrement << ";"<< endl;
     534        1519 : }
     535             : 
     536             : 
     537          33 : void Gspn_Writer::writeGetDistParameters(ofstream &f)const{
     538             :     using namespace text_output;
     539          66 :     writeFunT(f, "void", "GetDistParameters(", ")const",
     540         510 :               [&](unsigned int t,stringstream &newcase){
     541        2997 :                   if (MyGspn.transitionStruct[t].type == Timed) {
     542         495 :                       newcase << "\t{" << endl;
     543         990 :                       if (MyGspn.transitionStruct[t].singleService)
     544        1988 :                           for (size_t i = 0; i < MyGspn.transitionStruct[t].dist.Param.size(); i++) {
     545        1497 :                               newcase << "\t\tParamDistr[" << i << "]= ( double ) " << ( (MyGspn.transitionStruct[t].dist.name != "SYNC") ? MyGspn.transitionStruct[t].dist.Param[i] : expr(0.0)) << ";" << endl;
     546             :                           } else {
     547           0 :                               newcase << "\t\tdouble EnablingDegree = INT_MAX; " << endl;
     548           0 :                               bool AtLeastOneMarkDepArc = false;
     549           0 :                               for (const auto &p : MyGspn.placeStruct)
     550           0 :                                   if (!MyGspn.access(MyGspn.inArcsStruct,t,p.id).isEmpty) {
     551           0 :                                       if (!MyGspn.access(MyGspn.inArcsStruct,t,p.id).isMarkDep)
     552           0 :                                           newcase << "\t\tEnablingDegree=min(floor(Marking.P->_PL_" << p.name <<"/(double)(" << MyGspn.access(MyGspn.inArcsStruct,t,p.id).exprVal.intVal << ")),EnablingDegree);" << endl;
     553             :                                       else {
     554           0 :                                           AtLeastOneMarkDepArc = true;
     555           0 :                                           newcase << "\t\tif(" << MyGspn.access(MyGspn.inArcsStruct,t,p.id).exprVal.to_string() << ">0)" << endl;
     556           0 :                                           newcase << "\t\t\tEnablingDegree=min(floor(Marking.P->_PL_" << p.name <<"/(double)(" << MyGspn.access(MyGspn.inArcsStruct,t,p.id).exprVal.to_string() << ")),EnablingDegree);" << endl;
     557             :                                       }
     558             :                                   }
     559           0 :                               if (AtLeastOneMarkDepArc) {
     560           0 :                                   if (MyGspn.transitionStruct[t].nbServers >= INT_MAX) {
     561           0 :                                       newcase << "\t\t\tif(EnablingDegree < INT_MAX ) ParamDistr[0] = EnablingDegree * ( " << MyGspn.transitionStruct[t].dist.Param[0] << " );" << endl;
     562           0 :                                       newcase << "\t\t\telse ParamDistr[0] = " << MyGspn.transitionStruct[t].dist.Param[0] << " ;" << endl;
     563             :                                   } else {
     564           0 :                                       newcase << "\t\t\tif(EnablingDegree < INT_MAX ) P[0] = min(EnablingDegree , " << MyGspn.transitionStruct[t].nbServers << " ) * ( " << MyGspn.transitionStruct[t].dist.Param[0] << " );" << endl;
     565           0 :                                       newcase << "\t\t\telse ParamDistr[0] = " << MyGspn.transitionStruct[t].dist.Param[0] << " ;" << endl;
     566             :                                   }
     567             :                               } else {
     568           0 :                                   if (MyGspn.transitionStruct[t].nbServers >= INT_MAX)
     569           0 :                                       newcase << "\t\t\tParamDistr[0] = EnablingDegree  * ( " << MyGspn.transitionStruct[t].dist.Param[0] << " );" << endl;
     570             :                                   else
     571           0 :                                       newcase << "\t\t\tParamDistr[0] = min(EnablingDegree , " << MyGspn.transitionStruct[t].nbServers << " ) * ( " << MyGspn.transitionStruct[t].dist.Param[0] << " );" << endl;
     572             :                               }
     573             :                           }
     574         495 :                       newcase << "\t}" << endl;
     575             :                   }
     576         543 :               }, "using namespace hybridVar;\n");
     577          33 : }
     578             : 
     579          33 : void Gspn_Writer::writeIsEnabled(ofstream &f)const{
     580             :     using namespace text_output;
     581          99 :     writeFunT(f, "bool", "IsEnabled(", ")const",
     582         510 :               [&](unsigned int t,stringstream &newcase){
     583       24578 :                   if(MyGspn.transitionStruct[t].dist.name == "SYNC"){
     584           0 :                       newcase << "\t\treturn true;" << endl;
     585             :                   }
     586         510 :                   if(P.localTesting){
     587           0 :                       newcase << "\treturn (TransitionConditions[t]==0);" << endl;
     588             :                   } else {
     589         510 :                       newcase<<endl;
     590       12034 :                       for (let p : MyGspn.placeStruct) {
     591       34572 :                           let in_arc = MyGspn.access(MyGspn.inArcsStruct,t,p.id);
     592       34572 :                           let inhib_arc = MyGspn.access(MyGspn.inhibArcsStruct,t,p.id);
     593             :                           //Test Equality
     594       11524 :                           if (!in_arc.isEmpty && !inhib_arc.isEmpty)
     595           0 :                               if (!in_arc.isMarkDep && !inhib_arc.isMarkDep)
     596           0 :                                   if (in_arc.exprVal.intVal+1 == inhib_arc.exprVal.intVal) {
     597           0 :                                       newcase << "\t\t\tif( Marking.P->_PL_" << p.name <<" != " << in_arc.exprVal << ") return false;" << endl;
     598           0 :                                       continue;
     599             :                                   }
     600             :                           //Test inarc
     601       11524 :                           if (!in_arc.isEmpty) {
     602         828 :                               if (!in_arc.isMarkDep)
     603         828 :                                   newcase << "\t\t\tif (!(contains(Marking.P->_PL_" << p.name <<" , " << in_arc.exprVal << "))) return false;" << endl;
     604             :                               else {
     605           0 :                                   newcase << "\t\t\tif ( !(" << in_arc.exprVal << " < 1)) " << endl;
     606           0 :                                   newcase << "\t\t\tif (!(contains(Marking.P->_PL_" << p.name <<" , " << in_arc.exprVal << "))) return false;" << endl;
     607             :                               }
     608             :                           }
     609             :                           //Test inhibitor arc
     610       11524 :                           if (!inhib_arc.isEmpty) {
     611           4 :                               if (!inhib_arc.isMarkDep)
     612           4 :                                   newcase << "    if (Marking.P->_PL_" << p.name <<" >= " << inhib_arc.exprVal << ") return false;" << endl;
     613             :                               else {
     614           0 :                                   newcase << "    if ( !(" << inhib_arc.exprVal << " < 1) ) " << endl;
     615           0 :                                   newcase << "        if (contains(Marking.P->_PL_" << p.name <<" , " << inhib_arc.exprVal << ")) return false;" << endl;
     616             :                               }
     617             :                           }
     618             :                       }
     619         510 :                       newcase << "\t\treturn true;";
     620             :                   }
     621         576 :               },(!P.magic_values.empty() ? "\tif(!magicConditional(t,b))return false;\n":""));
     622          33 : }
     623             : 
     624          33 : void Gspn_Writer::writeFire(ofstream &f)const{
     625          66 :     stringstream preamble;
     626          33 :     preamble << "\tlastTransition = t;" << endl;
     627          33 :     if(!P.magic_values.empty()){
     628           0 :         preamble << "\tmagicUpdate(t,b,time);" << endl;
     629             :     }
     630          33 :     if(!MyGspn.hybridVars.empty()){
     631           0 :         preamble << "\tdouble incrtime = time - lastTransitionTime;" << endl;
     632           0 :         preamble << "\tlastTransitionTime = time;" << endl;
     633           0 :         for(const auto &v:MyGspn.hybridVars)
     634           0 :             if (v.type == CV_CLOCK)
     635           0 :                 preamble << "\thybridVar::" << v.name << "+= incrtime;" << endl;
     636             :     }
     637             : 
     638          66 :     writeFunT(f, "void", "fire(", ",REAL_TYPE time)",
     639         510 :               [&](unsigned int t,stringstream &newcase){
     640       52306 :                   if(MyGspn.transitionStruct[t].dist.name == "SYNC")return;
     641        1020 :                   let ts = MyGspn.transitionStruct[t];
     642         510 :                   newcase << "{" << endl;
     643             :                   //Write value of Marking dependant place to a temporary variable
     644        1020 :                   set<place> dependency;
     645       12034 :                   for (let p : MyGspn.placeStruct) {
     646             :                       using namespace text_output;
     647       34572 :                       let ain = MyGspn.access(MyGspn.inArcsStruct,t,p.id);
     648       34572 :                       let aout = MyGspn.access(MyGspn.outArcsStruct,t,p.id);
     649       23048 :                       set<string> depSet;
     650       11524 :                       if(!ain.isEmpty || !aout.isEmpty){
     651        1224 :                           dependency.insert(p);
     652             :                           //cout << "transistion: '"<< ts.name << "' place: '" << p.name;
     653        1224 :                           ain.exprVal.get_places(depSet);
     654        1224 :                           aout.exprVal.get_places(depSet);
     655             : 
     656             :                       }
     657             :                       /*if(!ain.isEmpty){
     658             :                        cout << "' arc in: '" << ain.exprVal << "' {";
     659             :                        ain.exprVal.printXML(cout);
     660             :                        cout << "} ";
     661             :                        }
     662             :                        if(!aout.isEmpty){
     663             :                        cout << "} arc out: '" << aout.exprVal << "' {";
     664             :                        aout.exprVal.printXML(cout);
     665             :                        cout << "} ";
     666             :                        }*/
     667       11524 :                       if(!ain.isEmpty || !aout.isEmpty){
     668        1224 :                           for(let pn : depSet ){
     669             :                               //cout << "dep: " << pn;
     670           0 :                               dependency.insert(MyGspn.placeStruct[MyGspn.PlacesId.at(pn)]);
     671             :                           }
     672             :                           //cout << endl;
     673             :                       }
     674             : 
     675             :                   }
     676        1734 :                   for(let p : dependency){
     677        2448 :                       newcase << "\t\t\t"<< MyGspn.colDoms[p.colorDom].cname() <<" tmpMark_" << p.name;
     678        1224 :                       newcase << " = Marking.P->_PL_" << p.name << ";" << endl;
     679             :                   }
     680             : 
     681             :                   //update the marking
     682       12034 :                   for (let p : MyGspn.placeStruct) {
     683       23048 :                       if (!MyGspn.access(MyGspn.inArcsStruct,t,p.id).isEmpty) {
     684             :                           //update for place in place
     685        1656 :                           writeMarkingUpdate(newcase, t, p,MyGspn.inArcsStruct,true);
     686             :                       }
     687             : 
     688       23048 :                       if (!MyGspn.access(MyGspn.outArcsStruct,t,p.id).isEmpty) {
     689             :                           //update for outplace
     690        1290 :                           writeMarkingUpdate(newcase, t, p,MyGspn.outArcsStruct,false);
     691             :                       }
     692             :                   }
     693         510 :                   if(!ts.update.empty()){
     694           0 :                       newcase << "{using namespace hybridVar;" <<endl;
     695           0 :                       newcase << "\tabstractMarkingImpl &M = *Marking.P;"<<endl;
     696           0 :                       newcase << "\tabstractBindingImpl &B = *b.P;"<<endl;
     697           0 :                       newcase << ts.update << "}" << endl;
     698             :                   }
     699         510 :                   newcase << "\t}";
     700             :               },
     701          66 :               preamble.str()
     702          33 :               );
     703             : 
     704          33 :     if(!P.lightSimulator){
     705         576 :         writeFunT(f, "void", "unfire(", ")", [&](unsigned int t,stringstream &newcase){
     706         824 :             if(P.RareEvent || P.computeStateSpace){
     707             :                 //update the marking
     708         149 :                 for (const auto &p : MyGspn.placeStruct) {
     709         222 :                     if (!MyGspn.access(MyGspn.inArcsStruct,t,p.id).isEmpty) {
     710             :                         //update for place in place
     711          40 :                         writeMarkingUpdate(newcase, t, p,MyGspn.inArcsStruct,false);
     712             :                     }
     713             : 
     714         222 :                     if (!MyGspn.access(MyGspn.outArcsStruct,t,p.id).isEmpty) {
     715             :                         //update for outplace
     716          52 :                         writeMarkingUpdate(newcase, t, p,MyGspn.outArcsStruct,true);
     717             :                     }
     718             : 
     719             :                 }
     720             :             }
     721         543 :         });
     722             : 
     723          33 :         if (P.is_domain_impl_set) { writeEnabledDisabledBindingSet(f); }
     724          29 :         else { writeEnabledDisabledBinding(f); }
     725             :     }
     726          33 : }
     727             : 
     728             : 
     729          33 : void Gspn_Writer::writeSetConditionsVector(ofstream &f)const{
     730             :     using namespace text_output;
     731          33 :     f << "void "<< objName <<"setConditionsVector(){" << endl;
     732          33 :     if(P.localTesting)for (size_t t = 0; t < MyGspn.tr; t++) {
     733           0 :         f << "\tTransitionConditions["<< t <<"]=0;" << endl;
     734           0 :         for (const auto &p : MyGspn.placeStruct)  {
     735           0 :             if (!MyGspn.access(MyGspn.inArcsStruct,t,p.id).isEmpty) {
     736           0 :                 if (!MyGspn.access(MyGspn.inArcsStruct,t,p.id).isMarkDep)
     737           0 :                     f << "\tif (Marking.P->_PL_" << p.name <<" < " << MyGspn.access(MyGspn.inArcsStruct,t,p.id).exprVal.intVal << ")TransitionConditions["<< t <<"]++;" << endl;
     738             :                 else {
     739           0 :                     f << "\tif ( " << MyGspn.access(MyGspn.inArcsStruct,t,p.id).exprVal << "> 0) " << endl;
     740           0 :                     f << "\t\tif (Marking.P->_PL_" << p.name <<" < " << MyGspn.access(MyGspn.inArcsStruct,t,p.id).exprVal << ")TransitionConditions["<< t <<"]++;" << endl;
     741             :                 }
     742             :             }
     743           0 :             if (!MyGspn.access(MyGspn.inhibArcsStruct,t,p.id).isEmpty) {
     744           0 :                 if (!MyGspn.access(MyGspn.inhibArcsStruct,t,p.id).isMarkDep)
     745           0 :                     f << "\tif (Marking.P->_PL_" << p.name <<" >= " << MyGspn.access(MyGspn.inhibArcsStruct,t,p.id).exprVal.intVal << ")TransitionConditions["<< t <<"]++;" << endl;
     746             :                 else {
     747           0 :                     f << "\tif ( " << MyGspn.access(MyGspn.inhibArcsStruct,t,p.id).exprVal << " > 0 ) " << endl;
     748           0 :                     f << "\t\tif (Marking.P->_PL_" << p.name <<" >= " << MyGspn.access(MyGspn.inhibArcsStruct,t,p.id).exprVal << ")TransitionConditions["<< t <<"]++;" << endl;
     749             :                 }
     750             :             }
     751             :         }
     752             :     }
     753          33 :     f << "}" << endl;
     754          33 : }
     755             : 
     756          33 : void Gspn_Writer::writeGetPriority(ofstream &f)const{
     757             :     using namespace text_output;
     758          66 :     writeFunT(f, "REAL_TYPE","GetPriority(", ")const",
     759         510 :               [&](unsigned int t,stringstream &ss){
     760         510 :                   ss << "\t\treturn (double)" << MyGspn.transitionStruct[t].priority << ";";
     761         543 :               }, "using namespace hybridVar;\n");
     762          33 : }
     763             : 
     764             : 
     765          33 : void Gspn_Writer::writeGetWeight(ofstream &f)const{
     766             :     using namespace text_output;
     767          66 :     writeFunT(f, "REAL_TYPE","GetWeight(", ")const",
     768         510 :               [&](unsigned int t,stringstream &ss){
     769         510 :                   ss << "\t\treturn (double)" << MyGspn.transitionStruct[t].weight << ";";
     770         543 :               }, "using namespace hybridVar;\n");
     771          33 : }
     772             : 
     773          33 : void Gspn_Writer::writeMarkingClasse(ofstream &SpnCppFile,ofstream &header)const{
     774             :     using namespace text_output;
     775          33 :     header << "#ifndef ABSTRACT_BINDING_h"  << endl;
     776          33 :     header << "#define ABSTRACT_BINDING_h" << endl;
     777             : 
     778             : 
     779          33 :     header << "class abstractBindingImpl {\npublic:\n";
     780          45 :     for (vector<colorVariable>::const_iterator colvar = MyGspn.colVars.begin() ; colvar != MyGspn.colVars.end(); ++colvar) {
     781          12 :         header << "\t" << MyGspn.colDoms[colvar->type].tokname() << " " << colvar->name << " = " << MyGspn.colDoms[colvar->type].tokname() << "((" << MyGspn.colDoms[colvar->type].ccname() << ") 0);\n";
     782             :     }
     783          33 :     header << "};\n";
     784          33 :     header << "#endif"<< endl;
     785             : 
     786             : 
     787          33 :     header << "class abstractMarkingImpl {\n";
     788          33 :     header << "public:\n";
     789             : 
     790         960 :     for (vector<place>::const_iterator plit = MyGspn.placeStruct.begin();
     791         640 :          plit!= MyGspn.placeStruct.end(); ++plit) {
     792             : 
     793         287 :         header << "\t"<< MyGspn.colDoms[plit->colorDom].cname() << " _PL_"<< plit->name << ";\n";
     794             : 
     795             :     }
     796          33 :     writeVariable(header);
     797          33 :     header << "};\n";
     798             : 
     799          33 :     SpnCppFile << "\n";
     800          33 :     SpnCppFile << "void abstractMarking::resetToInitMarking(){\n";
     801          33 :     if(!P.magic_values.empty()){
     802           0 :         SpnCppFile << "\tmagicReset();" << endl;
     803             :     }
     804         320 :     for (const auto &plit : MyGspn.placeStruct) {
     805         287 :         SpnCppFile << "\tP->_PL_"<< plit.name << " = 0;\n";
     806         434 :         for(const auto & tok : plit.initMarking){
     807         147 :             SpnCppFile << "\tP->_PL_"<< plit.name << " +=";
     808         147 :             writeTok(SpnCppFile, tok, MyGspn.colDoms[plit.colorDom]);
     809         147 :             SpnCppFile << ";\n";
     810             :         }
     811             :     }
     812          33 :     if (!MyGspn.hybridVars.empty()) {
     813           0 :         for(const auto &v:MyGspn.hybridVars)
     814           0 :             SpnCppFile << "\thybridVar::" << v.name << "=" << v.initialValue << ";" << endl;
     815             :     }
     816             : 
     817          33 :     SpnCppFile << "}\n";
     818          33 :     SpnCppFile << "\n";
     819          33 :     SpnCppFile << "\n";
     820             : 
     821          33 :     SpnCppFile << "abstractMarking::abstractMarking() {\n";
     822          33 :     SpnCppFile << "\tP= new abstractMarkingImpl;\n";
     823          33 :     SpnCppFile << "\tresetToInitMarking();\n";
     824          33 :     SpnCppFile << "}\n";
     825          33 :     SpnCppFile << "\n";
     826          33 :     if(!P.lightSimulator){
     827          33 :         SpnCppFile << "abstractMarking::abstractMarking(const std::vector<int>& m) {\n";
     828          33 :         SpnCppFile << "\tP = new abstractMarkingImpl;\n";
     829          33 :         SpnCppFile << "\tsetVector(m);\n";
     830          33 :         SpnCppFile << "}\n";
     831          33 :         SpnCppFile << "abstractMarking::abstractMarking(const abstractMarking& m) {\n";
     832          33 :         SpnCppFile << "\tP= new abstractMarkingImpl;\n";
     833          33 :         SpnCppFile << "\t*this = m;\n";
     834          33 :         SpnCppFile << "};\n";
     835          33 :         SpnCppFile << "\n";
     836          33 :         SpnCppFile << "abstractMarking& abstractMarking::operator = (const abstractMarking& m) {\n";
     837          33 :         SpnCppFile << "\t*P = *(m.P);\n";
     838          33 :         SpnCppFile << "\treturn *this;\n";
     839          33 :         SpnCppFile << "}\n";
     840          33 :         SpnCppFile << "\n";
     841             :     }
     842          33 :     SpnCppFile << "abstractMarking::~abstractMarking() {\n";
     843          33 :     SpnCppFile << "\tdelete(P);\n";
     844          33 :     SpnCppFile << "}\n";
     845          33 :     SpnCppFile << "\n";
     846          33 :     SpnCppFile << "\n";
     847          33 :     if(!P.lightSimulator){
     848          33 :         SpnCppFile << "void abstractMarking::swap(abstractMarking& m) {\n";
     849          33 :         SpnCppFile << "\tabstractMarkingImpl* tmp = m.P;\n";
     850          33 :         SpnCppFile << "\tm.P = P;\n";
     851          33 :         SpnCppFile << "\tP = tmp;\n";
     852          33 :         SpnCppFile << "}\n";
     853             :     }
     854             : 
     855          33 :     size_t maxNameSize =5;
     856         320 :     for (const auto &plit : MyGspn.placeStruct)
     857         287 :         if (plit.isTraced)
     858         235 :             maxNameSize = max(maxNameSize, plit.name.length());
     859          66 :     vector<place> plitcp((MyGspn.placeStruct.size()));
     860             : 
     861         287 :     auto it = copy_if(MyGspn.placeStruct.begin(), MyGspn.placeStruct.end(), plitcp.begin(), [](const place &plit){
     862             :         return plit.isTraced;
     863         320 :     });
     864          33 :     plitcp.resize(distance(plitcp.begin(),it));
     865             : 
     866             : 
     867         556 :     sort(plitcp.begin(), plitcp.end(), [&](const place &p1, const place &p2){
     868         523 :         if (P.tracedPlace.count(p1.name)>0 && P.tracedPlace.count(p2.name)>0){
     869           0 :             const auto i1= P.tracedPlace.at(p1.name);
     870           0 :             const auto i2= P.tracedPlace.at(p2.name);
     871           0 :             return i1 < i2;
     872         523 :         } else return false;
     873          66 :     });
     874             : 
     875          33 :     if(P.lightSimulator){
     876           0 :         if(P.StringInSpnLHA){
     877           0 :             SpnCppFile << "void abstractMarking::printHeader()const{\n";
     878           0 :             if(P.StringInSpnLHA)
     879           0 :                 for (const auto &plit : plitcp)
     880           0 :                     SpnCppFile << "::print(\"" << plit.name << "\t\");"<<endl;
     881           0 :             SpnCppFile << "}\n";
     882           0 :             SpnCppFile << "\n";
     883           0 :             SpnCppFile << "void abstractMarking::print()const{\n";
     884           0 :             if(P.StringInSpnLHA){
     885           0 :                 for (const auto &plit : plitcp){
     886           0 :                     SpnCppFile << "print_magic(P->_PL_"<< plit.name << ");"<<endl;
     887           0 :                     SpnCppFile << "::print(\"\t\");"<<endl;
     888             :                 }
     889             :             }
     890           0 :             SpnCppFile << "}\n";
     891             :         }
     892             :     } else {
     893          33 :         SpnCppFile << "void abstractMarking::printHeader(ostream &s)const{\n";
     894          33 :         if(P.StringInSpnLHA){
     895          42 :             for (const auto &plit : plitcp)
     896          32 :                 if (plit.isTraced){
     897          32 :                     SpnCppFile << "s << ";
     898          32 :                     SpnCppFile << " setw(" << maxNameSize << ") << ";
     899          32 :                     SpnCppFile << "\"" <<plit.name  << " \";"<<endl;
     900             :                 }
     901          10 :             for (const auto &v : MyGspn.hybridVars)
     902           0 :                 if(v.isTraced){
     903           0 :                     SpnCppFile << "s << ";
     904           0 :                     SpnCppFile << " setw(" << maxNameSize << ") << ";
     905           0 :                     SpnCppFile << "\"" << v.name  << "\";"<<endl;
     906             :                 }
     907             : 
     908             :         }
     909          33 :         SpnCppFile << "}\n";
     910          33 :         SpnCppFile << "\n";
     911             : 
     912          33 :         SpnCppFile << "void abstractMarking::print(ostream &s,double eTime)const{\n";
     913          33 :         if(P.StringInSpnLHA){
     914             :             //SpnCppFile << "\tstd::cerr << \"Marking:\"<< std::endl;\n";
     915          42 :             for(const auto &plit : plitcp)
     916          32 :                 if (plit.isTraced){
     917          32 :                     SpnCppFile << "\ts << ";
     918          32 :                     SpnCppFile << " setw(" << maxNameSize-1 << ") << ";
     919          32 :                     if (not P.use_magic_print){ SpnCppFile << "P->_PL_"<< plit.name << "<<\" \";\n";
     920           0 :                     }else{ SpnCppFile << "print_magic(P->_PL_"<< plit.name << ")<<\" \";\n";
     921             :                     }
     922             :                 }
     923          10 :             for (const auto &v : MyGspn.hybridVars)
     924           0 :                 if(v.isTraced){
     925           0 :                     SpnCppFile << "s << ";
     926           0 :                     SpnCppFile << " setw(" << maxNameSize-1 << ") ";
     927           0 :                     SpnCppFile << " << hybridVar::"<< v.name  <<"+ eTime <<\" \";"<<endl;
     928             :                 }
     929             :         }
     930          33 :         SpnCppFile << "}\n";
     931             :     }
     932             : 
     933             : 
     934          33 :     if(!P.lightSimulator){
     935          33 :         SpnCppFile << "void abstractMarking::printSedCmd(ostream &s)const{\n";
     936          33 :         if(P.StringInSpnLHA){
     937             :             //SpnCppFile << "\tstd::cerr << \"Marking:\"<< std::endl;\n";
     938          42 :             for (const auto &plit : MyGspn.placeStruct){
     939          32 :                 SpnCppFile << "\ts << \"-e 's/\\\\$"<< plit.name <<"\\\\$/\";"<< endl;
     940          32 :                 if(not P.use_magic_print){
     941          32 :                     SpnCppFile << "\ts << P->_PL_"<< plit.name << ";"<<endl;
     942             :                 } else {
     943           0 :                     SpnCppFile << "\ts << print_magic(P->_PL_"<< plit.name << ");"<<endl;
     944             :                 }
     945          32 :                 SpnCppFile << "\ts <<\"/g' \";"<<endl;
     946             :             }
     947             :         }
     948          33 :         SpnCppFile << "}\n";
     949             : 
     950          33 :         SpnCppFile << "\n";
     951          33 :         SpnCppFile << "int abstractMarking::getNbOfTokens(int p)const {\n";
     952          33 :         if(MyGspn.isColored() || P.lightSimulator){
     953          11 :             SpnCppFile << "\texit(EXIT_FAILURE);\n";
     954             :         }else{
     955          22 :             SpnCppFile << "\tswitch (p) {\n";
     956         182 :             for (const auto &plit : MyGspn.placeStruct) {
     957         160 :                 SpnCppFile << "\t\tcase "<< plit.id << ": return P->_PL_"<< plit.name << ";\n";
     958             :             }
     959          22 :             SpnCppFile << "     }\n";
     960             :         }
     961          33 :         SpnCppFile << "}\n";
     962          33 :         SpnCppFile << "\n";
     963          33 :         SpnCppFile << "std::vector<int> abstractMarking::getVector()const {\n";
     964          33 :         if( P.lightSimulator || P.is_domain_impl_set){
     965           4 :             SpnCppFile << "\texit(EXIT_FAILURE);\n";
     966             :         }else{
     967          29 :             SpnCppFile << "\tstd::vector<int> v("<< markingSize <<");" << endl;
     968          29 :             SpnCppFile << "\tv.reserve("<< markingSize +1<<");" << endl;
     969          29 :             SpnCppFile << "\tsize_t i = 0;" << endl;
     970         284 :             for (let plit : MyGspn.placeStruct) {
     971         255 :                 if(plit.colorDom == UNCOLORED_DOMAIN ){SpnCppFile << "\tv[i++]= P->_PL_"<< plit.name << ";"<< endl;}
     972          77 :                 else SpnCppFile << "\ti= P->_PL_"<< plit.name << ".copyVector(v,i);"<< endl;
     973             :             }
     974             :             //SpnCppFile << "\tcopy((int*) P,(int*)P + "<< markingSize <<",v.data() );"<< endl;
     975          29 :             SpnCppFile << "     return v;\n";
     976             :         }
     977          33 :         SpnCppFile << "}\n";
     978          33 :         SpnCppFile << "\n";
     979          33 :         SpnCppFile << "void abstractMarking::setVector(const std::vector<int>&v) {\n";
     980          33 :         if(P.lightSimulator){
     981           0 :             SpnCppFile << "\texit(EXIT_FAILURE);\n";
     982             :         }else{
     983          33 :             SpnCppFile << "\tsize_t i = 0;" << endl;
     984         320 :             for (let plit : MyGspn.placeStruct) {
     985         287 :                 if(plit.colorDom == UNCOLORED_DOMAIN ){SpnCppFile << "\tP->_PL_"<< plit.name << " = v[i++];"<< endl;}
     986         103 :                 else SpnCppFile << "\ti= P->_PL_"<< plit.name << ".setVector(v,i);"<< endl;
     987             :             }
     988             :         }
     989          33 :         SpnCppFile << "};"<<endl<<endl;
     990             : 
     991             : 
     992          33 :         SpnCppFile << "void abstractMarking::Symmetrize(){" << endl;
     993          33 :         if(P.lumpStateSpace)
     994           0 :             for (size_t cci=0 ; cci<MyGspn.colClasses.size(); cci++) {
     995           0 :                 let cc = MyGspn.colClasses[cci];
     996           0 :                 SpnCppFile << "\t{"<< endl;
     997           0 :                 SpnCppFile << "\tconst vector<contains_"<< cc.cname()<< "* > vClasse = {" << endl;
     998           0 :                 for(let plit: MyGspn.placeStruct){
     999           0 :                     let cciv = MyGspn.colDoms[plit.colorDom].colorClassIndex;
    1000           0 :                     if( count(cciv.begin(), cciv.end(), cci )>0 )
    1001           0 :                         SpnCppFile << "\t\t&(P->_PL_"<<plit.name << ")," << endl;
    1002             :                 }
    1003           0 :                 SpnCppFile << "\t\t};" << endl;
    1004             : 
    1005           0 :                 SpnCppFile << "\t\tconst vector<size_t> v = getPerm(vClasse, Color_"<< cc.name <<"_Total);"<< endl;
    1006           0 :                 SpnCppFile << "\t\tapplyPerm(vClasse, Color_"<< cc.name <<"_Total, v);"<<endl;
    1007           0 :                 SpnCppFile << "\t}"<< endl;
    1008             :             }
    1009          33 :         SpnCppFile << "}";
    1010             : 
    1011             : 
    1012          33 :         if(P.modelType != External /*&& P.modelType != GSPN_Simulink*/ ){
    1013          33 :             SpnCppFile << "bool abstractBinding::next() {\n";
    1014          33 :             if(!P.is_domain_impl_set){
    1015          29 :                 SpnCppFile << "\tidcount++;\n";
    1016          37 :                 for (vector<colorVariable>::const_iterator colvar = MyGspn.colVars.begin() ; colvar != MyGspn.colVars.end(); ++colvar) {
    1017           8 :                     SpnCppFile << "\tif(P->" << colvar->name << ".mult >= 0){\n";
    1018           8 :                     SpnCppFile << "\t\tif (! P->"<< colvar->name << ".islast()){";
    1019           8 :                     SpnCppFile << "\tP->"<< colvar->name << ".iter(); return true; };\n";
    1020           8 :                     SpnCppFile << "\t\tP->"<< colvar->name << " = "<< MyGspn.colDoms[colvar->type].tokname() << "();\n";
    1021           8 :                     SpnCppFile << "\t}\n";
    1022             :                 }
    1023             :             }
    1024          33 :             SpnCppFile << "\treturn false;\n};\n";
    1025             : 
    1026             : 
    1027          33 :             SpnCppFile << "abstractBinding::abstractBinding() {\n";
    1028          33 :             if(MyGspn.isColored())SpnCppFile << " P= new abstractBindingImpl;\n";
    1029          33 :             SpnCppFile << "       idcount=0;\n";
    1030          33 :             SpnCppFile << "}\n";
    1031             : 
    1032          33 :             SpnCppFile << "abstractBinding::abstractBinding(const abstractBinding& m) {\n";
    1033          33 :             if(MyGspn.isColored())SpnCppFile << " P= new abstractBindingImpl;\n";
    1034          33 :             if(MyGspn.isColored())SpnCppFile << " *P = *m.P;\n";
    1035          33 :             SpnCppFile << "\tidcount = m.idcount;\n";
    1036          33 :             SpnCppFile << "}\n";
    1037             : 
    1038          33 :             SpnCppFile << "abstractBinding::~abstractBinding() {\n";
    1039          33 :             if(MyGspn.isColored())SpnCppFile << " delete P;\n";
    1040          33 :             SpnCppFile << "}\n";
    1041             : 
    1042          33 :             SpnCppFile << "abstractBinding& abstractBinding::operator = (const abstractBinding& m) {\n";
    1043          33 :             if(MyGspn.isColored())SpnCppFile << " *P = *m.P;\n";
    1044          33 :             SpnCppFile << "\tidcount = m.idcount;\n";
    1045          33 :             SpnCppFile << "       return *this;\n";
    1046          33 :             SpnCppFile << "}\n";
    1047             : 
    1048          33 :             SpnCppFile << "void abstractBinding::print()const{\n";
    1049             :             //SpnCppFile << "\tstd::cerr << \"Binding:\"<< std::endl;\n";
    1050          45 :             for (vector<colorVariable>::const_iterator colvar = MyGspn.colVars.begin() ; colvar != MyGspn.colVars.end(); ++colvar) {
    1051             : 
    1052          12 :                 SpnCppFile << "\tstd::cerr << \"\\t"<< colvar->name <<": \";\n";
    1053          12 :                 if (P.verbose > 6) {
    1054           0 :                     SpnCppFile << "\tstd::cerr << \"(v: \" << ( (int) P->"<< colvar->name << ".c0 ) << \") \";\n";
    1055             :                 }
    1056          12 :                 SpnCppFile << "\tP->"<< colvar->name << ".print(std::cerr);\n"; //\tcerr << endl;\n
    1057             :             }
    1058          33 :             SpnCppFile << "}\n";
    1059             : 
    1060          33 :             SpnCppFile << "size_t abstractBinding::id()const{\n";
    1061             :             /*for (vector<colorVariable>::const_iterator colvar = MyGspn.colVars.begin() ; colvar != MyGspn.colVars.end(); ++colvar) {
    1062             :              SpnCppFile << "\tstd::cerr << \"\\t"<< colvar->name <<": \";";
    1063             :              SpnCppFile << "P->"<< colvar->name << ".print();\n\tcerr << endl;\n";
    1064             :              }*/
    1065          33 :             SpnCppFile << "\treturn idcount;\n}\n";
    1066             : 
    1067          33 :             SpnCppFile << "size_t abstractBinding::idTotal()const{\n";
    1068          33 :             SpnCppFile << "\t return ";
    1069          33 :             if(!P.is_domain_impl_set){
    1070          37 :                 for (let colvar : MyGspn.colVars) {
    1071           8 :                     SpnCppFile << "P->"<< colvar.name << ".c0 + Color_"<< MyGspn.colDoms[colvar.type].name << "_Total *(";
    1072             :                 }
    1073          29 :                 SpnCppFile << "0";
    1074          29 :                 for (int i=0; i< MyGspn.colVars.size() ;i++) SpnCppFile << ")";
    1075           4 :             } else SpnCppFile << "0";
    1076          33 :             SpnCppFile << ";\n}\n";
    1077             :         }
    1078             :     }
    1079             : 
    1080          33 : }
    1081             : 
    1082          33 : void Gspn_Writer::writeSynchronisation(std::ofstream &)const{
    1083          66 :     ofstream f(P.tmpPath+"/multimodel.cpp" , ios::out | ios::trunc);
    1084          33 :     f << "#include \"EventsQueue.hpp\"\n";
    1085          33 :     f << "#include \"markingImpl.hpp\"\n";
    1086          33 :     f << "#include \"stateImpl.hpp\"\n";
    1087          33 :     f << "#include \"MultiModel.hpp\"\n";
    1088             : 
    1089          33 :     f << "namespace hybridVar {" << endl;
    1090             :     //if (!MyGspn.hybridVars.empty()){
    1091          33 :     for(const auto &v:MyGspn.hybridVars)
    1092           0 :         f << "extern " << (v.type == CV_INT? "\tint ":"\tdouble ") << v.name << ";" << endl; // We let the GSPN set the initial value.
    1093             :     //}
    1094          33 :     f << "}" << endl;
    1095             : 
    1096          33 :     f << "template<typename EQT, typename M1, typename M2>" << endl;
    1097          33 :     f << "void MultiModel<EQT,M1,M2>::synchronize_fire(size_t t){" <<endl;
    1098             :     //f << "cout << \"synchronize(\" << t << \")\" << endl;" << endl;
    1099          66 :     auto ch = casesHandler("t");
    1100          33 :     ch.addDefault("");
    1101             :     //Simulink -> GSPN
    1102          66 :     stringstream newcase;
    1103          33 :     newcase << "{" << endl;
    1104             : 
    1105         543 :     for(let tr : MyGspn.transitionStruct)if(tr.dist.name == "SYNC" && tr.name != "Synctrans"){
    1106             :         //update the marking
    1107           0 :         for (let p : MyGspn.placeStruct) {
    1108             : 
    1109           0 :             if (!MyGspn.access(MyGspn.outArcsStruct,tr.id,p.id).isEmpty) {
    1110           0 :                 let coldom = MyGspn.colDoms[p.colorDom];
    1111           0 :                 ColorClassType cct = Cyclic;
    1112           0 :                 if(!coldom.isUncolored())cct =MyGspn.colClasses[coldom.colorClassIndex[0]].type ;
    1113             : 
    1114             :                 //update for outplace
    1115           0 :                 string signal =  tr.dist.Param.begin()->to_string();
    1116           0 :                 if(!tr.update.empty()){
    1117           0 :                     newcase << "\t{" <<endl << tr.update << endl << "\t}" << endl;
    1118             :                 }
    1119           0 :                 else if( cct != Continuous) {
    1120           0 :                     newcase << "\tm1.Marking.P->_PL_" << p.name << "= m2.Marking.P->" << signal <<"[m2.Marking.P->lastPrintEntry] ; "  << endl;
    1121             :                 } else {
    1122             :                     //newcase << "\tm1.Marking.P->_PL_" << p.name << ".clear();"<<endl;
    1123             :                     //newcase << "\tm1.Marking.P->_PL_" << p.name << ".insert( std::pair<double,unsigned int>(m2.Marking.P->" << signal <<"[m2.Marking.P->lastPrintEntry],1)) ; "  << endl;
    1124           0 :                     newcase << "\tm1.Marking.P->_PL_" << p.name << "  = "<< coldom.tokname() << "(m2.Marking.P->" << signal <<"[m2.Marking.P->lastPrintEntry]) ; "  << endl;
    1125             :                 }
    1126             :             }
    1127             : 
    1128             :         }
    1129             :     }
    1130          33 :     newcase << "}" << endl;
    1131          33 :     ch.addCase(MyGspn.transitionStruct.size(), newcase.str() , "Simulink -> GSPN");
    1132             : 
    1133             : 
    1134             :     //GSPN -> Simulink
    1135         543 :     for(let tr : MyGspn.transitionStruct)if(tr.dist.name == "SYNC"){
    1136           0 :         stringstream newcase;
    1137           0 :         newcase << "{" << endl;
    1138             : 
    1139             :         //update the marking
    1140           0 :         for (let p : MyGspn.placeStruct) {
    1141             : 
    1142           0 :             if (!MyGspn.access(MyGspn.inArcsStruct,tr.id,p.id).isEmpty) {
    1143             :                 //update for outplace
    1144           0 :                 string blockident =  tr.dist.Param.begin()->to_string();
    1145           0 :                 newcase << "\tm2.setInput(" << blockident << ",m1.Marking.P->_PL_" << p.name << ");" << endl;
    1146             :             }
    1147             : 
    1148             :         }
    1149             : 
    1150           0 :         newcase << "}" << endl;
    1151           0 :         ch.addCase(tr.id, newcase.str() ,tr.name);
    1152             :     }
    1153          33 :     ch.writeCases(f);
    1154          33 :     f << "}\n" << endl;
    1155             : 
    1156          33 :     f << "template<typename EQT, typename M1, typename M2>" << endl;
    1157          33 :     f << "void MultiModel<EQT,M1,M2>::synchronize_update(double ctime, size_t tr, const abstractBinding& b, EQT &EQ, timeGen &TG){" <<endl;
    1158             : 
    1159          66 :         auto chB = casesHandler("tr");
    1160          33 :         chB.addDefault("");
    1161             :         // Simulink -> GSPN
    1162          66 :         stringstream newcaseB;
    1163          33 :         newcaseB << "{" << endl;
    1164          33 :         newcaseB << "\tm1.fire(" << MyGspn.TransId.find("Synctrans")->second << ",b,ctime);" << endl;
    1165          33 :         newcaseB << "\tm1.update(ctime, " << MyGspn.TransId.find("Synctrans")->second << ",b,EQ,TG);" << endl;
    1166          33 :         newcaseB << "}" << endl;
    1167          33 :         chB.addCase(MyGspn.transitionStruct.size(), newcaseB.str() , "Simulink -> GSPN");
    1168             : 
    1169             :         // GSPN -> Simulink
    1170         543 :         for(let tr : MyGspn.transitionStruct)if(tr.dist.name == "SYNC"){
    1171           0 :                 stringstream newcase;
    1172           0 :                 newcase << "{" << endl;
    1173             : 
    1174             :         //update the marking
    1175           0 :         for (let p : MyGspn.placeStruct) {
    1176           0 :             if (!MyGspn.access(MyGspn.inArcsStruct,tr.id,p.id).isEmpty) {
    1177             :                 //update for outplace
    1178           0 :                 string blockident =  tr.dist.Param.begin()->to_string();
    1179           0 :                 newcase << "\tm2.setInput(" << blockident << ",m1.Marking.P->_PL_" << p.name << ");" << endl;
    1180             :             }
    1181             :         }
    1182           0 :                 newcase << "\t\tm2.updateInput(ctime,0,b,EQ,TG);" << endl;
    1183           0 :                 newcase << "}" << endl;
    1184           0 :                 chB.addCase(tr.id, newcase.str() ,tr.name);
    1185             :       }
    1186             : 
    1187          33 :         chB.writeCases(f);
    1188          33 :     f << "}\n" << endl;
    1189             : 
    1190          33 :     f << "template class MultiModel<EventsQueue,SPN_orig<EventsQueue>,SKModel<EventsQueue>>;" << endl;
    1191          33 :     if(P.modelType == GSPN_Simulink)
    1192           0 :         f << "template class MultiModel<EventsQueueSet,SPN_orig<EventsQueueSet>,SKModel<EventsQueueSet>>;" << endl;
    1193             : 
    1194          33 :     f.close();
    1195          33 : }
    1196             : 
    1197          33 : void Gspn_Writer::writeFile(){
    1198             : 
    1199          66 :     string Pref = P.tmpPath;
    1200          66 :     string loc;
    1201             : 
    1202          33 :     generateStringVal(MyGspn.inArcsStruct);
    1203          33 :     generateStringVal(MyGspn.outArcsStruct);
    1204          33 :     generateStringVal(MyGspn.inhibArcsStruct);
    1205         320 :     for(auto &p: MyGspn.placeStruct){
    1206         574 :         stringstream ss;
    1207             :         //writeTok(ss, p.initMarking,MyGspn.colDoms[p.colorDom]);
    1208         287 :         p.Marking = expr((string)"FAIL Marking");  // ss.str();
    1209             :     }
    1210             : 
    1211             :     //loc = Pref + "../SOURCES/Cosmos/spn.cpp";
    1212          33 :     loc = Pref + "/spn.cpp";
    1213             : 
    1214             :     //loc= "/Users/barbot/Documents/Cosmos/SOURCES/Cosmos/spn.cpp";
    1215          66 :     ofstream SpnCppFile(loc.c_str(), ios::out | ios::trunc);
    1216             :     // ouverture en écriture avec effacement du SpnCppFile ouvert
    1217             :     //cout << loc << endl;
    1218             : 
    1219          66 :     string headerloc = Pref + "/markingImpl.hpp";
    1220          66 :     ofstream header(headerloc.c_str(), ios::out | ios::trunc);
    1221          33 :     header << "#ifndef _MarkingImpl_HPP" << endl;
    1222          33 :     header << "#define    _MarkingImpl_HPP" << endl;
    1223             : 
    1224          33 :     if(P.lightSimulator){
    1225           0 :         loc = Pref + "/macro.h";
    1226           0 :         ofstream macroF(loc.c_str(),ios::out | ios::trunc);
    1227           0 :         macroF << "#define NB_EVENT " << MyGspn.tr << endl;
    1228           0 :         if(!P.StringInSpnLHA)macroF << "#define NO_STRING_SIM" <<endl;
    1229           0 :         macroF << "#define FAST_SIM" << endl;
    1230           0 :         macroF << "#define TR_PL_ID unsigned char" << endl;
    1231           0 :         macroF << "#define REAL_TYPE float" << endl;
    1232           0 :         macroF << "#define VERBOSE_LEVEL " << P.verbose << endl;
    1233             : 
    1234           0 :         macroF << "#define uint8 unsigned char" << endl;
    1235           0 :         macroF << "#define uint16 unsigned int" << endl;
    1236           0 :         macroF << "#define uint32 unsigned long" << endl;
    1237           0 :         macroF.close();
    1238             :     }
    1239             : 
    1240             :     //SpnCppFile << "#include \"spn_orig.hpp\"" << endl;
    1241          33 :     if(P.lightSimulator){
    1242           0 :         SpnCppFile << "#include \"spnLight.hpp\"" << endl;
    1243             :     }else{
    1244          33 :         SpnCppFile << "#include \"spn.hpp\"" << endl;
    1245             :     }
    1246          33 :     if(!P.lightSimulator){
    1247          33 :         SpnCppFile << "#include <iomanip>" << endl;
    1248          33 :         header << "using namespace std;" <<endl;
    1249          33 :         SpnCppFile << "using namespace std;" <<endl;
    1250             :     }
    1251             :     //------------- Writing constant--------------------------------------------
    1252          33 :     writeMacro(SpnCppFile);
    1253         384 :     for (map<string,double>::iterator it= MyGspn.RealConstant.begin();
    1254         256 :          it!= MyGspn.RealConstant.end() ; it++) {
    1255          95 :         SpnCppFile << "const double "<<it->first<<"="<<it->second << ";" << endl;
    1256             :     }
    1257         320 :     for (const auto &plit : MyGspn.placeStruct) {
    1258         287 :         SpnCppFile << "const int _nb_Place_"<< plit.name << "=" << plit.id << ";" << endl;
    1259             :     }
    1260             : 
    1261             :     //------------- Hybrid Variable --------------------------------------------
    1262          33 :     SpnCppFile << "namespace hybridVar {" << endl;
    1263             :     //if (!MyGspn.hybridVars.empty()){
    1264          33 :     for(const auto &v:MyGspn.hybridVars)
    1265           0 :         SpnCppFile << (v.type == CV_INT? "\tint ":"\tdouble ") << v.name << "=" << v.initialValue << ";" << endl;
    1266             :     //}
    1267          33 :     SpnCppFile << "}" << endl;
    1268             : 
    1269             : 
    1270          33 :     if (P.magic_values != "")
    1271           0 :         SpnCppFile << "#include \"" << P.magic_values << "\"" << endl;
    1272          33 :     if(P.RareEvent){
    1273           6 :         SpnCppFile << "#include \"lumpingfun.cpp\"" << endl;
    1274          27 :     }else if(!P.lightSimulator){
    1275          27 :         SpnCppFile << "void "<<"REHandling::"<<"print_state(const vector<int> &vect){}" << endl;
    1276          27 :         SpnCppFile << "void "<<"REHandling::"<<"lumpingFun(const abstractMarking &M,vector<int> &vect){}" << endl;
    1277          27 :         SpnCppFile << "bool "<<"REHandling::"<<"precondition(const abstractMarking &M){return true;}" << endl;
    1278             :     }
    1279             :     //SpnCppFile << "namespace GSPN {" << endl;
    1280             : 
    1281             :     //------------- Writing Marking type and header ----------------------------
    1282          33 :     if(!P.lightSimulator)SpnCppFile << "#include \"marking.hpp\"\n";
    1283          33 :     SpnCppFile << "#include \"markingImpl.hpp\"\n";
    1284          33 :     header << "#include <string.h>\n";
    1285          33 :     writeMarkingClasse(SpnCppFile,header);
    1286          33 :     header << "#endif" << endl;
    1287          33 :     header.close();
    1288             : 
    1289             :     //------------- Writing Color name -----------------------------------------
    1290          45 :     for (let it : MyGspn.colClasses) {
    1291          12 :         if(it.type != ColorClassType::Continuous){
    1292          12 :             SpnCppFile << "const char *Color_"<< it.name << "_names[Color_" << it.name << "_Total] = {\n";
    1293         138 :             for (let it2 : it.colors ) {
    1294         126 :                 SpnCppFile << "\"" << it2.name << "\",";
    1295             :             }
    1296          12 :             SpnCppFile << "\n};\n";
    1297             :         }
    1298             :     }
    1299             : 
    1300             :     //------------ Writing polynomials ------------------------------------------
    1301          33 :     if(!P.lightSimulator && !MyGspn.distribStruct.empty()){
    1302           0 :         if(!userDefineDistribution::polyfile.empty()){
    1303           0 :             writePolynome(SpnCppFile);
    1304             :         }else{
    1305           0 :             writeUserDefineDistr(SpnCppFile);
    1306             :         }
    1307             :     }
    1308             : 
    1309             : 
    1310             : 
    1311             :     //--------------- Writing synchronization tables ---------------------------
    1312             :     //if(!P.lightSimulator)
    1313          33 :     writeEnabledDisabled(SpnCppFile);
    1314          33 :     writeSynchronisation(SpnCppFile);
    1315             : 
    1316             :     //--------------- Writing transitions tables -------------------------------
    1317          33 :     if(!P.lightSimulator){
    1318          33 :         size_t nbbinding = 1;
    1319          45 :         for (size_t v = 0 ; v < MyGspn.colVars.size(); v++)
    1320          12 :             nbbinding *= MyGspn.colClasses[MyGspn.colDoms[MyGspn.colVars[v].type].colorClassIndex[0]].colors.size();
    1321          33 :         SpnCppFile << "static spn_trans TransArray[" << MyGspn.tr << "] = { ";
    1322         543 :         for (size_t t=0; t < MyGspn.tr; t++ ) {
    1323         510 :             SpnCppFile << "_trans(" << t << ",";
    1324             : 
    1325             : 
    1326         510 :             SpnCppFile  << MyGspn.transitionStruct[t].dist.name << ",";
    1327             : 
    1328         510 :             if (!P.is_domain_impl_set) {
    1329         484 :                 SpnCppFile << MyGspn.transitionStruct[t].markingDependant << ","<< nbbinding;
    1330             :             } else {
    1331          26 :                 SpnCppFile << MyGspn.transitionStruct[t].markingDependant << ",1";
    1332             :             }
    1333         510 :             SpnCppFile << ", " << MyGspn.transitionStruct[t].ageMemory;
    1334         510 :             if(P.StringInSpnLHA)SpnCppFile << ", \"" << MyGspn.transitionStruct[t].name<< "\"";
    1335         510 :             SpnCppFile <<"), ";
    1336             :         }
    1337          33 :         SpnCppFile << " }; " << endl;
    1338             :     }
    1339             : 
    1340             :     //--------------- Writing implementation of SPN ----------------------------
    1341          33 :     SpnCppFile << objName<<"SPN():" << endl;
    1342          33 :     if(!MyGspn.distribStruct.empty()){
    1343           0 :         if(!userDefineDistribution::polyfile.empty()){
    1344           0 :             SpnCppFile << "customDistr(*(new CustomDistrPoly())),";
    1345             :         }else{
    1346           0 :             SpnCppFile << "customDistr(*(new CustomDistrOverride())),";
    1347             :         }
    1348             :     }else{
    1349          33 :         SpnCppFile << "customDistr(*(new CustomDistr())),";
    1350             :     }
    1351             : 
    1352          33 :     SpnCppFile << "pl(" << MyGspn.pl << "), ";
    1353          33 :     SpnCppFile << "tr(" << MyGspn.tr << ") ";
    1354          33 :     if(!P.lightSimulator){
    1355          33 :         SpnCppFile << ",Transition(TransArray,TransArray +"<< MyGspn.tr <<")";
    1356          33 :         SpnCppFile << ",Place("<< MyGspn.pl << ")";
    1357          33 :         SpnCppFile << ",ParamDistr()";
    1358          33 :         SpnCppFile << ",TransitionConditions(" << MyGspn.tr <<",0)";
    1359             :     }
    1360             : 
    1361          33 :     SpnCppFile << "{" << endl;
    1362          33 :     if(!P.lightSimulator)SpnCppFile << "    Path =\"" << P.PathGspn << "\";" << endl;
    1363             : 
    1364             : 
    1365          33 :     if(P.localTesting){
    1366           0 :         SpnCppFile << "\tsetConditionsVector();"<< endl;
    1367           0 :         SpnCppFile << "\tinitTransitionConditions = TransitionConditions;" << endl;
    1368             :     }
    1369             : 
    1370         320 :     for (const auto &plit : MyGspn.placeStruct) {
    1371         287 :         if(P.StringInSpnLHA && !P.lightSimulator){
    1372          32 :             SpnCppFile << "    Place[" << plit.id << "].label =\" " << plit.name << "\";" << endl;
    1373          32 :             SpnCppFile << "    Place[" << plit.id << "].isTraced = " << plit.isTraced << ";" << endl;
    1374             :         }
    1375             :     }
    1376             : 
    1377          33 :     writeTransition(SpnCppFile);
    1378             : 
    1379             :     //-------------- Rare Event -----------------
    1380          33 :     if(P.RareEvent || P.computeStateSpace>0){
    1381           9 :         SpnCppFile << "\tMsimple();" << endl;
    1382             :     }
    1383             :     //------------- /Rare Event -----------------
    1384             : 
    1385          33 :     SpnCppFile << "}\n" << endl;
    1386             : 
    1387          33 :     if(P.lightSimulator){
    1388           0 :         SpnCppFile << "TR_PL_ID SPN::getIncomingTrans(){ return ";
    1389           0 :         if(MyGspn.TransId.count("INCOMING_SREC")>0){
    1390           0 :             SpnCppFile << "TR_INCOMING_SREC_RT;};\n"<< endl;
    1391             :         } else {
    1392           0 :             SpnCppFile << "UNSET_TRANS;};\n"<< endl;
    1393             :         }
    1394             :     }
    1395             : 
    1396          33 :     writeIsEnabled(SpnCppFile);
    1397          33 :     writeFire(SpnCppFile);
    1398          33 :     writeSetConditionsVector(SpnCppFile);
    1399          33 :     writeGetDistParameters(SpnCppFile);
    1400          33 :     writeGetPriority(SpnCppFile);
    1401          33 :     writeGetWeight(SpnCppFile);
    1402             : 
    1403          33 :     if(!P.lightSimulator){
    1404          33 :         SpnCppFile << "void "<<objName<<"Msimple(){"<<endl;
    1405          33 :         SpnCppFile << "\tvector<int> tab;"<<endl;
    1406         320 :         for (const auto &p : MyGspn.placeStruct) {
    1407         287 :             if(p.name.substr(0,3).compare("RE_") == 0)
    1408          18 :                 SpnCppFile << "\t\ttab.push_back("<< p.id << ");" << endl;
    1409             :         }
    1410          33 :         SpnCppFile << "\tMsimpletab = tab;\n}"<< endl;
    1411             :     }
    1412             : 
    1413          33 :     SpnCppFile << "void "<<objName<<"reset() {"<< endl;
    1414          33 :     SpnCppFile << "\tlastTransitionTime = 0;"<< endl;
    1415          33 :     SpnCppFile << "\tMarking.resetToInitMarking();"<< endl;
    1416          33 :     if(P.localTesting)SpnCppFile << "\tTransitionConditions = initTransitionConditions;"<< endl;
    1417          33 :     SpnCppFile << "}"<< endl<< endl;
    1418             : 
    1419             :     //SpnCppFile << "}" << endl;
    1420          33 :     SpnCppFile.close();
    1421          33 : }
    1422             : 
    1423           0 : void Gspn_Writer::writeUserDefineDistr(ofstream &f)const{
    1424           0 :     f << "class CustomDistrOverride: public CustomDistr {" << endl;
    1425           0 :     f << "public:"<< endl;
    1426           0 :     f << "double virtual userDefineCDF(const std::array<double,PARAM_TBL_SIZE> & param, double funvar)const override{" <<endl;
    1427             :     {
    1428             :         //f<< "std::cerr << \"test\" << std::endl;"<<endl;
    1429           0 :         auto ch = casesHandler("(int)param[0]");
    1430           0 :         for (size_t it=0; it<MyGspn.distribStruct.size(); ++it) {
    1431           0 :             const auto &dist = MyGspn.distribStruct[it];
    1432           0 :             stringstream newcase;
    1433           0 :             newcase << "\t{" << endl;
    1434           0 :             newcase << "\t\tdouble " << dist.var << " = funvar;" << endl;
    1435           0 :             newcase << "\t\treturn (" << dist.cdf << ");" << endl;
    1436           0 :             newcase << "\t}" << endl;
    1437           0 :             ch.addCase(it , newcase.str(),dist.name);
    1438             :         }
    1439           0 :         ch.writeCases(f);
    1440           0 :         f << "}\n" << endl;
    1441             :     }
    1442             :     {
    1443           0 :         f << "double virtual userDefinePDF(const std::array<double,PARAM_TBL_SIZE> & param, double funvar)const override{" <<endl;
    1444           0 :         auto ch = casesHandler("(int)param[0]");
    1445           0 :         for (size_t it=0; it<MyGspn.distribStruct.size(); ++it) {
    1446           0 :             const auto &dist = MyGspn.distribStruct[it];
    1447           0 :             stringstream newcase;
    1448           0 :             newcase << "\t{" << endl;
    1449           0 :             newcase << "\t\tdouble " << dist.var << " = funvar;" << endl;
    1450           0 :             newcase << "\t\treturn (" << dist.pdf << ");" << endl;
    1451           0 :             newcase << "\t}" << endl;
    1452           0 :             ch.addCase(it , newcase.str(),dist.name);
    1453             :         }
    1454           0 :         ch.writeCases(f);
    1455           0 :         f << "}\n" << endl;
    1456             :     }
    1457             :     {
    1458           0 :         f << "double virtual userDefineLowerBound(const std::array<double,PARAM_TBL_SIZE> & param)const override{" <<endl;
    1459           0 :         auto ch = casesHandler("(int)param[0]");
    1460           0 :         for (size_t it=0; it<MyGspn.distribStruct.size(); ++it) {
    1461           0 :             const auto &dist = MyGspn.distribStruct[it];
    1462           0 :             stringstream newcase;
    1463           0 :             newcase << "\t\treturn (" << dist.lowerBound << ");" << endl;
    1464           0 :             ch.addCase(it , newcase.str(),dist.name);
    1465             :         }
    1466           0 :         ch.writeCases(f);
    1467           0 :         f << "}\n" << endl;
    1468             :     }
    1469             :     {
    1470           0 :         f << "double virtual userDefineUpperBound(const std::array<double,PARAM_TBL_SIZE> & param)const override{" <<endl;
    1471           0 :         auto ch = casesHandler("(int)param[0]");
    1472           0 :         for (size_t it=0; it<MyGspn.distribStruct.size(); ++it) {
    1473           0 :             const auto &dist = MyGspn.distribStruct[it];
    1474           0 :             stringstream newcase;
    1475           0 :             newcase << "\t\treturn (" << dist.upperBound << ");" << endl;
    1476           0 :             ch.addCase(it , newcase.str(),dist.name);
    1477             :         }
    1478           0 :         ch.writeCases(f);
    1479           0 :         f << "}\n" << endl;
    1480             :     }
    1481             : 
    1482             :     {
    1483           0 :         f << "double virtual userDefineDiscreteDistr(const std::array<double,PARAM_TBL_SIZE> & param,unsigned int i)const override{" <<endl;
    1484           0 :         if( any_of(MyGspn.transitionStruct.begin(),MyGspn.transitionStruct.end(),[](const transition &t){return t.dist.name == "DISCRETEUSERDEFINE";})){
    1485           0 :             f << "\treturn (magicUDDD(param,i));" << endl;
    1486             :         } else {
    1487           0 :             f << "\treturn (0.0);" << endl;
    1488             :         }
    1489           0 :         f << "}\n" << endl;
    1490             :     }
    1491           0 :     f << "};" << endl;
    1492           0 : }
    1493             : 
    1494           0 : void Gspn_Writer::writePolynome(ofstream &f)const{
    1495           0 :     if(MyGspn.distribStruct.empty())return;
    1496           0 :     size_t n = userDefineDistribution::nbparam;
    1497             : 
    1498           0 :     f << "#include \"Polynome.hpp\""<< endl;
    1499           0 :     f << "class CustomDistrPoly: public CustomDistr {" << endl;
    1500           0 :     f << "\tconst static int poly_table[];" << endl;
    1501           0 :     f << "\tvector<Poly<"<<n<<">> ptable;" << endl;
    1502           0 :     f << "public:" << endl;
    1503           0 :     f << "\tCustomDistrPoly(){" << endl;
    1504           0 :     f << "\t\tptable = parse<"<<n<<">(\""<< userDefineDistribution::polyfile <<"\");"<<endl;
    1505           0 :     f << "\t}" << endl;
    1506             : 
    1507           0 :     f << "\tdouble virtual userDefineCDF(const std::array<double,PARAM_TBL_SIZE> & param, double funvar)const override{" <<endl;
    1508           0 :     if(P.verbose>4){
    1509           0 :       f << "\t\tcerr << \"Evaluating CDF with parameters {\"";
    1510           0 :       for(int i=0;i<n;i++) f << " << param[" << i << "] << \", \"";
    1511           0 :       f << " \"}\" << endl;" << endl;
    1512             :     }
    1513             :     //f << "\tparam[0]=funvar;" << endl;
    1514           0 :     f << "\t\treturn (eval(ptable[poly_table[ 5*((int)param[0]) ]],param,funvar)/eval(ptable[poly_table[ 5*((int)param[0])+2 ]],param,funvar))  ;"<< endl;
    1515           0 :     f << "\t}"<<endl;
    1516             : 
    1517           0 :     f << "\tdouble  virtual userDefinePDF(const std::array<double,PARAM_TBL_SIZE> & param, double funvar)const override{" <<endl;
    1518             :     //f << "\tparam[0]=funvar;" << endl;
    1519           0 :     f << "\t\treturn (eval(ptable[poly_table[ 5*((int)param[0])+1 ]],param,funvar)/eval(ptable[poly_table[ 5*((int)param[0])+2 ]],param,funvar))  ;"<< endl;
    1520           0 :     f << "\t}"<<endl;
    1521             : 
    1522             :     {
    1523           0 :         f << "\tdouble virtual userDefineLowerBound(const std::array<double,PARAM_TBL_SIZE> & param)const override{" <<endl;
    1524           0 :         f << "\t\treturn eval(ptable[poly_table[ 5*((int)param[0])+3 ]],param);" << endl;
    1525           0 :         f << "\t}\n" << endl;
    1526             :     }
    1527             :     {
    1528           0 :         f << "\tdouble virtual userDefineUpperBound(const std::array<double,PARAM_TBL_SIZE> & param)const override{" <<endl;
    1529           0 :         f << "\t\treturn eval(ptable[poly_table[ 5*((int)param[0])+4] ],param);" << endl;
    1530           0 :         f << "\t}\n" << endl;
    1531             :     }
    1532             : 
    1533             :     {
    1534           0 :         f << "\tdouble virtual userDefineDiscreteDistr(const std::array<double,PARAM_TBL_SIZE> & param,unsigned int i)const override{" <<endl;
    1535           0 :         if( any_of(MyGspn.transitionStruct.begin(),MyGspn.transitionStruct.end(),[](const transition &t){return t.dist.name == "DISCRETEUSERDEFINE";})){
    1536           0 :             f << "\t\treturn (magicUDDD(param,i));" << endl;
    1537             :         } else {
    1538           0 :             f << "\t\treturn (0.0);" << endl;
    1539             :         }
    1540           0 :         f << "\t}\n" << endl;
    1541             :     }
    1542             : 
    1543           0 :     f << "\tconst std::string print_poly(unsigned long i)const override {"<<endl;
    1544           0 :     f << "\t\tstringstream ss;" << endl;
    1545           0 :     f << "\t\tss << \"[\" << ptable[poly_table[ 5*i+3 ]] << \"; (\" << ptable[poly_table[ 5*i]]<< \")/(\"<< ptable[poly_table[ 5*i+2 ]] <<\"); \" << ptable[poly_table[ 5*i+4 ]] << \"]\" ;" << endl;
    1546           0 :     f << "\t\treturn ss.str();};" << endl;
    1547             : 
    1548             : 
    1549           0 :     f << "\tdouble virtual evalPoly(unsigned long i,const std::array<double,PARAM_TBL_SIZE> & param)const override{"<< endl;
    1550           0 :     if(P.verbose>4)f << "\t\tcerr << \"Evaluating poly \" << i <<\":\"<< ptable[i] << endl;" << endl;
    1551           0 :     f << "\t\treturn eval(ptable[i],param);"<< endl;
    1552           0 :     f << "\t}"<< endl;
    1553             : 
    1554           0 :     f << "};" << endl;
    1555             : 
    1556           0 :     f << "const int CustomDistrPoly::poly_table[]= { " << endl;
    1557           0 :     for ( let d : MyGspn.distribStruct) {
    1558           0 :         f << d.cdf <<"," ;
    1559           0 :         f << d.pdf <<"," ;
    1560           0 :         f << d.norm << "," ;
    1561           0 :         f << d.lowerBound << "," ;
    1562           0 :         f << d.upperBound << "," ;
    1563             :     }
    1564           0 :     f << "};" << endl;
    1565             : 
    1566         105 : }

Generated by: LCOV version 1.13