HaLeX-1.1: scripts/faAnim.lefty
# HaLeX: A Haskell Library to Model,
# Manipulate and
# Animate Regular Languages
#
# http://www.di.uminho.pt/~jas/Research/HaLeX
#
# The script to animate the Reactive Finite Automata produced by HaLeX
#
# copyright João Saraiva
# Department of Computer Science,
# University of Minho,
# Braga, Portugal
# jas@di.uminho.pt
#
# Version: 1.0 (January, 2002)
#
load('dotty.lefty');
# filenames
fa.graphfilename = 'fa.dot';
fa.transfilename = 'fa.trans';
# tracking the states/nodes
fa.normalcolor = 'black';
fa.highlightcolor = 'light_grey';
fa.currentcolor = 'tan';
fa.trackcur = 0; # 0: No 1: Yes
# tracking the path
fa.trackpath = 0; # 0: No 1: Yes
fa.trackhighlightcolor = 'red';
fa.trackhighlightfontcolor = 'red';
fa.trackhighlightfontsize = '30';
# tracking the input sentence
fa.sentence = '';
fa.protogt.graph.edgeattr.color = 'red';
fa.sleep = 500000;
fa.start = '1';
fa.init = function () {
dotty.init ();
monitorfile = dotty.monitorfile;
};
fa.protogt = [
'layoutmode' = 'sync';
'actions' = copy (dotty.protogt.actions);
];
fa.protovt = [
'name' = 'FA';
'type' = 'normal';
];
fa.main = function () {
local gnvt , gt ;
gnvt = dotty.createviewandgraph(null,'file',fa.protogt,fa.protovt);
gt = gnvt.gt ;
gt.loadgraph (gt, fa.graphfilename,'file',fa.protogt.graph, 1);
fa.currstate = gt.graph.nodes[gt.graph.nodedict[fa.start]]; # <-- Init Node
fa.loadtrans ('fa.trans');
fa.setcurrcolor(gt, fa.currstate);
fa.focuson (gt , fa.currstate);
};
fa.loadtrans = function (filename) {
local fd , i ;
if (~((fd = openio ('file',filename,'r')) >= 0)) {
echo ('cannot open transition file: ',filename);
return;
}
echo ('reading transition file');
i = 0;
while ((fa.trans[i] = readline (fd)))
i = i + 1;
closeio (fd);
fa.trani = 0 ;
fa.states[0] = fa.currstate ;
fa.currstate.count = 1 ;
};
fa.next = function (gt) {
local label , eid , edge , tran ;
if (~(label = fa.trans[fa.trani]))
return 0;
for (eid in fa.currstate.edges) {
edge = fa.currstate.edges[eid];
if (edge.attr.label == label & edge.tail == fa.currstate) {
tran = edge ;
break ;
}
}
if (tran) {
if (fa.trackpath) fa.setedegecolor (gt , tran);
sleep(fa.sleep);
fa.trani = fa.trani + 1;
fa.setcolor (gt , fa.currstate);
fa.currstate = (fa.states[fa.trani] = tran.head) ;
if (fa.currstate.count)
fa.currstate.count = fa.currstate.count + 1;
else
fa.currstate.count = 1;
fa.setcurrcolor (gt, fa.currstate);
fa.focuson (gt , fa.currstate);
sleep(fa.sleep);
}
return 1;
};
fa.prev = function (gt) {
if (fa.trani == 0)
return 0;
sleep(fa.sleep);
remove (fa.trani , fa.states);
fa.trani = fa.trani - 1;
fa.currstate.count = fa.currstate.count - 1;
fa.setcolor (gt , fa.currstate );
fa.currstate = fa.states[fa.trani];
fa.setcurrcolor (gt, fa.currstate);
fa.focuson (gt , fa.currstate);
return 1;
};
fa.setedegecolor = function (gt , edge) {
edge.attr.color = fa.trackhighlightcolor;
edge.attr.fontcolor = fa.trackhighlightfontcolor;
edge.attr.fontsize = fa.trackhighlightfontsize;
ge.undrawedge(gt , gt.views , edge);
remove('style',edge.attr);
gt.unpackedgeattr (gt, edge);
gt.drawedge (gt , gt.views , edge);
};
fa.setcolor = function (gt , node) {
if (node.count) {
node.attr.style = 'filled' ;
node.attr.color = fa.highlightcolor ;
} else {
gt.undrawnode (gt , gt.views , node);
remove ('style' , node.attr);
node.attr.color = fa.normalcolor ;
}
gt.unpacknodeattr (gt, node);
gt.drawnode (gt , gt.views , node);
};
fa.setcurrcolor = function (gt , node) {
node.attr.style = 'filled' ;
node.attr.color = fa.currentcolor ;
gt.unpacknodeattr (gt, node);
gt.drawnode (gt , gt.views , node);
};
fa.focuson = function (gt , node) {
gt.setviewcenter (gt.views , node.pos);
};
fa.protogt.actions.general['play fwd'] = function (gt , vt , data) {
while (fa.next(gt))
;
};
fa.protogt.actions.general['play bwd'] = function (gt , vt , data) {
while (fa.prev(gt))
;
};
fa.protogt.actions.general['track node'] = function (gt , vt , data) {
if (fa.trackcur)
fa.trackcur = 0;
else {
fa.trackcur = 1;
fa.focuson (gt , fa.currstate);
}
};
fa.protogt.actions.general['track path (y/n)'] = function (gt , vt , data) {
if (fa.trackpath) fa.trackpath = 0 ;
else fa.trackpath = 1 ;
};
fa.protogt.actions.general['inc sleep'] = function (gt , vt , data) {
fa.sleep = fa.sleep + 200000;
};
fa.protogt.actions.general['dec sleep'] = function (gt , vt , data) {
fa.sleep = fa.sleep - 200000;
};
fa.protovt.menus = [
'general' = [
0 = "undo";
1 = "paste";
2 = "do layout";
3 = "cancel layout";
4 = "redraw";
5 = "new graph";
6 = "load graph";
7 = "reload graph";
8 = "open view";
9 = "copy view";
10 = "clone view";
11 = "birdseye view";
12 = "close view";
13 = "play fwd";
14 = "play bwd";
15 = "inc sleep";
16 = "dec sleep";
17 = "zoom in";
18 = "zoom out";
19 = "find node";
20 = "track node";
21 = "track path (y/n)";
22 = "print graph";
23 = "text view";
24 = "quit";
];
'node' = [
0 = "cut";
1 = "Cut";
2 = "copy";
3 = "Copy";
4 = "group";
5 = "Group";
6 = "delete";
7 = "Delete";
8 = "remove";
9 = "Remove";
10 = "set attr";
11 = "print attr";
];
'edge' = [
0 = "cut";
1 = "Cut";
2 = "copy";
3 = "Copy";
4 = "group";
5 = "Group";
6 = "delete";
7 = "Delete";
8 = "set attr";
9 = "print attr";
];
];
fa.protovt.uifuncs.rightdown = dotty.protovt.normal.uifuncs.rightdown;
fa.protovt.uifuncs.keyup = dotty.protovt.normal.uifuncs.keyup;
fa.protovt.uifuncs.redraw = dotty.protovt.normal.uifuncs.redraw;
fa.protovt.uifuncs.closeview = dotty.protovt.normal.uifuncs.closeview;
fa.protovt.uifuncs.leftup = function (data) {
local gt ;
gt = dotty.graphs[dotty.views[data.widget].gtid];
if (fa.next(gt) == 0)
echo ('at end of log');
};
fa.protovt.uifuncs.middleup = function (data) {
local gt ;
gt = dotty.graphs[dotty.views[data.widget].gtid];
if (fa.prev(gt) == 0)
echo ('at end of log');
};