40 using std::ostream_iterator;
    51     verbosity(0), title(_title), cTA(NULL), cP(NULL), inp(false), out(false),
    52     sync(false), paramsExpanded(false)
    60     for (list<instance_t>::iterator it=ps.begin(), e=ps.end(); it!=e; ++it)
    68     for (procs_t::const_iterator p=
procs.begin(), e=
procs.end(); p!=e; ++p)
    70         os << (*p)->name << 
":\n  "; 
    72         for_each((*p)->inChans.begin(), (*p)->inChans.end(),
    76         for_each((*p)->outChans.begin(), (*p)->outChans.end(),
    79         str2strs_t::const_iterator v;
    81         for (v = (*p)->rdVars.begin(); v != (*p)->rdVars.end(); ++v)
    83             os << 
" " << v->first << 
"(";
    84             for_each(v->second.begin(), v->second.end(),
    90         for (v = (*p)->wtVars.begin(); v != (*p)->wtVars.end(); ++v)
    92             os << 
" " << v->first << 
"(";
    93             for_each(v->second.begin(), v->second.end(),
   104     os << 
"  subgraph procs {\n";
   107         os<<
"    node [shape=rectangle,style=filled];\n";
   111         os<<
"    node [shape=ellipse,style=filled];\n";
   115     for (procs_t::const_iterator p=
procs.begin(), e=
procs.end(); p!=e; ++p)
   116         os << (*p)->name << 
"; ";
   124     os << 
"  subgraph cluste_vars {\n";
   125     os << 
"    style=invis;\n";
   128         os << 
"    rank=min;\n";
   132         os << 
"    node [shape=diamond,color=blue];\n    ";
   136         os << 
"    node [shape=rectangle,color=blue];\n    ";
   147             os << *i << 
"[style=bold]; "; 
   156     os<<
"  edge [style=bold,color=blue,fontcolor=blue,weight=100];\n";
   158     for (procs_t::const_iterator a=
procs.begin(), ae=
procs.end(); a!=ae; ++a)
   160         if (!(*a)->wtVars.empty())
   162             for (str2strs_t::const_iterator v=(*a)->wtVars.begin(),
   163                      ve=(*a)->wtVars.end(); v!=ve; ++v)
   165                 os<<
"  "<<(*a)->name<< 
" -> " << v->first << 
" [label=\"(";
   167                 for_each(v->second.begin(), v->second.end(),
   178     os<<
"  edge [style=solid,color=blue,fontcolor=blue,weight=1];\n";
   180     for (procs_t::const_iterator a=
procs.begin(),ae=
procs.end(); a!=ae; ++a)
   182         if (!(*a)->rdVars.empty())
   184             for (str2strs_t::const_iterator v = (*a)->rdVars.begin(),
   185                      ve=(*a)->rdVars.end(); v!=ve; ++v)
   187                 os<<
"  " << v->first << 
" -> " <<(*a)->name<<
" [label=\"(";
   189                 for_each(v->second.begin(), v->second.end(),
   200     const char* src = 
"NO_SRC";
   201     const char* dst = 
"NO_DST";
   203     for (procs_t::const_iterator a=
procs.begin(),ae=
procs.end(); a!=ae; ++a)
   206         for (strs_t::const_iterator i=(*a)->outChans.begin(), 
   207                  e=(*a)->outChans.end(); i!=e; ++i)
   209             str2procs_t::const_iterator dests = 
receivers.find(*i);
   212                 for (procs_t::const_iterator rec = dests->second.begin();
   213                      rec != dests->second.end(); ++rec)
   215                     (*a)->outEdges[*rec].insert(*i);
   220                 (*a)->outEdges[NULL].insert(*i);
   226     os<<
"  edge[style=solid,color=black,fontcolor=black,weight=50];\n";
   227     for (procs_t::const_iterator a=
procs.begin(),ae=
procs.end(); a!=ae; ++a)
   230         for (proc2strs_t::const_iterator edge = (*a)->outEdges.begin(),
   231                  edgeEnd=(*a)->outEdges.end(); edge!=edgeEnd; ++edge)
   234             if (edge->first != NULL)
   237                 os<<
"  " <<(*a)->name << 
" -> " << edge->first->name
   245                       <<
" [style=filled,fillcolor=red];\n";
   248                 os<<
"  " <<(*a)->name << 
" -> " << dst
   252             strs_t::const_iterator 
ch=edge->second.begin();
   257                     if (ch != edge->second.end())
   271         for (strs_t::const_iterator i=(*a)->inChans.begin(), 
   272                  e=(*a)->inChans.end(); i!=e; ++i)
   274             str2procs_t::const_iterator trans = 
transmitters.find(*i);
   280                       <<
" [style=filled,fillcolor=red];\n";
   283                 os<<
"  "<<src<<
" -> " << (*a)->name << 
" [label=\""   293     os<< 
"  subgraph cluste_chans {\n";
   294     os<< 
"    style=invis;\n";
   301         os<<
"    node [shape=diamond,color=red];\n    ";
   305         os<<
"    node [shape=diamond,color=red];\n    ";
   311     for (procs_t::const_iterator a=
procs.begin(),ae=
procs.end(); a!=ae; ++a)
   313         for (strs_t::const_iterator i=(*a)->inChans.begin(), 
   314                  e=(*a)->inChans.end(); i!=e; ++i)
   316             os << 
"  " << *i << 
" -> " << (*a)->name << 
";\n";
   318         for (strs_t::const_iterator i=(*a)->outChans.begin(),
   319                  e=(*a)->outChans.end(); i!=e; ++i)
   321             os << 
"  " << (*a)->name << 
" -> " << *i << 
" [style=bold];\n";
   328     char* name = strcpy(
new char[strlen(
title)+1], 
title);
   329     for (uint32_t i=0, len=strlen(name); i<len; ++i)
   331         if (!isalpha((
unsigned char)name[i])) 
   337     os << 
"digraph " << name << 
" {\n";
   338     os << 
"  model=subset; remincross=true;\n";
   366             map<symbol_t, expression_t>::iterator e = 
cP->
mapping.find(s);
   375                 cerr << 
"mapping param '"<< s.
getName() << 
"' failed"<<endl;
   397     strs_t::iterator it = 
channels.find(s.c_str());
   399         s2 = strdup(s.c_str());
   403     index[s2].insert(
cTA);
   427     deque<state_t>::const_iterator s = temp->
states.begin();
   428     while (s != temp->
states.end())
   434     deque<edge_t>::const_iterator t; 
   435     for (t = temp->
edges.begin(); t != temp->
edges.end(); ++t)
   481         for (uint32_t i=0; i<e.
getSize(); ++i)
   511         inp = 
false; 
out = 
true;
   513         for (uint32_t i=1; i<e.
getSize(); ++i)
   540                 exprref_t::const_iterator exi = 
refparams.top().find(sym);
   564             std::ostringstream os;
   573         for (uint32_t i=1; i<e.
getSize(); ++i)
   599         for (uint32_t i=0; i<e.
getSize(); ++i)
   607         for (uint32_t i=0; i<e.
getSize(); ++i)
   615         for (uint32_t i=1; i<e.
getSize(); ++i)
   625         for (uint32_t i=0; i<e.
getSize()-1; ++i)
   672         for (
size_t i=0; i<e.
getSize()-1; ++i) {
   685         cerr << 
"unsupported kind (" << e.
getKind()
   686              << 
") of expression, please report it to developers."<<endl;
   733     while (it != stat->
end())
   735         res = (*it)->accept(
this);
   791     procs_t::const_iterator p;
   792     for (p = 
procs.begin(); p != 
procs.end(); ++p) 
delete *p;
   793     strs_t::const_iterator c;
   799     strs_t::const_iterator s;
   800     for (s=chansInp.begin(); s!=chansInp.end(); ++s) 
free((
char*)*s);
   801     for (s=chansOut.begin(); s!=chansOut.end(); ++s) 
free((
char*)*s);
   802     chansInp.clear(); chansOut.clear();
   808         cerr << 
"Violated rule \"" << rule << 
"\" for process \""   809              << proc->
name << 
"\" accessing \"" << var << 
"\"" << endl;
   821     for (strs_t::const_iterator c=chans.begin(), ce=chans.end(); c!=ce; ++c)
   823         str2procs_t::const_iterator c2p;
   824         c2p = index.find(*c);
   825         if (c2p != index.end()) {
   826             for (procs_t::const_iterator p=c2p->second.begin(),
   827                      pe=c2p->second.end(); p!=pe; ++p)
   829                 if (exclude.erase(*p) > 0) {
   831                     printViolation(*p, *c);
   832                 } 
else if (result.find(*p) == result.end() &&
   833                            procsBad.find(*p) == procsBad.end()) {
   836                         cerr << 
"Adding \""<<(*p)->name <<
"\" using \""<<(*c)
   837                              <<
"\" by rule \""<<rule<<
"\""<<endl;
   853     for (procs_t::const_iterator p=procs.begin(), pe=procs.end(); p!=pe; ++p)
   855         for (strs_t::const_iterator c=(*p)->inChans.begin(),
   856                  ce=(*p)->inChans.end(); c!=ce; ++c)
   858             if (observable.find(*c) == observable.end()) {
   859                 if (exclude.erase(*c) > 0) {
   861                     printViolation(*p, *c);
   862                 } 
else if (result.find(*c) == result.end() &&
   863                            chansBad.find(*c) == chansBad.end()) {
   865                         cerr << 
"Adding \""<<(*c)<<
"\" because of \""   866                              <<(*p)->name <<
"\" by rule \""<<rule
   872         for (strs_t::const_iterator c=(*p)->outChans.begin(),
   873                  ce=(*p)->outChans.end(); c!=ce; ++c)
   875             if (observable.find(*c) == observable.end()) {
   876                 if (exclude.erase(*c) > 0) {
   878                     printViolation(*p, *c);
   879                 } 
else if (result.find(*c) == result.end() &&
   880                            chansBad.find(*c) == chansBad.end()) {
   882                         cerr << 
"Adding \""<<(*c)<<
"\" because of \""   883                              <<(*p)->name <<
"\" by rule \""<<rule
   899     for (procs_t::const_iterator p=procs.begin(), pe=procs.end(); p!=pe; ++p)
   902         for (str2strs_t::const_iterator v2c=(*p)->rdVars.begin(),
   903                  v2ce=(*p)->rdVars.end(); v2c!=v2ce; ++v2c)
   905             if (!includes(observable.begin(), observable.end(),
   906                           v2c->second.begin(), v2c->second.end(), 
less_str()))
   908                 if (exclude.erase(v2c->first) > 0) {
   909                     varsBad.insert(v2c->first);
   910                     printViolation(*p, v2c->first);
   911                 } 
else if (result.find(v2c->first) == result.end() &&
   912                            varsBad.find(v2c->first) == varsBad.end()) {
   914                         cerr << 
"Adding \""<<(v2c->first)<<
"\" because of \""   915                              <<(*p)->name <<
"\" by rule \""<<rule<<
"\""<<endl;
   916                     result.insert(v2c->first);
   920         for (str2strs_t::const_iterator v2c=(*p)->wtVars.begin(),
   921                  v2ce=(*p)->wtVars.end(); v2c!=v2ce; ++v2c)
   923             if (!includes(observable.begin(), observable.end(),
   924                           v2c->second.begin(), v2c->second.end(), 
less_str()))
   926                 if (exclude.erase(v2c->first) > 0) {
   927                     varsBad.insert(v2c->first);
   928                     printViolation(*p, v2c->first);
   929                 } 
else if (result.find(v2c->first) == result.end() &&
   930                            varsBad.find(v2c->first) == varsBad.end()) {
   932                         cerr << 
"Adding \""<<(v2c->first)<<
"\" because of \""   933                              <<(*p)->name <<
"\" by rule \""<<rule<<
"\""<<endl;
   934                     result.insert(v2c->first);
   948     str2procs_t::const_iterator v2p;
   949     str2strs_t::const_iterator v2c;
   950     for (strs_t::const_iterator v=vars.begin(), ve=vars.end(); v!=ve; ++v)
   954             for(procs_t::const_iterator p=v2p->second.begin(),
   955                     pe=v2p->second.end(); p!=pe; ++p)
   957                 v2c = (*p)->rdVars.find(*v);
   958                 if (v2c != (*p)->rdVars.end()) {
   959                     if (!includes(observable.begin(), observable.end(),
   960                                   v2c->second.begin(), v2c->second.end(),
   963                         if (exclude.erase(*p) > 0) {
   965                             printViolation(*p, *v);
   966                         } 
else if (procs.find(*p) == procs.end() &&
   967                                    procsBad.find(*p) == procsBad.end()) {
   969                                 cerr << 
"Adding \""<<(*p)->name
   970                                      <<
"\" using \""<<(*v)
   971                                      <<
"\" by rule \""<<rule<<
"\""<<endl;
   977                         cerr<<
"addProcsByVars could not find in rdVars"<<endl;
   982                 cerr << 
"addProcsByVars could not find readers"<<endl;
   986             for(procs_t::const_iterator p=v2p->second.begin(),
   987                     pe=v2p->second.end(); p!=pe; ++p)
   989                 v2c = (*p)->wtVars.find(*v);
   990                 if (v2c != (*p)->wtVars.end()) {
   991                     if (!includes(observable.begin(), observable.end(),
   992                                   v2c->second.begin(), v2c->second.end(),
   995                         if (exclude.erase(*p) > 0) {
   997                             printViolation(*p, *v);
   998                         } 
else if (procs.find(*p) == procs.end() &&
   999                                    procsBad.find(*p) == procsBad.end()) {
  1001                                 cerr << 
"Adding \""<<(*p)->name
  1002                                      <<
"\" using \""<<(*v)
  1003                                      <<
"\" by rule \""<<rule<<
"\""<<endl;
  1009                         cerr<<
"addProcsByVars could not find in wtVars"<<endl;
  1014                 cerr<<
"addProcsByVars could not find writers for "<<(*v)<<endl;
  1024         if (isalnum((
unsigned char)c) || c==
'_' || c==
'[' || c==
']') buffer += c;
  1026             if (c==
'(') 
while (in.get(c) && c!=
')') ; 
  1027             if (buffer.length()>0)
  1028             return strdup(buffer.c_str());
  1031     if (buffer.length()>0) 
return strdup(buffer.c_str());
  1039     std::ios::fmtflags flags = ioinfo.flags();
  1040     ioinfo.unsetf(std::ios::skipws);
  1043         if (strcmp(token, 
"input")!=0) {
  1044             cerr << 
"\"input\" is expected instead of \""<<token<<
"\"" << endl;
  1049         while ((token = 
get_token(ioinfo)) != NULL &&
  1050                strcmp(token, 
"output") != 0)
  1051             inputs.insert(token);
  1053         if (token == NULL) {
  1054             cerr << 
"\"output\" expected, but EOF found" << endl;
  1058         while ((token = 
get_token(ioinfo)) != NULL &&
  1059                strcmp(token, 
"precision")!=0 && strcmp(token, 
"timeout")!=0)
  1060             outputs.insert(token);
  1061         if (token != NULL) 
free(token);
  1063     ioinfo.flags(flags);
  1064     int res = partition(inputs, outputs);
  1065     strs_t::const_iterator s;
  1066     for (s=inputs.begin(); s!=inputs.end(); ++s) 
free((
char*)*s);
  1067     for (s=outputs.begin(); s!=outputs.end(); ++s) 
free((
char*)*s);
  1073     procsEnv.clear(); procsIUT.clear();
  1074     chansIntEnv.clear(); chansIntIUT.clear();
  1075     varsEnv.clear(); varsIUT.clear();
  1076     strs_t::const_iterator s;
  1077     for (s=chansInp.begin(); s!=chansInp.end(); ++s) 
free((
char*)*s);
  1078     for (s=chansOut.begin(); s!=chansOut.end(); ++s) 
free((
char*)*s);
  1079     chansInp.clear(); chansOut.clear();
  1081     for (s=inputs.begin(); s!=inputs.end(); ++s)
  1082         chansInp.insert(strdup(*s));
  1083     for (s=outputs.begin(); s!=outputs.end(); ++s)
  1084         chansOut.insert(strdup(*s));
  1087     observable.insert(chansInp.begin(), chansInp.end());
  1088     observable.insert(chansOut.begin(), chansOut.end());
  1091         cerr << 
"Inputs:  " << chansInp << endl;
  1092         cerr << 
"Outputs: " << chansOut << endl;
  1095     size_t oldProgress=0, progress=0;
  1097         oldProgress = progress;
  1100         rule=
"transmitters on input channels belong to Env";
  1102         rule=
"receivers on output channels belong to Env";
  1103         addProcs(outputs, 
receivers, procsEnv, procsIUT);
  1104         rule=
"receivers on input channels belong IUT";
  1105         addProcs(inputs, 
receivers, procsIUT, procsEnv);
  1106         rule=
"transmitters on output channels belong IUT";
  1116         rule=
"internal channel belongs to Env if it is used by Env";
  1117         addIntChans(procsEnv, chansIntEnv, chansIntIUT);
  1118         rule=
"internal channel belongs to IUT if it is used by IUT";
  1119         addIntChans(procsIUT, chansIntIUT, chansIntEnv);
  1123         rule=
"process belongs to Env if it shouts on internal Env channel";
  1124         addProcs(chansIntEnv, 
transmitters, procsEnv, procsIUT);
  1125         rule=
"process belongs to Env if it listens to internal Env channel";
  1126         addProcs(chansIntEnv, 
receivers, procsEnv, procsIUT);
  1127         rule=
"process belongs to IUT if it shouts on internal IUT channel";
  1128         addProcs(chansIntIUT, 
transmitters, procsIUT, procsEnv);
  1129         rule=
"process belongs to IUT if it listens to internal IUT channel";
  1130         addProcs(chansIntIUT, 
receivers, procsIUT, procsEnv);
  1136         rule=
"variable belongs to Env if accessed by Env without observable sync";
  1137         addIntVars(procsEnv, varsEnv, varsIUT);
  1138         rule=
"variable belongs to IUT if accessed by IUT without observable sync";
  1139         addIntVars(procsIUT, varsIUT, varsEnv);
  1143         rule=
"process belongs to Env if it access Env variable without observable synchronization";
  1144         addProcsByVars(varsEnv, procsEnv, procsIUT);
  1145         rule=
"process belongs to IUT if it access IUT variable without observable synchronization";
  1146         addProcsByVars(varsIUT, procsIUT, procsEnv);
  1147         progress = procsEnv.size() + procsIUT.size() + procsBad.size();
  1148     } 
while (progress>oldProgress);
  1149     procs_t::const_iterator p;
  1152         cerr << 
"==== Partitioned =========================================\n";
  1153         cerr << 
"Env procs: " << procsEnv << endl;
  1154         cerr << 
"Env chans: " << chansIntEnv << endl;
  1155         cerr << 
"Env vars:  " << varsEnv << endl;
  1156         cerr << 
"----------------------------------------------------------\n";
  1157         cerr << 
"IUT procs: " << procsIUT << endl;
  1158         cerr << 
"IUT chans: " << chansIntIUT << endl;
  1159         cerr << 
"IUT vars:  " << varsIUT << endl;
  1160         cerr << 
"==========================================================\n";
  1163         if (!procsBad.empty())
  1164             cerr << 
"Inconsistent procs: " << procsBad << endl;
  1165         if (!chansBad.empty())
  1166             cerr << 
"Inconsistent chans: " << chansBad << endl;
  1167         if (!varsBad.empty())
  1168             cerr << 
"Inconsistent vars:  " << varsBad << endl;
  1173             if (procsEnv.find(*p) == procsEnv.end() &&
  1174                 procsIUT.find(*p) == procsIUT.end())
  1175                 leftovers.insert(*p);
  1176         if (!leftovers.empty()) {
  1177             cerr << 
"==== Not partitioned: ====================================\n";
  1178             cerr << 
"procs: " << leftovers << endl;
  1182     if (!procsBad.empty() || !chansBad.empty() || !varsBad.empty()) 
return 2;
  1183     if (progress==
procs.size()) 
return 0; 
  1187 #define BADSTYLE "style=filled,fillcolor=\"#FF8080\""  1188 #define IUTSTYLE "style=filled,fillcolor=\"#B8C0FF\""  1189 #define ENVSTYLE "style=filled,fillcolor=\"#C8FFC8\""  1190 #define MEDSTYLE "style=filled,fillcolor=\"#C0C0C0\""  1195     for (SignalFlow::strs_t::const_iterator b=what.begin(), e=what.end(); 
  1200 struct surround: 
public std::unary_function<const char*, void>
  1205     surround(ostream &os, 
const char* prefix, 
const char* postfix):
  1206         out(os), pre(prefix), post(postfix) {}
  1207     void operator()(
const char* x) {
  1208         out << pre << x << post;
  1215     char* name = strcpy(
new char[strlen(
title)+1], 
title);
  1216     for (uint32_t i=0; i<strlen(name); ++i)
  1218         if (!isalpha((
unsigned char)name[i]))
  1224     os << 
"digraph " << name << 
" {\n";
  1226     os << 
"// printer friendly options, fill A4 landscape:\n"  1227         "  size=\"10.2,7.8\"; ratio=fill; margin=0.2;\n"  1228         "  nodesep=0.3; // separation of labelled edges\n\n"  1231         "// neato options:\n"  1232         "  epsilon=0.0001;\n\n"  1233         "  node[fontname=\"Helvetica-Bold\"];\n"  1234         "  edge[fontname=\"Helvetica\",fontsize=10];\n\n"  1236         "// process[shape=ellipse]; int[shape=rectangle]; chan[shape=diamond];\n\n";
  1238     procs_t::const_iterator p, pe;
  1241     ostream_iterator<const char*> osi(os, 
"; ");
  1243     if (!procsBad.empty()) {
  1244         os << 
"// processes in conflict:\n"  1245             "  node [shape=ellipse,peripheries=1," BADSTYLE "];\n  ";
  1246         for (p = procsBad.begin(), pe = procsBad.end(); p!=pe; ++p) {
  1247             os << (*p)->name << 
"; ";
  1248             procsR.erase((*p)->name);
  1252     if (!chansBad.empty()) {
  1253         os << 
"// channels in conflict:\n"  1254             "  node [shape=diamond,peripheries=1," BADSTYLE "];\n  ";
  1255         for_each(chansBad.begin(), chansBad.end(), 
  1256                  surround(os, 
"\"", 
"\"; "));
  1261     if (!varsBad.empty()) {
  1262         os << 
"// variables in conflict:\n"  1263             "  node [shape=diamond,peripheries=1," BADSTYLE "];\n  ";
  1264         copy(varsBad.begin(), varsBad.end(), osi);
  1269     if (!procsIUT.empty()) {
  1270         os << 
"// IUT processes:\n";
  1271         os << 
"  node [shape=ellipse,peripheries=1," IUTSTYLE "];\n  ";
  1272         for (p = procsIUT.begin(), pe = procsIUT.end(); p!=pe; ++p) {
  1273             os << (*p)->name << 
"; ";
  1274             procsR.erase((*p)->name);
  1278     if (!chansIntIUT.empty()) {
  1279         os << 
"// IUT channels:\n";
  1280         os << 
"  node [shape=diamond,peripheries=1," IUTSTYLE "];\n  ";
  1281         for_each(chansIntIUT.begin(), chansIntIUT.end(), 
  1282                  surround(os, 
"\"", 
"\"; "));
  1287     if (!varsIUT.empty()) {
  1288         os << 
"// IUT variables:\n";
  1289         os << 
"  node [shape=rectangle,peripheries=1," IUTSTYLE "];\n  ";
  1290         copy(varsIUT.begin(), varsIUT.end(), osi);
  1295     if (!chansOut.empty()) {
  1296         os << 
"// observable output channels (controlled by IUT):\n"  1297             "  node [shape=diamond,peripheries=2," IUTSTYLE "];\n  ";
  1298         for_each(chansOut.begin(), chansOut.end(), 
  1299                  surround(os, 
"\"", 
"\"; "));
  1304     if (!chansInp.empty()) {
  1305         os << 
"// observable input channels (controlled by Env):\n"  1306             "  node [shape=diamond,peripheries=2," ENVSTYLE "];\n  ";
  1307         for_each(chansInp.begin(), chansInp.end(), 
  1308                  surround(os, 
"\"", 
"\"; "));
  1314     if (!procsEnv.empty()) {
  1315         os << 
"// Env processes:\n";
  1316         os << 
"  node [shape=ellipse,peripheries=1," ENVSTYLE "];\n  ";
  1317         for (p = procsEnv.begin(), pe = procsEnv.end(); p!=pe; ++p) {
  1318             os << (*p)->name << 
"; ";
  1319             procsR.erase((*p)->name);
  1323     if (!chansIntEnv.empty()) {
  1324         os << 
"// Env channels:\n";
  1325         os << 
"  node [shape=diamond,peripheries=1," ENVSTYLE "];\n  ";
  1326         for_each(chansIntEnv.begin(), chansIntEnv.end(), 
  1327                  surround(os, 
"\"", 
"\"; "));
  1332     if (!varsEnv.empty()) {
  1333         os << 
"// Env variables:\n";
  1334         os << 
"  node [shape=rectangle,peripheries=1," ENVSTYLE "];\n  ";
  1335         copy(varsEnv.begin(), varsEnv.end(), osi);
  1339     os << 
"// set attributes for non-partitioned procs/chans/vars:\n";
  1340     if (!procsR.empty()) {
  1341         os << 
"  node [shape=ellipse,peripheries=1," MEDSTYLE "];\n";
  1342         copy(procsR.begin(), procsR.end(), osi);
  1345     if (!chansR.empty()) {
  1346         os << 
"  node [shape=diamond,peripheries=1," MEDSTYLE "];\n";
  1347         for_each(chansR.begin(), chansR.end(), 
  1348                  surround(os, 
"\"", 
"\"; "));
  1352     if (!varsR.empty()) {
  1353         os << 
"  node [shape=rectangle,peripheries=1," MEDSTYLE "];\n";
  1354         copy(varsR.begin(), varsR.end(), osi);
  1360     str2strs_t::const_iterator v2c;
  1361     os << 
"// edges for write to variable:\n"  1362        << 
"  edge [style=bold];\n";
  1363     for (p = 
procs.begin(), pe = 
procs.end(); p!=pe; ++p) {
  1364         if (!(*p)->wtVars.empty()) {
  1365             for (v2c = (*p)->wtVars.begin(); v2c != (*p)->wtVars.end(); ++v2c){
  1366                 os<<
"  "<<(*p)->name<< 
" -> " << v2c->first << 
" [label=\"(";
  1368                 for_each(v2c->second.begin(), v2c->second.end(),
  1374     os << 
"// edges for read of variable:\n"  1375        << 
"  edge [style=solid];\n";
  1376     for (p = 
procs.begin(), pe = 
procs.end(); p!=pe; ++p) {
  1377         if (!(*p)->rdVars.empty()) {
  1378             for (v2c = (*p)->rdVars.begin(); v2c != (*p)->rdVars.end(); ++v2c){
  1379                 os<<
"  " << v2c->first << 
" -> " <<(*p)->name<<
" [label=\"(";
  1381                 for_each(v2c->second.begin(), v2c->second.end(),
  1394             os << 
"// channel transmit edges:\n"  1395                << 
"  edge [style=bold];\n";
  1396             for (p = 
procs.begin(), pe = 
procs.end(); p!=pe; ++p) {
  1397                 for (strs_t::const_iterator c=(*p)->outChans.begin(),
  1398                          ce=(*p)->outChans.end(); c!=ce; ++c)
  1400                     os << 
"  " << (*p)->name << 
" -> \"" << *c << 
"\";\n";
  1403             os << 
"// channel receive edges:\n"  1404                << 
"  edge [style=solid];\n";
  1405             for (p = 
procs.begin(), pe = 
procs.end(); p!=pe; ++p) {
  1406                 for (strs_t::const_iterator c=(*p)->inChans.begin(),
  1407                          ce=(*p)->inChans.end(); c!=ce; ++c)
  1409                     os << 
"  \"" << *c << 
"\" -> " << (*p)->name << 
";\n";
  1413             const char* src = 
"NO_SRC";
  1414             const char* dst = 
"NO_DST";
  1416             for (p = 
procs.begin(), pe = 
procs.end(); p!=pe; ++p)
  1419                 for (strs_t::const_iterator c=(*p)->outChans.begin(),
  1420                          ce=(*p)->outChans.end(); c!=ce; ++c)
  1422                     str2procs_t::const_iterator dests = 
receivers.find(*c);
  1425                         for (procs_t::const_iterator rec =
  1426                                  dests->second.begin();
  1427                              rec != dests->second.end(); ++rec)
  1429                             (*p)->outEdges[*rec].insert(*c);
  1434                         (*p)->outEdges[NULL].insert(*c);
  1440             os<<
"  edge[style=solid];\n";
  1441             for (p = 
procs.begin(), pe = 
procs.end(); p!=pe; ++p)
  1444                 for (proc2strs_t::const_iterator edge = (*p)->outEdges.begin();
  1445                      edge != (*p)->outEdges.end(); ++edge)
  1448                     if (edge->first != NULL)
  1451                         os<<
"  " <<(*p)->name << 
" -> " << edge->first->name
  1459                               <<
" [style=filled,fillcolor=red];\n";
  1462                         os<<
"  " <<(*p)->name << 
" -> " << dst
  1466                     strs_t::const_iterator 
ch=edge->second.begin();
  1469                         os<< 
"\"" << *ch << 
"\"";
  1471                         if (ch != edge->second.end())
  1485                 for (strs_t::const_iterator c=(*p)->inChans.begin(),
  1486                          ce=(*p)->inChans.end(); c!=ce; ++c)
  1488                     str2procs_t::const_iterator trans = 
transmitters.find(*c);
  1494                               <<
" [style=filled,fillcolor=red];\n";
  1497                         os<<
"  "<<src<<
" -> " << (*p)->name << 
" [label=\""  1509     for (procs_t::const_iterator p=procsEnv.begin(); p!=procsEnv.end(); ++p)
  1510         procs.insert((*p)->name);
  1515     for (procs_t::const_iterator p=procsIUT.begin(); p!=procsIUT.end(); ++p)
  1516         procs.insert((*p)->name);
  1523     distancesUpToDate = 
false;
  1524     const char* dot = strchr(var, 
'.');
  1525     size_t length = dot == NULL ? strlen(var) : dot - var;
  1526     char* name = strncpy(
new char[length+1], var, length);
  1527     name[length] = 
'\0';
  1530         cerr << 
"Variable not found: " << var << endl;
  1534     dist_t* distance = NULL;
  1535     str2dist_t::iterator i = distances.find(name);
  1536     if (i==distances.end()) {
  1537         varNeedles.insert(name);
  1538         distances[name] = dist_t(0, 1, 0);
  1541         distance = &(i->second);
  1542         if (distance->hops==0 && distance->distance==0) {
  1544             distance->complexity = 2 * distance->complexity;
  1547             distance->distance = 0;
  1555     distancesUpToDate = 
false;
  1556     const char* dot = strchr(proc, 
'.');
  1557     size_t length = dot == NULL ? strlen(proc) : dot - proc;
  1558     char* name = strncpy(
new char[length+1], proc, length);
  1559     name[length] = 
'\0';
  1562         cerr << 
"AddNeedle: Process not found: " << proc << endl;
  1567     dist_t* distance = NULL;
  1568     str2dist_t::iterator i = distances.find(name);
  1569     if (i==distances.end()) {
  1570         procNeedles.insert(name);
  1571         distances[name] = dist_t(0, calcComplexity(name), 0);
  1574         distance = &(i->second);
  1575         if (distance->hops==0 && distance->distance==0) {
  1577             distance->complexity = 2 * distance->complexity;
  1580             distance->distance = 0;
  1586 void DistanceCalculator::updateDistancesFromVariable(
const char* name, 
  1590     str2procs_t::const_iterator t = 
transmitters.find(name);
  1592     for (procs_t::const_iterator p=t->second.begin(),e=t->second.end(); 
  1595         dist_t* distance = NULL;
  1596         str2dist_t::iterator i = distances.find((*p)->name);
  1597         if (i==distances.end()) {
  1598             procNeedles.insert(strcpy(
new char[strlen((*p)->name)+1], 
  1600             distances[(*p)->name] = dist_t(d->hops+1, 
  1601                                            calcComplexity((*p)->name), 
  1602                                            d->distance + d->complexity);
  1603             distance = &distances[(*p)->name];
  1605             distance = &(i->second);
  1606             if (distance->distance <= d->distance + d->complexity)
  1609                 distance->hops = d->hops+1;
  1610                 distance->distance = d->distance + d->complexity;
  1613         updateDistancesFromProcess((*p)->name, distance);
  1617 void DistanceCalculator::updateDistancesFromProcess(
const char* name, 
  1621     procs_t::const_iterator s = 
procs.begin();
  1622     while (s != 
procs.end()) 
  1623         if (strcmp((*s)->name, name)==0) 
break;
  1625     if (s == 
procs.end()) {
  1626         cerr << 
"UpdateDistancesFromProcess: Process not found: "<<name<<endl;
  1630     for (strs_t::const_iterator c=(*s)->inChans.begin(),ce=(*s)->inChans.end();
  1636         for (procs_t::const_iterator p=t->second.begin(),e=t->second.end(); 
  1639             dist_t* distance = NULL;
  1640             str2dist_t::iterator i = distances.find((*p)->name);
  1641             if (i==distances.end()) {
  1642                 procNeedles.insert(strcpy(
new char[strlen((*p)->name)+1], 
  1644                 distances[(*p)->name] = dist_t(d->hops+1, 
  1645                                                calcComplexity((*p)->name), 
  1646                                                d->distance + d->complexity);
  1647                 distance = &distances[(*p)->name];
  1649                 distance = &(i->second);
  1650                 if (distance->distance <= d->distance + d->complexity)
  1653                     distance->hops = d->hops+1;
  1654                     distance->distance = d->distance + d->complexity;
  1657             updateDistancesFromProcess((*p)->name, distance);
  1661     for (str2strs_t::const_iterator v=(*s)->rdVars.begin(),
  1662              ve=(*s)->rdVars.end(); v!=ve; ++v)
  1664         dist_t* distance = NULL;
  1665         str2dist_t::iterator i = distances.find(v->first);
  1666         if (i==distances.end()) {
  1667             varNeedles.insert(strcpy(
new char[strlen(v->first)+1], v->first));
  1668             distances[v->first] = dist_t(d->hops+1, 1, 
  1669                                          d->distance + d->complexity);
  1670             distance = &distances[v->first];
  1672             distance = &(i->second);
  1673             if (distance->distance <= d->distance + d->complexity)
  1676                 distance->hops = d->hops+1;
  1677                 distance->distance = d->distance + d->complexity;
  1680         updateDistancesFromVariable(v->first, distance);        
  1684 int DistanceCalculator::calcComplexity(
const char* process)
  1687     list<instance_t> &ps(taSystem.getProcesses());
  1688     for (list<instance_t>::iterator i=ps.begin(), e=ps.end(); i!=e; ++i)
  1690         if (i->uid.getName()==process) {   
  1692             deque<edge_t>::const_iterator t = i->
templ->
edges.begin();
  1693             while (t != temp->
edges.end()) { result++; t++; }
  1702     os << 
"  subgraph procs {\n";
  1705         os<<
"    node [shape=rectangle,style=filled];\n";
  1709         os<<
"    node [shape=ellipse,style=filled];\n";
  1713     for (procs_t::const_iterator p=
procs.begin(), e=
procs.end(); p!=e; ++p)
  1715         str2dist_t::const_iterator d = distances.find((*p)->name);
  1716         if (d==distances.end()) {
  1717             os << (*p)->name << 
"[label=\"\\N\\n(( ?, ?))\"]; ";
  1719             os << (*p)->name << 
"[label=\"\\N\\n((" << d->second.hops 
  1720                <<
", "<< d->second.distance <<
"))\"]; ";
  1731     os << 
"  subgraph cluste_vars {\n";
  1732     os << 
"    style=invis;\n";
  1735         os << 
"    rank=min;\n";
  1739         os << 
"    node [shape=diamond,color=blue];\n    ";
  1743         os << 
"    node [shape=rectangle,color=blue];\n    ";
  1748         str2dist_t::const_iterator d = distances.find(*i);
  1749         if (d==distances.end()) {
  1750             os << *i << 
"[label=\"\\N\\n(( ?, ?))\"";
  1752             os << *i << 
"[label=\"\\N\\n((" << d->second.hops 
  1753                <<
", "<< d->second.distance <<
"))\"";
  1756         else os << 
",style=bold]; "; 
  1763     for(strs_t::iterator i=varNeedles.begin(),e=varNeedles.end(); i!=e; ++i)
  1767     for(strs_t::iterator i=procNeedles.begin(),e=procNeedles.end(); i!=e; ++i)
  1769     procNeedles.clear();
  1774     if (!distancesUpToDate) updateDistances();
  1776     str2dist_t::iterator f = distances.find(element);
  1777     if (f == distances.end()) {
  1781     return f->second.distance;
  1787     if (!distancesUpToDate) updateDistances();
  1795     for (str2dist_t::iterator i=distances.begin(), e=distances.end(); 
  1798         if (i->second.hops>0) {
  1799             i->second.hops = INT_MAX;
  1800             i->second.distance = INT_MAX;
  1804     for(strs_t::iterator i=varNeedles.begin(),e=varNeedles.end(); 
  1807         str2dist_t::iterator f = distances.find(*i);
  1808         if (f == distances.end()) {
  1809             cerr << 
"Variable not found: " << *i << endl;
  1812         updateDistancesFromVariable(*i, &(f->second));
  1815     for(strs_t::iterator i=procNeedles.begin(),e=procNeedles.end(); 
  1818         str2dist_t::iterator f = distances.find(*i);
  1819         if (f == distances.end()) {
  1820             cerr << 
"Process not found: " << *i << endl;
  1823         updateDistancesFromProcess(*i, &(f->second));
  1825     distancesUpToDate = 
true;
 
virtual void printChansOnEdgesForDot(std::ostream &os)
 
Class SignalFlow is for analysing UPPAAL specifications and extracting the timed automata input/outpu...
 
Constants::kind_t getKind() const
Returns the kind of the expression. 
 
Partial instance of a template. 
 
int32_t visitWhileStatement(WhileStatement *stat) override
 
static ParserBuilder * ch
 
struct template_t * templ
 
int32_t visitBreakStatement(BreakStatement *stat) override
 
void addProcsByVars(const strs_t &vars, procs_t &procs, procs_t &exclude)
Take all variables and add all accessing processes to the list. 
 
void printForDot(std::ostream &os, bool ranked, bool erd, bool cEdged) override
Print I/O information in DOT format into given output stream. 
 
void visitExpression(const expression_t &)
 
void printProcsForDot(std::ostream &os, bool erd) override
 
bool empty() const
Returns true if this is an empty expression. 
 
bool hasParent() const
Returns true if this frame has a parent. 
 
DistanceCalculator is used in TargetFirst heuristic search order of Uppaal. 
 
int32_t visitCaseStatement(CaseStatement *stat) override
 
std::deque< state_t > states
Locations. 
 
const_iterator end() const
 
void addIntVars(const procs_t &procs, strs_t &result, strs_t &exclude)
Takes the variables of each process from procs list and adds them to the result list. 
 
virtual void printVarsReadForDot(std::ostream &os)
 
virtual void printForDot(std::ostream &os, bool ranked, bool erd, bool cEdged)
Print I/O information in DOT format into given output stream. 
 
virtual ~SignalFlow()
All strings are from TASystem (don't dispose TASystem before SignalFlow). 
 
int32_t visitIfStatement(IfStatement *stat) override
 
std::string getName() const
Returns the name (identifier) of this symbol. 
 
symbol_t getSymbol()
Returns the symbol of a variable reference. 
 
void fillWithIUTProcs(strs_t &procs)
 
void visitProcess(instance_t &)
 
std::vector< Statement * >::iterator iterator
 
static const char * noChan
 
int32_t visitContinueStatement(ContinueStatement *stat) override
 
frame_t parameters
The parameters. 
 
Statement class for the iterator loop-construction. 
 
void addChan(const std::string &, strs_t &, str2procs_t &)
 
int32_t visitDefaultStatement(DefaultStatement *stat) override
 
int32_t visitEmptyStatement(EmptyStatement *stat) override
System visitor pattern extracts read/write information from UCode. 
 
void printVarsForDot(std::ostream &os, bool ranked, bool erd) override
 
virtual void printProcsForDot(std::ostream &os, bool erd)
 
std::set< proc_t * > procs_t
 
int32_t visitBlockStatement(BlockStatement *stat) override
 
std::list< instance_t > & getProcesses()
Returns the processes of the system. 
 
Partitions the system into environment and IUT according to TRON assumptions. 
 
std::map< const char *, strs_t > str2strs_t
 
void set_remove(SignalFlow::strs_t &from, const SignalFlow::strs_t &what)
 
void addProcessNeedle(const char *proc)
adds a variable needle to I/O map 
 
int partition(const strs_t &inputs, const strs_t &outputs)
 
void updateDistances()
Recalculates the distances to needles. 
 
std::deque< edge_t > edges
Edges. 
 
std::set< const char *, const less_str > strs_t
 
virtual void printChansSeparateForDot(std::ostream &os, bool ranked, bool erd)
 
std::stack< exprref_t > valparams
 
std::stack< exprref_t > refparams
 
virtual void printVarsForDot(std::ostream &os, bool ranked, bool erd)
 
int32_t visitIterationStatement(IterationStatement *stat) override
 
uint32_t getDistance(const char *element)
Finds a distance measure for given element. 
 
print – template for pretty printing lists. 
 
bool checkParams(const symbol_t &s)
 
void fillWithEnvProcs(strs_t &procs)
 
int32_t visitReturnStatement(ReturnStatement *stat) override
 
std::map< const symbol_t, expression_t > exprref_t
 
const_iterator begin() const
 
void addVariableNeedle(const char *var)
adds a variable needle to I/O map 
 
SignalFlow(const char *_title, TimedAutomataSystem &ta)
Analyse the system and extract I/O information: 
 
virtual ~DistanceCalculator()
 
int32_t accept(StatementVisitor *visitor) override
 
char * get_token(istream &in)
 
void printForDot(std::ostream &os, bool ranked, bool erd, bool cEdged) override
Print I/O information in DOT format into given output stream. 
 
std::map< symbol_t, expression_t > mapping
The arguments. 
 
type_t getType() const
Returns the type of this symbol. 
 
void addVar(const symbol_t &, str2strs_t &, str2procs_t &)
 
void printForTron(std::ostream &os)
Print I/O information in TRON format into given output stream. 
 
int32_t visitSwitchStatement(SwitchStatement *stat) override
 
A reference to an expression. 
 
Information about a function. 
 
int32_t visitForStatement(ForStatement *stat) override
 
type_t getType() const
Returns the type of the expression. 
 
void * getData()
Returns the user data of this symbol. 
 
void addProcs(const strs_t &chans, const str2procs_t &index, procs_t &result, procs_t &exclude)
Adds processes to the result which use the channels from chans list according to index. 
 
virtual int32_t accept(StatementVisitor *visitor)=0
 
int32_t getValue() const
Returns the value field of this expression. 
 
size_t getSize() const
Returns the number of subexpression. 
 
bool is(Constants::kind_t kind) const
Returns true if the type has kind kind or if type is a prefix, RANGE or REF type and the getChild()...
 
void printViolation(const proc_t *process, const char *variable)
 
std::map< const char *, procs_t, less_str > str2procs_t
 
frame_t getFrame()
Get frame this symbol belongs to. 
 
int32_t visitExprStatement(ExprStatement *stat) override
 
Constants::synchronisation_t getSync() const
Returns the synchronisation type of SYNC operations. 
 
void addIntChans(const procs_t &procs, strs_t &result, strs_t &exclude)
Takes the internal channels of each process from procs list and adds them to the result list...
 
int32_t visitDoWhileStatement(DoWhileStatement *stat) override
 
int32_t getIndexOf(const std::string &name) const
Returns the index of the symbol with the given name. 
 
Constants::kind_t getKind() const
Returns the kind of type object. 
 
virtual void printVarsWriteForDot(std::ostream &os)
 
int32_t visitAssertStatement(UTAP::AssertStatement *stat) override