119 vector<int> locations;
157 class invalid_format :
public std::runtime_error
160 explicit invalid_format(
const string& arg) : runtime_error(arg) {}
165 bool read(istream& file,
string& str)
169 if (!getline(file, str))
173 }
while (!str.empty() && str[0] ==
'#');
189 cerr <<
"Expecting a line with '.' but got '" << str <<
"'" << endl;
199 while (is.peek() ==
' ')
215 while (getline(file, section))
217 if (section ==
"layout")
220 while (
read(file, str) && !str.empty() && !isspace(str[0]))
223 auto cstr = str.c_str();
225 if (sscanf(cstr,
"%d:clock:%d:%31s", &index,
226 &cell.clock.nr, name) == 3)
230 clocks.emplace_back(name);
233 else if (sscanf(cstr,
"%d:const:%d", &index,
236 cell.type = cell_t::CONST;
238 else if (sscanf(cstr,
"%d:var:%d:%d:%d:%d:%31s", &index,
239 &cell.var.min, &cell.var.max, &cell.var.init,
240 &cell.var.nr, name) == 6)
242 cell.type = cell_t::VAR;
247 else if (sscanf(cstr,
"%d:meta:%d:%d:%d:%d:%31s", &index,
248 &cell.meta.min, &cell.meta.max, &cell.meta.init,
249 &cell.meta.nr, name) == 6)
251 cell.type = cell_t::META;
256 else if (sscanf(cstr,
"%d:sys_meta:%d:%d:%31s", &index,
257 &cell.sys_meta.min, &cell.sys_meta.max, name) == 4)
259 cell.type = cell_t::SYS_META;
262 else if (sscanf(cstr,
"%d:location::%31s", &index, name) == 2)
265 cell.location.flags = cell_t::NONE;
268 else if (sscanf(cstr,
"%d:location:committed:%31s", &index, name) == 2)
274 else if (sscanf(cstr,
"%d:location:urgent:%31s", &index, name) == 2)
280 else if (sscanf(cstr,
"%d:static:%d:%d:%31s", &index,
281 &cell.fixed.min, &cell.fixed.max,
284 cell.type = cell_t::FIXED;
287 else if (sscanf(cstr,
"%d:%5s", &index, s) == 2
288 && strcmp(s,
"cost") == 0)
294 throw invalid_format(str);
299 #if defined(ENABLE_CORA) || defined(ENABLE_PRICED) 300 cell.type = cell_t::VAR;
301 cell.var.min = std::numeric_limits<int32_t>::min();
302 cell.var.max = std::numeric_limits<int32_t>::max();
305 cell.name =
"infimum_cost";
310 cell.name =
"offset_cost";
315 for (
size_t i=1; i<
clocks.size(); ++i) {
316 cell.name =
"#rate[";
317 cell.name.append(
clocks[i]);
318 cell.name.append(
"]");
325 else if (section ==
"instructions")
327 while (
read(file, str) && !str.empty() && (!isspace(str[0]) || str[0]==
'\t'))
335 int cnt = sscanf(str.c_str(),
"%d:%d%d%d%d", &address,
336 &values[0], &values[1], &values[2], &values[3]);
339 throw invalid_format(
"In instruction section");
342 for (
int i = 0; i < cnt-1; ++i)
348 else if (section ==
"processes")
350 while (
read(file, str) && !str.empty() && !isspace(str[0]))
353 if (sscanf(str.c_str(),
"%d:%d:%31s",
354 &index, &process.initial, name) != 3)
356 throw invalid_format(
"In process section");
363 else if (section ==
"locations")
365 while (
read(file, str) && !str.empty() && !isspace(str[0]))
371 if (sscanf(str.c_str(),
"%d:%d:%d", &index, &process, &invariant) != 3)
373 throw invalid_format(
"In location section");
376 layout[index].location.process = process;
377 layout[index].location.invariant = invariant;
378 processes[process].locations.push_back(index);
381 else if (section ==
"edges")
383 while (
read(file, str) && !str.empty() && !isspace(str[0]))
387 if (sscanf(str.c_str(),
"%d:%d:%d:%d:%d:%d", &edge.process,
388 &edge.source, &edge.target,
389 &edge.guard, &edge.sync, &edge.update) != 6)
391 throw invalid_format(
"In edge section");
395 edges.push_back(edge);
398 else if (section ==
"expressions")
400 while (
read(file, str) && !str.empty() && !isspace(str[0]))
402 if (sscanf(str.c_str(),
"%d", &index) != 1)
404 throw invalid_format(
"In expression section");
408 auto *s = str.c_str();
417 throw invalid_format(
"In expression section");
421 while (*s && isspace(*s))
425 auto *t = s + strlen(s) - 1;
426 while (t >= s && isspace(*t))
436 throw invalid_format(
"Unknown section");
452 static bound_t
infinity = { std::numeric_limits<int32_t>::max() >> 1,
true };
456 static bound_t
zero = { 0,
false };
466 explicit State(istream& file);
467 State(
const State& s) =
delete;
468 State(State&& s) =
delete;
471 int &getLocation(
int i) {
return locations[i]; }
472 int &getVariable(
int i) {
return integers[i]; }
473 bound_t &getConstraint(
int i,
int j) {
return dbm[i *
clockCount + j]; }
475 int getLocation(
int i)
const {
return locations[i]; }
476 int getVariable(
int i)
const {
return integers[i]; }
477 bound_t getConstraint(
int i,
int j)
const {
return dbm[i *
clockCount + j]; }
479 vector<int> locations;
480 vector<int> integers;
503 getConstraint(0, i) =
zero;
504 getConstraint(i, i) =
zero;
508 State::State(istream& file): State()
511 for (
auto& l: locations)
519 while (file >> i >> j >> bnd)
522 getConstraint(i, j).value = bnd >> 1;
523 getConstraint(i, j).strict = bnd & 1;
529 for (
auto& v: integers)
549 explicit Transition(istream& file);
552 Transition::Transition(istream& file)
554 int process, edge, select;
555 while (file >> process >> edge)
557 Edge e{process, edge};
559 while (file.peek()!=
'\n' && file.peek()!=
';')
563 e.select.push_back(select);
567 cerr <<
"Transition format error" << endl;
572 if (file.get()==
'\n')
590 int idx =
processes[p].locations[state.getLocation(p)];
597 cout <<
variables[v] <<
"=" << state.getVariable(v) <<
' ';
607 bound_t bnd = state.getConstraint(i, j);
609 if (bnd.value != infinity.value)
612 << (bnd.strict ?
"<" :
"<=") << bnd.value <<
" ";
627 for (
auto& edge: t.edges)
629 int eid =
processes[edge.process].edges[edge.edge];
630 int src =
edges[eid].source;
631 int dst =
edges[eid].target;
632 int guard =
edges[eid].guard;
633 int sync =
edges[eid].sync;
634 int update =
edges[eid].update;
638 if (!edge.select.empty()) {
639 auto s=edge.select.begin(), se=edge.select.end();
641 while (++s != se) cout <<
"," << *s;
657 cout <<
"State: " << State(file) << endl;
664 if (file.peek() ==
'.')
672 Transition transition(file);
675 cout <<
"\nTransition: " << transition << endl
676 <<
"\nState: " << state << endl;
681 int main(
int argc,
char *argv[])
687 printf(
"Synopsis: %s <if> <trace>\n", argv[0]);
693 if (strcmp(argv[1],
"-") == 0)
699 ifstream file(argv[1]);
711 ifstream file(argv[2]);
720 catch (std::exception &e)
722 cerr <<
"Cought exception: " << e.what() << endl;
void loadTrace(istream &file)
istream & readdot(istream &is)
static map< int, string > expressions
ostream & operator<<(ostream &o, const State &state)
static size_t variableCount
static vector< edge_t > edges
static vector< string > variables
static vector< cell_t > layout
static vector< process_t > processes
static size_t processCount
static vector< int > instructions
bool read(istream &file, string &str)
istream & skipspaces(istream &is)
void loadIF(istream &file)
static vector< string > clocks
int main(int argc, char *argv[])