uppaal-to-tchecker
Version:
JavaScript implementation of Uppaal to TChecker translator - convert Uppaal timed automata models to TChecker format
118 lines (100 loc) • 3.24 kB
JavaScript
/**
* TChecker Output Format Generator
* JavaScript implementation of utot-tchecker.hh
*/
class TCheckerOutputter {
constructor(stream = process.stdout) {
this.stream = stream;
this.tauGenerated = false;
}
system(id) {
this.stream.write(`system:${id}\n`);
}
process(id) {
this.stream.write(`process:${id}\n`);
}
event(id) {
this.stream.write(`event:${id}\n`);
}
clock(id, size = 1) {
this.stream.write(`clock:${size}:${id}\n`);
}
intvar(min, max, init, id, size = 1) {
if (min > max) {
throw new Error(`Invalid range: min (${min}) > max (${max})`);
}
if (init < min || init > max) {
throw new Error(`Init value (${init}) out of range [${min}, ${max}]`);
}
this.stream.write(`int:${size}:${min}:${max}:${init}:${id}\n`);
}
attributes(attr) {
if (!attr || Object.keys(attr).length === 0) {
this.stream.write('{}');
return;
}
this.stream.write('{');
const entries = Object.entries(attr);
entries.forEach(([key, value], index) => {
if (index > 0) this.stream.write(':');
this.stream.write(`${key}:${value}`);
});
this.stream.write('}');
}
location(processId, id, attr = {}) {
this.stream.write(`location:${processId}:${id}`);
this.attributes(attr);
this.stream.write('\n');
}
edge(processId, src, tgt, event, attr = {}) {
if (event === TCheckerOutputter.TAU_EVENT && !this.tauGenerated) {
this.commentln('global event for Uppaal unlabelled edges');
this.event(TCheckerOutputter.TAU_EVENT);
this.tauGenerated = true;
}
this.stream.write(`edge:${processId}:${src}:${tgt}:${event}`);
this.attributes(attr);
this.stream.write('\n');
}
sync(syncVectors) {
if (Object.keys(syncVectors).length < 2) {
throw new Error('Sync requires at least 2 processes');
}
this.stream.write('sync');
for (const [processId, { event, marked }] of Object.entries(syncVectors)) {
this.stream.write(`:${processId}@${event}`);
if (marked) {
this.stream.write('?');
}
}
this.stream.write('\n');
}
comment(...args) {
this.stream.write('# ');
this.stream.write(args.join(''));
}
commentln(...args) {
this.comment(...args);
this.stream.write('\n');
}
commentml(...args) {
const text = args.join('');
const lines = text.split('\n');
lines.forEach(line => {
this.stream.write(`# ${line}\n`);
});
}
getStream() {
return this.stream;
}
}
// Constants
TCheckerOutputter.TAU_EVENT = 'tau';
TCheckerOutputter.DO_NOP = 'nop';
TCheckerOutputter.LOCATION_INITIAL = 'initial';
TCheckerOutputter.LOCATION_INVARIANT = 'invariant';
TCheckerOutputter.LOCATION_COMMITTED = 'committed';
TCheckerOutputter.LOCATION_URGENT = 'urgent';
TCheckerOutputter.EDGE_DO = 'do';
TCheckerOutputter.EDGE_PROVIDED = 'provided';
module.exports = TCheckerOutputter;