UNPKG

uppaal-to-tchecker

Version:

JavaScript implementation of Uppaal to TChecker translator - convert Uppaal timed automata models to TChecker format

181 lines (146 loc) • 6.63 kB
#!/usr/bin/env node /** * Usage demonstration for uppaal-to-tchecker JavaScript API * This script shows various ways to use the translator */ const UppaalToTChecker = require('../src/index'); const fs = require('fs').promises; const path = require('path'); const demoModel = ` // Demo Uppaal model - Train Gate Controller clock x, y; int trains = 0; bool gate_open = true; chan approach, exit, lower, raise; process Train(const int id) { state far, near, crossing; init far; trans far -> near { sync approach!; }, near -> crossing { guard !gate_open; assign x = 0; }, crossing -> far { guard x >= 1; sync exit!; }; } process Controller() { state idle, lowering, raised, raising; init idle; trans idle -> lowering { sync approach?; assign trains++, y = 0; }, lowering -> raised { guard y >= 2; sync lower!; assign gate_open = false; }, raised -> raising { sync exit?; assign trains--; guard trains == 0; assign y = 0; }, raising -> idle { guard y >= 2; sync raise!; assign gate_open = true; }; } // Instantiate two trains T1 := Train(1); T2 := Train(2); system T1, T2, Controller; `; async function demonstrateAPI() { console.log('šŸš‚ Uppaal-to-TChecker JavaScript API Demo\n'); const translator = new UppaalToTChecker(); try { // Demo 1: Basic translation console.log('šŸ“ Demo 1: Basic Translation'); console.log('═'.repeat(50)); const result1 = await translator.translate(demoModel, { format: 'xta', systemName: 'TrainGateSystem' }); console.log('Input: Uppaal XTA model (Train Gate Controller)'); console.log('Output preview:'); console.log(result1.split('\n').slice(0, 10).join('\n') + '\n...\n'); // Demo 2: Translation with options console.log('šŸ“ Demo 2: Translation with Options'); console.log('═'.repeat(50)); translator.setVerbose(1); translator.setDebug(false); const result2 = await translator.translate(demoModel, { format: 'xta', language: 'xta', systemName: 'VerboseSystem', verbose: 1 }); console.log('Used options: verbose=1, systemName=VerboseSystem'); console.log('System line:', result2.split('\n').find(line => line.startsWith('system:'))); console.log(); // Demo 3: File-based translation console.log('šŸ“ Demo 3: File-based Translation'); console.log('═'.repeat(50)); const tempInput = path.join(__dirname, 'temp-demo.xta'); const tempOutput = path.join(__dirname, 'temp-demo.tck'); await fs.writeFile(tempInput, demoModel); const result3 = await translator.translateFile(tempInput, tempOutput, { systemName: 'FileBasedSystem' }); const outputContent = await fs.readFile(tempOutput, 'utf8'); console.log(`Created files: ${tempInput} -> ${tempOutput}`); console.log(`Output file size: ${outputContent.length} characters`); console.log(`Number of processes: ${(outputContent.match(/^process:/gm) || []).length}`); console.log(); // Demo 4: Format detection console.log('šŸ“ Demo 4: Format Detection'); console.log('═'.repeat(50)); const xmlExample = '<?xml version="1.0"?><nta><template><name>Test</name></template></nta>'; console.log('XTA format detected:', translator.detectFormat(demoModel)); console.log('XML format detected:', translator.detectFormat(xmlExample)); console.log('From extension .xta:', translator.detectFormatFromExtension('model.xta')); console.log('From extension .xml:', translator.detectFormatFromExtension('model.xml')); console.log(); // Demo 5: Error handling console.log('šŸ“ Demo 5: Error Handling'); console.log('═'.repeat(50)); try { await translator.translate('invalid uppaal syntax'); } catch (error) { console.log('Caught expected error:', error.constructor.name); console.log('Error message:', error.message); } console.log(); // Demo 6: Analysis of translation result console.log('šŸ“ Demo 6: Translation Analysis'); console.log('═'.repeat(50)); const lines = result1.split('\n'); const systemLine = lines.find(line => line.startsWith('system:')); const processLines = lines.filter(line => line.startsWith('process:')); const locationLines = lines.filter(line => line.startsWith('location:')); const edgeLines = lines.filter(line => line.startsWith('edge:')); const syncLines = lines.filter(line => line.startsWith('sync:')); const clockLines = lines.filter(line => line.startsWith('clock:')); const intLines = lines.filter(line => line.startsWith('int:')); console.log(`System: ${systemLine}`); console.log(`Processes: ${processLines.length}`); console.log(`Locations: ${locationLines.length}`); console.log(`Edges: ${edgeLines.length}`); console.log(`Synchronizations: ${syncLines.length}`); console.log(`Clocks: ${clockLines.length}`); console.log(`Integer variables: ${intLines.length}`); console.log(); console.log('Process names:'); processLines.forEach(line => { const processName = line.split(':')[1]; console.log(` - ${processName}`); }); console.log(); // Cleanup try { await fs.unlink(tempInput); await fs.unlink(tempOutput); } catch (e) { // Ignore cleanup errors } console.log('āœ… Demo completed successfully!'); console.log('\nšŸ“š Next steps:'); console.log(' - Check README.md for complete documentation'); console.log(' - See examples/ for more sample models'); console.log(' - Use USAGE_COMPARISON.md to compare with C++ version'); console.log(' - Run tests with: npm test'); } catch (error) { console.error('āŒ Demo failed:', error.message); if (translator.debug) { console.error(error.stack); } process.exit(1); } } // Run demo if called directly if (require.main === module) { demonstrateAPI(); } module.exports = { demonstrateAPI };