Jordan de la Houssaye

integrates andy's frontend and backend

# entities: tuple of name of the entities, initial level, tuple of decays 0
# denotes unbounded decay (omega)
# examples:
# entities = ( ('B',4, (0,2,2,2,3)), ('P',0, (0,0)), ('C',0, (0,0)),
# ('G',0, (0,0)) )
# entities = ( ('Sugar',1, (0,2)), ('Aspartame',0, (0,2)),
# ('Glycemia',2, (0,2,2,2)), ('Glucagon',0, (0,2)),
# ('Insulin',0,(0,2,2)) )
entities = ( ('s1',0, (0,1)), ('s2',0, (0,1)), ('s3',0, (0,1)) )
# Activities: Tuple of (activators, inhibitors, results, duration)
# activators, inhibitors are dictionaries of pairs
# (entity, level)
# results are dictionaries of pairs (entity, +z)
# potential activities examples:
# potential = ( (dict([('P',0)]),dict([('P',1)]),dict([('P',1)]),0),
# (dict([('P',1)]),dict(),dict([('P',-1)]),0),
# (dict([('C',0)]),dict([('C',1)]),dict([('C',1)]),0),
# (dict([('C',1)]),dict(),dict([('C',-1)]),0),
# (dict([('G',0)]),dict([('G',1)]),dict([('G',1)]),0),
# (dict([('G',1)]),dict(),dict([('G',-1)]),0) )
# potential = ( (dict([('Sugar',1)]),dict(),
# dict([('Insulin',1),('Glycemia',1)]),0),
# (dict([('Aspartame',1)]),dict(),dict([('Insulin',1)]),0),
# (dict(),dict([('Glycemia',1)]),dict([('Glucagon',1)]),0),
# (dict([('Glycemia',3)]),dict(),dict([('Insulin',1)]),0),
# (dict([('Insulin',2)]),dict(),dict([('Glycemia',-1)]),0),
# (dict([('Insulin',1),('Glycemia',3)]), dict(),
# dict([('Glycemia',-1)]),0),
# (dict([('Insulin',1)]),dict([('Glycemia',2)]),
# dict([('Glycemia',-1)]),0),
# (dict([('Glucagon',1)]),dict(),dict([('Glycemia',+1)]),0)
# )
potential = ( (dict(), dict([('s1',1)]), dict([('s2',1)]), 1),
(dict(), dict([('s2',1)]), dict([('s3',1)]), 1),
(dict(), dict([('s3',1)]), dict([('s1',1)]), 1) )
# obligatory activities examples:
# obligatory = ( (dict([('P',1)]),dict(),dict([('B',1)]),1),
# (dict([('C',1)]),dict(),dict([('B',-1)]),3),
# (dict([('G',1)]),dict(),dict([('B',-2)]),3))
obligatory = ()
"""This package features the ABCD compiler, this is mainly a
"""This package features the Andy compiler, this is mainly a
command-line tool but it can be called also from Python. The API is
very simple and mimics the command line interface
### Function `snakes.utils.abcd.main.main` ###
### Function `snakes.utils.andy.main.main` ###
:::python
def main (args=sys.argv[1:], src=None) : ...
def main (args=sys.argv[1:]) : ...
Entry point of the compiler
##### Call API #####
* `list args`:
* `str src`:
* `return PetriNet`:
##### Exceptions #####
......
import snakes.plugins
snakes.plugins.load(['gv', 'ops'], 'snakes.nets', 'nets')
from nets import *
###############################################################################
## AUXILIARY FUNCTIONS ########################################################
......@@ -132,14 +127,14 @@ def potentialt (name, lp, up, lambdap, R) :
###############################################################################
## MAIN #######################################################################
def andy2snakes(entities, potential, obligatory):
def andy2snakes(snk, entities, potential, obligatory):
# compute maximal duration of activities
D=0
for alpha in potential : D = max(D, alpha[3])
for alpha in obligatory : D = max(D, alpha[3])
n = PetriNet('andy')
n = snk.PetriNet('andy')
n.globals["obligatory"] = obligatory
n.globals["D"] = D
......@@ -153,13 +148,13 @@ def andy2snakes(entities, potential, obligatory):
level = entities[i][1]
deltas = entities[i][2]
vector = [0]*len(deltas)
n.add_place(Place(name, [(level,0, tuple(vector))]))
n.add_place(snk.Place(name, [(level,0, tuple(vector))]))
################# clock transition
inputlist = dict()
n.globals["inputlist"] = inputlist
n.add_transition(Transition('tc'))
n.add_transition(snk.Transition('tc'))
# connect all obligatory clocks
......@@ -167,7 +162,7 @@ def andy2snakes(entities, potential, obligatory):
# transition name
obname = 'ob'+str(i)
# for every obligatory activity connect corresponding place to clock
n.add_place(Place('p'+obname, [0]))
n.add_place(snk.Place('p'+obname, [0]))
n.add_input('p'+obname, 'tc', Variable('w'+obname))
inputlist.update({obname:'w'+obname})
......@@ -178,20 +173,20 @@ def andy2snakes(entities, potential, obligatory):
deltas = entities[i][2]
n.globals["deltas"+name] = deltas
n.globals[name] = name
n.add_input(name, 'tc', Tuple([Variable('l'+name), Variable('u'+name), Variable('lambda'+name) ]))
n.add_input(name, 'tc', snk.Tuple([snk.Variable('l'+name), snk.Variable('u'+name), snk.Variable('lambda'+name) ]))
inputlist.update({name:['l'+name, 'u'+name, 'lambda'+name ]})
for i in range(0,len(entities)):
name=entities[i][0]
n.add_output(name, 'tc', Expression("clockt(obligatory,"+name+",l"+name+',u'+name+',lambda'+name+',deltas'+name+',inputlist,D)'))
n.add_output(name, 'tc', snk.Expression("clockt(obligatory,"+name+",l"+name+',u'+name+',lambda'+name+',deltas'+name+',inputlist,D)'))
for i in range(0,len(obligatory)):
obname = 'ob'+str(i)
# for every obligatory activity connect corresponding place to clock
n.add_output('p'+obname, 'tc', Expression("clockbetat(obligatory,"+str(i)+',w'+obname+',inputlist,D)'))
n.add_output('p'+obname, 'tc', snk.Expression("clockbetat(obligatory,"+str(i)+',w'+obname+',inputlist,D)'))
## potential activities
......@@ -200,15 +195,15 @@ def andy2snakes(entities, potential, obligatory):
trname = 'tr'+str(i)
# for every potential activity connect corresponding place to clock
n.add_place(Place('p'+trname, [0]))
n.add_input('p'+trname, 'tc', Variable('w'+trname))
n.add_output('p'+trname, 'tc', Expression('min(D,w'+trname+'+1)'))
n.add_place(snk.Place('p'+trname, [0]))
n.add_input('p'+trname, 'tc', snk.Variable('w'+trname))
n.add_output('p'+trname, 'tc', snk.Expression('min(D,w'+trname+'+1)'))
activators = potential[i][0]
inhibitors = potential[i][1]
results = potential[i][2]
print results
#print results
n.globals["results"+trname] = results
duration = potential[i][3]
......@@ -240,14 +235,14 @@ def andy2snakes(entities, potential, obligatory):
level = str(inhibitors[nameinhib[j]])
guard += ' and l'+spec+'< '+ level + ' and lambda' +spec+'['+level+']>='+str(duration)
n.add_transition(Transition(trname, Expression(guard)))
n.add_input('p'+trname, trname, Variable('w'))
n.add_output('p'+trname, trname, Expression('0'))
n.add_transition(snk.Transition(trname, snk.Expression(guard)))
n.add_input('p'+trname, trname, snk.Variable('w'))
n.add_output('p'+trname, trname, snk.Expression('0'))
# arcs of the transition from and to involved entities
for j in range(0,len(names)) :
n.add_input(names[j], trname, Tuple([Variable('l'+names[j]), Variable('u'+names[j]), Variable('lambda'+names[j]) ]))
n.add_output(names[j], trname, Expression("potentialt(" +names[j]+",l"+names[j]+',u'+names[j]+',lambda'+names[j]+', results'+trname+')'))
n.add_input(names[j], trname, snk.Tuple([snk.Variable('l'+names[j]), snk.Variable('u'+names[j]), snk.Variable('lambda'+names[j]) ]))
n.add_output(names[j], trname, snk.Expression("potentialt(" +names[j]+",l"+names[j]+',u'+names[j]+',lambda'+names[j]+', results'+trname+')'))
return n
......@@ -255,7 +250,7 @@ def andy2snakes(entities, potential, obligatory):
def draw_net(net, out_name='repress'):
net.draw(out_name+'.ps')
def draw_stategraph(net, entities_names, out_name='repressgraph',
def draw_stategraph(snk, net, entities_names, out_name='repressgraph',
with_dot=True):
def node_attr (state, graph, attr) :
marking = graph[state]
......@@ -264,7 +259,7 @@ def draw_stategraph(net, entities_names, out_name='repressgraph',
def edge_attr (trans, mode, attr) :
attr["label"] = trans.name
s = StateGraph(net)
s = snk.StateGraph(net)
s.build()
s.draw(out_name+'.ps', node_attr=node_attr, edge_attr=edge_attr,
......@@ -278,6 +273,9 @@ def draw_stategraph(net, entities_names, out_name='repressgraph',
g.render(out_name+"-layout.dot", engine="dot")
if __name__=='__main__':
import snakes.plugins
snakes.plugins.load(['gv', 'ops'], 'snakes.nets', 'snk')
# entities: tuple of name of the entities, initial level, tuple of decays 0
# denotes unbounded decay (omega)
# examples:
......@@ -325,7 +323,7 @@ if __name__=='__main__':
obligatory = ()
net = andy2snakes(entities, potential, obligatory)
net = andy2snakes(snk, entities, potential, obligatory)
draw_net(net, out_name="repress")
draw_stategraph(net, ("s1", "s2", "s3"), out_name="repressgraph")
draw_stategraph(snk, net, ("s1", "s2", "s3"), out_name="repressgraph")
......
This diff is collapsed. Click to expand it.
import heapq
from snakes.nets import StateGraph
import snakes.lang
import snkast as ast
class Checker (object) :
def __init__ (self, net) :
self.g = StateGraph(net)
self.f = [self.build(f) for f in net.label("asserts")]
def build (self, tree) :
src = """
def check (_) :
return %s
""" % tree.st.source()[7:]
ctx = dict(self.g.net.globals)
ctx["bounded"] = self.bounded
exec(src, ctx)
fun = ctx["check"]
fun.lineno = tree.lineno
return fun
def bounded (self, marking, max) :
return all(len(marking(p)) == 1 for p in marking)
def run (self) :
for state in self.g :
marking = self.g.net.get_marking()
for place in marking :
if max(marking(place).values()) > 1 :
return None, self.trace(state)
for check in self.f :
try :
if not check(marking) :
return check.lineno, self.trace(state)
except :
pass
return None, None
def path (self, tgt, src=0) :
q = [(0, src, ())]
visited = set()
while True :
(c, v1, path) = heapq.heappop(q)
if v1 not in visited :
path = path + (v1,)
if v1 == tgt :
return path
visited.add(v1)
for v2 in self.g.successors(v1) :
if v2 not in visited :
heapq.heappush(q, (c+1, v2, path))
def trace (self, state) :
path = self.path(state)
return tuple(self.g.successors(i)[j]
for i, j in zip(path[:-1], path[1:]))
This diff is collapsed. Click to expand it.
import sys, optparse, os.path, webbrowser
import pdb, traceback
import snakes.plugins
from snakes.utils.abcd.build import Builder
from snakes.lang.abcd.parser import parse
from snakes.lang.pgen import ParseError
from snakes.utils.abcd import CompilationError, DeclarationError
from snakes.utils.abcd.simul import Simulator, ABCDSimulator
from snakes.utils.abcd.checker import Checker
from snakes.utils.abcd.html import build as html
from snakes.utils.andy import CompilationError, DeclarationError
from snakes.utils.andy.simul import Simulator, AndySimulator
from snakes.utils.andy.andy import andy2snakes
from snakes.utils.simul.html import json
##
......@@ -26,11 +22,11 @@ ERR_OUTPUT = 7
ERR_BUG = 255
def log (message) :
sys.stdout.write("abcd: %s\n" % message.strip())
sys.stdout.write("andy: %s\n" % message.strip())
sys.stdout.flush()
def err (message) :
sys.stderr.write("abcd: %s\n" % message.strip())
sys.stderr.write("andy: %s\n" % message.strip())
sys.stderr.flush()
def die (code, message=None) :
......@@ -66,7 +62,7 @@ def bug () :
gv_engines = ("dot", "neato", "twopi", "circo", "fdp")
opt = optparse.OptionParser(prog="abcd",
opt = optparse.OptionParser(prog="andy",
usage="%prog [OPTION]... FILE")
opt.add_option("-l", "--load",
dest="plugins", action="append", default=[],
......@@ -81,9 +77,6 @@ for engine in gv_engines :
dest="gv" + engine, action="store", default=None,
help="draw net using '%s' (from GraphViz)" % engine,
metavar="OUTFILE")
opt.add_option("-a", "--all-names",
dest="allnames", action="store_true", default=False,
help="draw control-flow places names (default: hide)")
opt.add_option("--debug",
dest="debug", action="store_true", default=False,
help="launch debugger on compiler error (default: no)")
......@@ -98,22 +91,13 @@ opt.add_option("--port",
dest="port", action="store", default=8000, type=int,
help="port on which the simulator server runs",
metavar="PORT")
opt.add_option("-H", "--html",
dest="html", action="store", default=None,
help="save net as HTML",
metavar="OUTFILE")
opt.add_option("--check",
dest="check", action="store_true", default=False,
help="check assertions")
def getopts (args) :
global options, abcd, tmp
global options, andy, tmp
(options, args) = opt.parse_args(args)
plugins = []
for p in options.plugins :
plugins.extend(t.strip() for t in p.split(","))
if "ops" not in options.plugins :
plugins.append("ops")
if "labels" not in plugins :
plugins.append("labels")
for engine in gv_engines :
......@@ -121,7 +105,7 @@ def getopts (args) :
if gvopt and "gv" not in plugins :
plugins.append("gv")
break
if (options.html or options.simul) and "gv" not in plugins :
if (options.simul) and "gv" not in plugins :
plugins.append("gv")
options.plugins = plugins
if len(args) < 1 :
......@@ -132,17 +116,13 @@ def getopts (args) :
err("more than one input file provided")
opt.print_help()
die(ERR_ARG)
abcd = args[0]
if options.pnml == abcd :
andy = args[0]
if options.pnml == andy :
err("input file also used as output (--pnml)")
opt.print_help()
die(ERR_ARG)
if options.html == abcd :
err("input file also used as output (--html)")
opt.print_help()
die(ERR_ARG)
for engine in gv_engines :
if getattr(options, "gv%s" % engine) == abcd :
if getattr(options, "gv%s" % engine) == andy :
err("input file also used as output (--%s)" % engine)
opt.print_help()
die(ERR_ARG)
......@@ -151,58 +131,9 @@ def getopts (args) :
## drawing nets
##
def place_attr (place, attr) :
# fix color
if place.status == snk.entry :
attr["fillcolor"] = "green"
elif place.status == snk.internal :
pass
elif place.status == snk.exit :
attr["fillcolor"] = "orange"
else :
attr["fillcolor"] = "lightblue"
# fix shape
if (not options.allnames
and place.status in (snk.entry, snk.internal, snk.exit)) :
attr["shape"] = "circle"
# render marking
if place._check == snk.tBlackToken :
count = len(place.tokens)
if count == 0 :
marking = " "
elif count == 1 :
marking = "&#8226;"
else :
marking = "%s&#8226;" % count
else :
marking = str(place.tokens)
# node label
if (options.allnames
or place.status not in (snk.entry, snk.internal, snk.exit)) :
attr["label"] = "%s\\n%s" % (place.name, marking)
else :
attr["label"] = "%s" % marking
def trans_attr (trans, attr) :
pass
def arc_attr (label, attr) :
if label == snk.Value(snk.dot) :
del attr["label"]
elif isinstance(label, snk.Test) :
attr["arrowhead"] = "none"
attr["label"] = " %s " % label._annotation
elif isinstance(label, snk.Flush) :
attr["arrowhead"] = "box"
attr["label"] = " %s " % label._annotation
def draw (net, target, engine="dot") :
try :
return net.draw(target, engine=engine,
place_attr=place_attr,
trans_attr=trans_attr,
arc_attr=arc_attr)
return net.draw(target, engine=engine)
except :
die(ERR_OUTPUT, str(sys.exc_info()[1]))
......@@ -222,49 +153,36 @@ def save_pnml (net, target) :
## simulator (not standalone)
##
def simulate (source, filename="<string>") :
def simulate (entities, potential, obligatory, filename='<string>') :
global options, snk
getopts(["--simul", filename])
node = parse(source, filename=filename)
snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk")
build = Builder(snk)
net = build.build(node)
net = andy2snakes(snk, entities, potential, obligatory)
net.label(srcfile=filename, snakes=snk)
return ABCDSimulator(node, net, draw(net, None))
return AndySimulator(net)
##
## main
##
def main (args=sys.argv[1:], src=None) :
def main (args=sys.argv[1:]) :
global options, snk
# get options
try:
if src is None :
getopts(args)
else :
getopts(list(args) + ["<string>"])
getopts(args)
except SystemExit :
raise
except :
die(ERR_OPT, str(sys.exc_info()[1]))
# read source
if src is not None :
source = src
else :
try :
source = open(abcd).read()
except :
die(ERR_IO, "could not read input file %r" % abcd)
# parse
try :
node = parse(source, filename=abcd)
except ParseError :
die(ERR_PARSE, str(sys.exc_info()[1]))
except :
bug()
# compile
dirname = os.path.dirname(abcd)
# read andy spec
try:
env = {}
execfile(andy, env)
del env['__builtins__']
except:
die(ERR_IO, "could not read input file %r" % andy)
# compile to net
dirname = os.path.dirname(andy)
if dirname and dirname not in sys.path :
sys.path.append(dirname)
elif "." not in sys.path :
......@@ -273,14 +191,13 @@ def main (args=sys.argv[1:], src=None) :
snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk")
except :
die(ERR_PLUGIN, str(sys.exc_info()[1]))
build = Builder(snk)
try :
net = build.build(node)
net.label(srcfile=abcd, snakes=snk)
except (CompilationError, DeclarationError) :
die(ERR_COMPILE, str(sys.exc_info()[1]))
except :
try:
net = andy2snakes(snk, env['entities'], env['potential'],
env['obligatory'])
except:
bug()
# output
if options.pnml :
save_pnml(net, options.pnml)
......@@ -288,17 +205,10 @@ def main (args=sys.argv[1:], src=None) :
target = getattr(options, "gv%s" % engine)
if target :
draw(net, target, engine)
if options.html :
try :
html(abcd, node, net, draw(net, None), options.html)
except :
bug()
trace, lineno = [], None
if options.check :
lineno, trace = Checker(net).run()
if options.simul :
try :
simul = Simulator(node, net, draw(net, None), options.port)
simul = Simulator(net, options.port)
except :
bug()
simul.start()
......
<!DOCTYPE html>
<html>
<head>
<link type="text/css" href="r/css/bootstrap-theme.css" rel="stylesheet"/>
<link type="text/css" href="r/css/bootstrap.css" rel="stylesheet"/>
<link type="text/css" href="r/css/docs.css" rel="stylesheet"/>
<link type="text/css" href="r/simulator.css" rel="stylesheet"/>
<link type="text/css" href="r/model.css" rel="stylesheet"/>
<script src="r/jquery.min.js"></script>
<script src="r/js/bootstrap.min.js"></script>
<script src="r/jquery.periodic.js"></script>
<script src="r/js/bootstrap.file-input.js"></script>
<script src="r/d3.min.js"></script>
<script src="r/js/petri.js"></script>
<script src="r/simulator.js"></script>
</head>
<head>
<link type="text/css" href="r/css/bootstrap-theme.css" rel="stylesheet"/>
<link type="text/css" href="r/css/bootstrap.css" rel="stylesheet"/>
<link type="text/css" href="r/css/docs.css" rel="stylesheet"/>
<link type="text/css" href="r/simulator.css" rel="stylesheet"/>
<link type="text/css" href="r/model.css" rel="stylesheet"/>
<script src="r/jquery.min.js"></script>
<script src="r/js/bootstrap.min.js"></script>
<script src="r/jquery.periodic.js"></script>
<script src="r/js/bootstrap.file-input.js"></script>
<script src="r/d3.min.js"></script>
<script src="r/js/petri.js"></script>
<script src="r/simulator.js"></script>
<style>
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
line {
stroke: black;
}
text {
font-family: Arial;
font-size: 9pt;
}
path { stroke: steelblue;
stroke-width: 2;
fill: none; }
line { stroke: black; }
text { font-family: Arial;
font-size: 9pt; }
</style>
<body>
</head>
<body>
<header class="navbar navbar-static-top">
<div class="container">
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-6"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Simulation SNAKES</a></div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-6">
<ul id="nav_sim" class="nav navbar-nav">
<li><a href="#" id="ui-reset">Reset Simulation</a></li>
<li><a href="#" id="ui-quit">Stop Simulation</a></li>
<li><a href="#" id="ui-help">Help</a></li>
</ul>
<div class="navbar-header">
<button type="button" class="navbar-toggle"
data-toggle="collapse"
data-target="#bs-example-navbar-collapse-6">
<span class="sr-only">Toggle navigation</span>
</button>
<a class="navbar-brand" href="#">Simulation SNAKES</a>
</div>
<div class="collapse navbar-collapse"
id="bs-example-navbar-collapse-6">
<ul class="nav navbar-nav" id="nav_sim">
<li><a id="ui-reset">Reset Simulation</a></li>
<li><a id="ui-quit">Stop Simulation</a></li>
<li><a id="ui-help">Help</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div>
</nav>
</div>
</header>
<div class="container">
%(model)s
<!-- model to be simulated -->
%(model)s
<div class="modal fade" id="about" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="myModalLabel">Petri Net</h4>
</div>
<div class="modal-body">
<p><span class="title">ABCD simulator is part of the SNAKES toolkit</span><br /> (C) 2014 Franck Pommereau</p>
<p><a href="http://www.ibisc.univ-evry.fr/~fpommereau/SNAKES" target="_blank">SNAKES homepage</a></p>
</div>
<div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div>
<!-- information about the simulator -->
<div aria-hidden="true" aria-labelledby="myModalLabel" class="modal fade"
id="about" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button aria-hidden="true" class="close"
data-dismiss="modal" type="button">x</button>
<h4 class="modal-title" id="myModalLabel">Petri Net</h4>
</div>
<div class="modal-body">
<p>
<span class="title">Andy simulator is part of the
SNAKES toolkit</span><br />
(C) 2014 Franck Pommereau
</p>
<p>
<a href="http://www.ibisc.univ-evry.fr/~fpommereau/SNAKES"
target="_blank">SNAKES homepage</a>
</p>
</div>
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal"
type="button">Close</button>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$.simisc({
"nav":{
"about": {
"text": "About",
"attr": {
"id":"ui-about",
"data-toggle": "modal",
"data-target": "#about"
}
},
"net": {
"text": "Petri Net",
"attr": {
"id":"ui-net",
"data-toggle": "modal",
"data-target": "#net"
}
}
},
"graph": {
"activate": false
}
});
});
</script>
</div>
<script>
$(document).ready(function(){
$.simisc({ "nav":{ "about": { "text": "About",
"attr": { "id":"ui-about",
"data-toggle": "modal",
"data-target": "#about"
} } },
"graph": { "color": { "y":"red",
"x":"blue" } } });
});
</script>
</body>
</html>
......
<div class="container-fluid">
<div class="row">
<div class="page-header">
<h1><tt>%(filename)s</tt> <small> powered by Franck</small></h1>
<h1><tt>Andy Simulator</tt> <small> powered by Franck</small></h1>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="row">
<div class="col-md-4">
<div class="row">
<h3>Player</h3>
<div id="player"></div>
<div id="player">&nbsp;</div>
</div>
</div>
</div>
<div id="model" class="row">
<div class="col-md-6">
<div class="row">
<h3>ABCD</h3>
<div class="abcd">%(abcd)s</div>
<h3>Modes</h3>
<div id="modes">&nbsp;</div>
</div>
</div>
<div class=col-md-6>
<div class="row">
<h3>Tree</h3>
<div class="tree">%(tree)s</div>
<h3>Command Panel</h3>
<div id="Command_center">&nbsp;</div>
</div>
</div>
<div class="col-md-12">
<div id="trace_zone"></div>
<div class="col-md-8">
<div class="row">
<h3>Net Graph</h3>
<div id="graph">&nbsp;</div>
</div>
</div>
</div>
<div class="modal fade" id="net" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" style="width:auto;">
<div class="modal-content" style="overflow: scroll;">
%(net)s
</div>
<div class="row">
<div class="col-md-12">
<div id="trace_zone">&nbsp;</div>
</div>
</div>
\ No newline at end of file
</div>
</div>
......
from snakes.utils.simul import BaseSimulator, BaseHTTPSimulator
import snakes.utils.abcd.html as html
class ABCDSimulator (BaseSimulator) :
def __init__ (self, node, net, gv) :
BaseSimulator.__init__(self, net)
a2html = html.ABCD2HTML(node)
n2html = html.Net2HTML(net, gv, a2html)
self.info = {"filename" : node.st.filename,
"abcd" : a2html.html(),
"tree" : n2html.html(),
"net" : n2html.svg()}
self.tree = {}
for node in net.node() :
nid = gv.nodemap[node.name]
if nid in n2html.n2t :
self.tree[node.name] = "#" + n2html.n2t[nid]
self.places = [place.name for place in net.place()
if place.name in self.tree]
self.abcd = {}
self.transid = []
for trans in net.transition() :
nid = gv.nodemap[trans.name]
self.transid.append(self.tree[trans.name])
if nid in n2html.n2a :
self.abcd[trans.name] = ", ".join("#" + i for i in
n2html.n2a[nid])
def init (self, state=-1) :
res = BaseSimulator.init(self, state)
res.update(self.info)
res["help"] = self.init_help()
return res
def init_help (self) :
help = BaseSimulator.init_help(self)
help.update({
"#model .abcd" : {
"title" : "Source",
"content" : "ABCD source code"
},
"#model .tree" : {
"title" : "State",
"content" : "hierarchy of ABCD objects",
},
"#model .petrinet" : {
"title" : "Net",
"content" : "Petri nets semantics"
}})
return help
class AndySimulator (BaseSimulator) :
def getstate (self, state) :
ret = BaseSimulator.getstate(self, state)
marking = self.states[state]
modes = dict((t, []) for t in self.transid)
for i, (trans, mode) in enumerate(marking.modes) :
modes[self.tree[trans.name]].append({"state" : state,
"mode" : i,
"html" : str(mode)})
return {"id" : state,
"states" :
[{"do" : "dropclass",
"select" : "#model .active",
"class" : "active"}]
+ [{"do" : "addclass",
"select" : self.abcd[trans.name],
"class" : "active"} for trans, mode in marking.modes]
+ [{"do" : "addclass",
"select" : self.tree[trans.name],
"class" : "active"} for trans, mode in marking.modes]
+ [{"do" : "settext",
"select" : "%s .content" % self.tree[place],
"text" : "{}"} for place in self.places
if place not in marking]
+ [{"do" : "settext",
"select" : "%s .content" % self.tree[place],
"text" : str(marking[place])} for place in marking
if place in self.tree],
"modes" : [{"select" : "%s + .modes" % trans,
"items" : items}
for trans, items in modes.items()],
}
ret["variables"] = dict((place, tokens.items()[0])
for place, tokens in marking.items())
ret["groups"] = ["timed", "even", "odd"]
modes = []
for i, (trans, binding) in enumerate(marking.modes) :
if (state + i) % 5 == 0 :
groups = ["timed"]
else :
groups = []
modes.append(
{"state" : state,
"mode" : i,
"html" : "%s (%s)" % (trans.name[7:], binding),
"groups" : groups + ["odd" if (state % 2) else "even"]
})
ret["modes"] = [{"select": "#modes", "items": modes}]
return ret
#class Simulator (BaseHTTPSimulator) :
# def __init__ (self, **system) :
# simul = AndySimulator(**system)
# BaseHTTPSimulator.__init__(self, simulator=simul)
class Simulator (BaseHTTPSimulator) :
def __init__ (self, node, net, gv, port) :
simul = ABCDSimulator(node, net, gv)
def __init__ (self, net, port) :
simul = AndySimulator(net)
BaseHTTPSimulator.__init__(self, net, simulator=simul, port=port)
def init_model (self) :
return self.res["model.html"] % self.simul.info
def init_ui (self) :
return BaseHTTPSimulator.init_ui(self)[:-1] + [{
"label" : "Show net",
"id" : "ui-shownet",
"href" : "#",
"script" : "dialog($('#model .petrinet').html())"
}]
# def init_model (self) :
# return self.res["model.html"] % self.simul.info
# def init_ui (self) :
# return BaseHTTPSimulator.init_ui(self)[:-1] + [{
# "label" : "Show net",
# "id" : "ui-shownet",
# "href" : "#",
# "script" : "dialog($('#model .petrinet').html())"
# }]
......
from snakes.lang.abcd.parser import ast
class NodeCopier (ast.NodeTransformer) :
def copy (self, node, **replace) :
args = {}
for name in node._fields + node._attributes :
old = getattr(node, name, None)
if name in replace :
new = replace[name]
elif isinstance(old, list):
new = []
for val in old :
if isinstance(val, ast.AST) :
new.append(self.visit(val))
else :
new.append(val)
elif isinstance(old, ast.AST):
new = self.visit(old)
else :
new = old
args[name] = new
if hasattr(node, "st") :
args["st"] = node.st
return node.__class__(**args)
def generic_visit (self, node) :
return self.copy(node)
class ArgsBinder (NodeCopier) :
def __init__ (self, args, buffers, nets, tasks) :
NodeCopier.__init__(self)
self.args = args
self.buffers = buffers
self.nets = nets
self.tasks = tasks
def visit_Name (self, node) :
if node.id in self.args :
return self.copy(self.args[node.id])
else :
return self.copy(node)
def visit_Instance (self, node) :
if node.net in self.nets :
return self.copy(node, net=self.nets[node.net])
else :
return self.copy(node)
def _visit_access (self, node) :
if node.buffer in self.buffers :
return self.copy(node, buffer=self.buffers[node.buffer])
else :
return self.copy(node)
def visit_SimpleAccess (self, node) :
return self._visit_access(node)
def visit_FlushAccess (self, node) :
return self._visit_access(node)
def visit_SwapAccess (self, node) :
return self._visit_access(node)
def _visit_task (self, node) :
if node.net in self.tasks :
return self.copy(node, net=self.tasks[node.net])
else :
return self.copy(node)
def visit_Spawn (self, node) :
return self._visit_task(node)
def visit_Wait (self, node) :
return self._visit_task(node)
def visit_Suspend (self, node) :
return self._visit_task(node)
def visit_Resume (self, node) :
return self._visit_task(node)
def visit_AbcdNet (self, node) :
args = self.args.copy()
buffers = self.buffers.copy()
nets = self.nets.copy()
tasks = self.tasks.copy()
netargs = ([a.arg for a in node.args.args + node.args.kwonlyargs]
+ [node.args.vararg, node.args.kwarg])
copy = True
for a in netargs :
for d in (args, buffers, nets, tasks) :
if a in d :
del d[a]
copy = False
if copy :
return self.copy(node)
else :
return self.__class__(args, buffers, nets, tasks).visit(node)
if __name__ == "__main__" :
import doctest
doctest.testmod()