Jordan de la Houssaye

integrates andy's frontend and backend

1 +# entities: tuple of name of the entities, initial level, tuple of decays 0
2 +# denotes unbounded decay (omega)
3 +# examples:
4 +# entities = ( ('B',4, (0,2,2,2,3)), ('P',0, (0,0)), ('C',0, (0,0)),
5 +# ('G',0, (0,0)) )
6 +# entities = ( ('Sugar',1, (0,2)), ('Aspartame',0, (0,2)),
7 +# ('Glycemia',2, (0,2,2,2)), ('Glucagon',0, (0,2)),
8 +# ('Insulin',0,(0,2,2)) )
9 +
10 +entities = ( ('s1',0, (0,1)), ('s2',0, (0,1)), ('s3',0, (0,1)) )
11 +
12 +# Activities: Tuple of (activators, inhibitors, results, duration)
13 +# activators, inhibitors are dictionaries of pairs
14 +# (entity, level)
15 +# results are dictionaries of pairs (entity, +z)
16 +
17 +# potential activities examples:
18 +# potential = ( (dict([('P',0)]),dict([('P',1)]),dict([('P',1)]),0),
19 +# (dict([('P',1)]),dict(),dict([('P',-1)]),0),
20 +# (dict([('C',0)]),dict([('C',1)]),dict([('C',1)]),0),
21 +# (dict([('C',1)]),dict(),dict([('C',-1)]),0),
22 +# (dict([('G',0)]),dict([('G',1)]),dict([('G',1)]),0),
23 +# (dict([('G',1)]),dict(),dict([('G',-1)]),0) )
24 +# potential = ( (dict([('Sugar',1)]),dict(),
25 +# dict([('Insulin',1),('Glycemia',1)]),0),
26 +# (dict([('Aspartame',1)]),dict(),dict([('Insulin',1)]),0),
27 +# (dict(),dict([('Glycemia',1)]),dict([('Glucagon',1)]),0),
28 +# (dict([('Glycemia',3)]),dict(),dict([('Insulin',1)]),0),
29 +# (dict([('Insulin',2)]),dict(),dict([('Glycemia',-1)]),0),
30 +# (dict([('Insulin',1),('Glycemia',3)]), dict(),
31 +# dict([('Glycemia',-1)]),0),
32 +# (dict([('Insulin',1)]),dict([('Glycemia',2)]),
33 +# dict([('Glycemia',-1)]),0),
34 +# (dict([('Glucagon',1)]),dict(),dict([('Glycemia',+1)]),0)
35 +# )
36 +
37 +potential = ( (dict(), dict([('s1',1)]), dict([('s2',1)]), 1),
38 + (dict(), dict([('s2',1)]), dict([('s3',1)]), 1),
39 + (dict(), dict([('s3',1)]), dict([('s1',1)]), 1) )
40 +
41 +# obligatory activities examples:
42 +# obligatory = ( (dict([('P',1)]),dict(),dict([('B',1)]),1),
43 +# (dict([('C',1)]),dict(),dict([('B',-1)]),3),
44 +# (dict([('G',1)]),dict(),dict([('B',-2)]),3))
45 +
46 +obligatory = ()
47 +
1 -"""This package features the ABCD compiler, this is mainly a 1 +"""This package features the Andy compiler, this is mainly a
2 command-line tool but it can be called also from Python. The API is 2 command-line tool but it can be called also from Python. The API is
3 very simple and mimics the command line interface 3 very simple and mimics the command line interface
4 4
5 -### Function `snakes.utils.abcd.main.main` ### 5 +### Function `snakes.utils.andy.main.main` ###
6 6
7 :::python 7 :::python
8 - def main (args=sys.argv[1:], src=None) : ... 8 + def main (args=sys.argv[1:]) : ...
9 9
10 Entry point of the compiler 10 Entry point of the compiler
11 11
12 ##### Call API ##### 12 ##### Call API #####
13 13
14 * `list args`: 14 * `list args`:
15 - * `str src`:
16 * `return PetriNet`: 15 * `return PetriNet`:
17 16
18 ##### Exceptions ##### 17 ##### Exceptions #####
......
1 -import snakes.plugins
2 -snakes.plugins.load(['gv', 'ops'], 'snakes.nets', 'nets')
3 -from nets import *
4 -
5 -
6 ############################################################################### 1 ###############################################################################
7 ## AUXILIARY FUNCTIONS ######################################################## 2 ## AUXILIARY FUNCTIONS ########################################################
8 3
...@@ -132,14 +127,14 @@ def potentialt (name, lp, up, lambdap, R) : ...@@ -132,14 +127,14 @@ def potentialt (name, lp, up, lambdap, R) :
132 127
133 ############################################################################### 128 ###############################################################################
134 ## MAIN ####################################################################### 129 ## MAIN #######################################################################
135 -def andy2snakes(entities, potential, obligatory): 130 +def andy2snakes(snk, entities, potential, obligatory):
136 # compute maximal duration of activities 131 # compute maximal duration of activities
137 D=0 132 D=0
138 for alpha in potential : D = max(D, alpha[3]) 133 for alpha in potential : D = max(D, alpha[3])
139 134
140 for alpha in obligatory : D = max(D, alpha[3]) 135 for alpha in obligatory : D = max(D, alpha[3])
141 136
142 - n = PetriNet('andy') 137 + n = snk.PetriNet('andy')
143 138
144 n.globals["obligatory"] = obligatory 139 n.globals["obligatory"] = obligatory
145 n.globals["D"] = D 140 n.globals["D"] = D
...@@ -153,13 +148,13 @@ def andy2snakes(entities, potential, obligatory): ...@@ -153,13 +148,13 @@ def andy2snakes(entities, potential, obligatory):
153 level = entities[i][1] 148 level = entities[i][1]
154 deltas = entities[i][2] 149 deltas = entities[i][2]
155 vector = [0]*len(deltas) 150 vector = [0]*len(deltas)
156 - n.add_place(Place(name, [(level,0, tuple(vector))])) 151 + n.add_place(snk.Place(name, [(level,0, tuple(vector))]))
157 152
158 ################# clock transition 153 ################# clock transition
159 inputlist = dict() 154 inputlist = dict()
160 n.globals["inputlist"] = inputlist 155 n.globals["inputlist"] = inputlist
161 156
162 - n.add_transition(Transition('tc')) 157 + n.add_transition(snk.Transition('tc'))
163 158
164 159
165 # connect all obligatory clocks 160 # connect all obligatory clocks
...@@ -167,7 +162,7 @@ def andy2snakes(entities, potential, obligatory): ...@@ -167,7 +162,7 @@ def andy2snakes(entities, potential, obligatory):
167 # transition name 162 # transition name
168 obname = 'ob'+str(i) 163 obname = 'ob'+str(i)
169 # for every obligatory activity connect corresponding place to clock 164 # for every obligatory activity connect corresponding place to clock
170 - n.add_place(Place('p'+obname, [0])) 165 + n.add_place(snk.Place('p'+obname, [0]))
171 n.add_input('p'+obname, 'tc', Variable('w'+obname)) 166 n.add_input('p'+obname, 'tc', Variable('w'+obname))
172 inputlist.update({obname:'w'+obname}) 167 inputlist.update({obname:'w'+obname})
173 168
...@@ -178,20 +173,20 @@ def andy2snakes(entities, potential, obligatory): ...@@ -178,20 +173,20 @@ def andy2snakes(entities, potential, obligatory):
178 deltas = entities[i][2] 173 deltas = entities[i][2]
179 n.globals["deltas"+name] = deltas 174 n.globals["deltas"+name] = deltas
180 n.globals[name] = name 175 n.globals[name] = name
181 - n.add_input(name, 'tc', Tuple([Variable('l'+name), Variable('u'+name), Variable('lambda'+name) ])) 176 + n.add_input(name, 'tc', snk.Tuple([snk.Variable('l'+name), snk.Variable('u'+name), snk.Variable('lambda'+name) ]))
182 inputlist.update({name:['l'+name, 'u'+name, 'lambda'+name ]}) 177 inputlist.update({name:['l'+name, 'u'+name, 'lambda'+name ]})
183 178
184 179
185 180
186 for i in range(0,len(entities)): 181 for i in range(0,len(entities)):
187 name=entities[i][0] 182 name=entities[i][0]
188 - n.add_output(name, 'tc', Expression("clockt(obligatory,"+name+",l"+name+',u'+name+',lambda'+name+',deltas'+name+',inputlist,D)')) 183 + n.add_output(name, 'tc', snk.Expression("clockt(obligatory,"+name+",l"+name+',u'+name+',lambda'+name+',deltas'+name+',inputlist,D)'))
189 184
190 185
191 for i in range(0,len(obligatory)): 186 for i in range(0,len(obligatory)):
192 obname = 'ob'+str(i) 187 obname = 'ob'+str(i)
193 # for every obligatory activity connect corresponding place to clock 188 # for every obligatory activity connect corresponding place to clock
194 - n.add_output('p'+obname, 'tc', Expression("clockbetat(obligatory,"+str(i)+',w'+obname+',inputlist,D)')) 189 + n.add_output('p'+obname, 'tc', snk.Expression("clockbetat(obligatory,"+str(i)+',w'+obname+',inputlist,D)'))
195 190
196 191
197 ## potential activities 192 ## potential activities
...@@ -200,15 +195,15 @@ def andy2snakes(entities, potential, obligatory): ...@@ -200,15 +195,15 @@ def andy2snakes(entities, potential, obligatory):
200 trname = 'tr'+str(i) 195 trname = 'tr'+str(i)
201 196
202 # for every potential activity connect corresponding place to clock 197 # for every potential activity connect corresponding place to clock
203 - n.add_place(Place('p'+trname, [0])) 198 + n.add_place(snk.Place('p'+trname, [0]))
204 - n.add_input('p'+trname, 'tc', Variable('w'+trname)) 199 + n.add_input('p'+trname, 'tc', snk.Variable('w'+trname))
205 - n.add_output('p'+trname, 'tc', Expression('min(D,w'+trname+'+1)')) 200 + n.add_output('p'+trname, 'tc', snk.Expression('min(D,w'+trname+'+1)'))
206 201
207 202
208 activators = potential[i][0] 203 activators = potential[i][0]
209 inhibitors = potential[i][1] 204 inhibitors = potential[i][1]
210 results = potential[i][2] 205 results = potential[i][2]
211 - print results 206 + #print results
212 n.globals["results"+trname] = results 207 n.globals["results"+trname] = results
213 duration = potential[i][3] 208 duration = potential[i][3]
214 209
...@@ -240,14 +235,14 @@ def andy2snakes(entities, potential, obligatory): ...@@ -240,14 +235,14 @@ def andy2snakes(entities, potential, obligatory):
240 level = str(inhibitors[nameinhib[j]]) 235 level = str(inhibitors[nameinhib[j]])
241 guard += ' and l'+spec+'< '+ level + ' and lambda' +spec+'['+level+']>='+str(duration) 236 guard += ' and l'+spec+'< '+ level + ' and lambda' +spec+'['+level+']>='+str(duration)
242 237
243 - n.add_transition(Transition(trname, Expression(guard))) 238 + n.add_transition(snk.Transition(trname, snk.Expression(guard)))
244 - n.add_input('p'+trname, trname, Variable('w')) 239 + n.add_input('p'+trname, trname, snk.Variable('w'))
245 - n.add_output('p'+trname, trname, Expression('0')) 240 + n.add_output('p'+trname, trname, snk.Expression('0'))
246 241
247 # arcs of the transition from and to involved entities 242 # arcs of the transition from and to involved entities
248 for j in range(0,len(names)) : 243 for j in range(0,len(names)) :
249 - n.add_input(names[j], trname, Tuple([Variable('l'+names[j]), Variable('u'+names[j]), Variable('lambda'+names[j]) ])) 244 + n.add_input(names[j], trname, snk.Tuple([snk.Variable('l'+names[j]), snk.Variable('u'+names[j]), snk.Variable('lambda'+names[j]) ]))
250 - n.add_output(names[j], trname, Expression("potentialt(" +names[j]+",l"+names[j]+',u'+names[j]+',lambda'+names[j]+', results'+trname+')')) 245 + n.add_output(names[j], trname, snk.Expression("potentialt(" +names[j]+",l"+names[j]+',u'+names[j]+',lambda'+names[j]+', results'+trname+')'))
251 246
252 return n 247 return n
253 248
...@@ -255,7 +250,7 @@ def andy2snakes(entities, potential, obligatory): ...@@ -255,7 +250,7 @@ def andy2snakes(entities, potential, obligatory):
255 def draw_net(net, out_name='repress'): 250 def draw_net(net, out_name='repress'):
256 net.draw(out_name+'.ps') 251 net.draw(out_name+'.ps')
257 252
258 -def draw_stategraph(net, entities_names, out_name='repressgraph', 253 +def draw_stategraph(snk, net, entities_names, out_name='repressgraph',
259 with_dot=True): 254 with_dot=True):
260 def node_attr (state, graph, attr) : 255 def node_attr (state, graph, attr) :
261 marking = graph[state] 256 marking = graph[state]
...@@ -264,7 +259,7 @@ def draw_stategraph(net, entities_names, out_name='repressgraph', ...@@ -264,7 +259,7 @@ def draw_stategraph(net, entities_names, out_name='repressgraph',
264 def edge_attr (trans, mode, attr) : 259 def edge_attr (trans, mode, attr) :
265 attr["label"] = trans.name 260 attr["label"] = trans.name
266 261
267 - s = StateGraph(net) 262 + s = snk.StateGraph(net)
268 s.build() 263 s.build()
269 264
270 s.draw(out_name+'.ps', node_attr=node_attr, edge_attr=edge_attr, 265 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', ...@@ -278,6 +273,9 @@ def draw_stategraph(net, entities_names, out_name='repressgraph',
278 g.render(out_name+"-layout.dot", engine="dot") 273 g.render(out_name+"-layout.dot", engine="dot")
279 274
280 if __name__=='__main__': 275 if __name__=='__main__':
276 + import snakes.plugins
277 + snakes.plugins.load(['gv', 'ops'], 'snakes.nets', 'snk')
278 +
281 # entities: tuple of name of the entities, initial level, tuple of decays 0 279 # entities: tuple of name of the entities, initial level, tuple of decays 0
282 # denotes unbounded decay (omega) 280 # denotes unbounded decay (omega)
283 # examples: 281 # examples:
...@@ -325,7 +323,7 @@ if __name__=='__main__': ...@@ -325,7 +323,7 @@ if __name__=='__main__':
325 323
326 obligatory = () 324 obligatory = ()
327 325
328 - net = andy2snakes(entities, potential, obligatory) 326 + net = andy2snakes(snk, entities, potential, obligatory)
329 draw_net(net, out_name="repress") 327 draw_net(net, out_name="repress")
330 - draw_stategraph(net, ("s1", "s2", "s3"), out_name="repressgraph") 328 + draw_stategraph(snk, net, ("s1", "s2", "s3"), out_name="repressgraph")
331 329
......
This diff is collapsed. Click to expand it.
1 -import heapq
2 -from snakes.nets import StateGraph
3 -import snakes.lang
4 -import snkast as ast
5 -
6 -class Checker (object) :
7 - def __init__ (self, net) :
8 - self.g = StateGraph(net)
9 - self.f = [self.build(f) for f in net.label("asserts")]
10 - def build (self, tree) :
11 - src = """
12 -def check (_) :
13 - return %s
14 -""" % tree.st.source()[7:]
15 - ctx = dict(self.g.net.globals)
16 - ctx["bounded"] = self.bounded
17 - exec(src, ctx)
18 - fun = ctx["check"]
19 - fun.lineno = tree.lineno
20 - return fun
21 - def bounded (self, marking, max) :
22 - return all(len(marking(p)) == 1 for p in marking)
23 - def run (self) :
24 - for state in self.g :
25 - marking = self.g.net.get_marking()
26 - for place in marking :
27 - if max(marking(place).values()) > 1 :
28 - return None, self.trace(state)
29 - for check in self.f :
30 - try :
31 - if not check(marking) :
32 - return check.lineno, self.trace(state)
33 - except :
34 - pass
35 - return None, None
36 - def path (self, tgt, src=0) :
37 - q = [(0, src, ())]
38 - visited = set()
39 - while True :
40 - (c, v1, path) = heapq.heappop(q)
41 - if v1 not in visited :
42 - path = path + (v1,)
43 - if v1 == tgt :
44 - return path
45 - visited.add(v1)
46 - for v2 in self.g.successors(v1) :
47 - if v2 not in visited :
48 - heapq.heappush(q, (c+1, v2, path))
49 - def trace (self, state) :
50 - path = self.path(state)
51 - return tuple(self.g.successors(i)[j]
52 - for i, j in zip(path[:-1], path[1:]))
This diff is collapsed. Click to expand it.
1 import sys, optparse, os.path, webbrowser 1 import sys, optparse, os.path, webbrowser
2 import pdb, traceback 2 import pdb, traceback
3 import snakes.plugins 3 import snakes.plugins
4 -from snakes.utils.abcd.build import Builder 4 +from snakes.utils.andy import CompilationError, DeclarationError
5 -from snakes.lang.abcd.parser import parse 5 +from snakes.utils.andy.simul import Simulator, AndySimulator
6 -from snakes.lang.pgen import ParseError 6 +from snakes.utils.andy.andy import andy2snakes
7 -from snakes.utils.abcd import CompilationError, DeclarationError
8 -from snakes.utils.abcd.simul import Simulator, ABCDSimulator
9 -from snakes.utils.abcd.checker import Checker
10 -from snakes.utils.abcd.html import build as html
11 from snakes.utils.simul.html import json 7 from snakes.utils.simul.html import json
12 8
13 ## 9 ##
...@@ -26,11 +22,11 @@ ERR_OUTPUT = 7 ...@@ -26,11 +22,11 @@ ERR_OUTPUT = 7
26 ERR_BUG = 255 22 ERR_BUG = 255
27 23
28 def log (message) : 24 def log (message) :
29 - sys.stdout.write("abcd: %s\n" % message.strip()) 25 + sys.stdout.write("andy: %s\n" % message.strip())
30 sys.stdout.flush() 26 sys.stdout.flush()
31 27
32 def err (message) : 28 def err (message) :
33 - sys.stderr.write("abcd: %s\n" % message.strip()) 29 + sys.stderr.write("andy: %s\n" % message.strip())
34 sys.stderr.flush() 30 sys.stderr.flush()
35 31
36 def die (code, message=None) : 32 def die (code, message=None) :
...@@ -66,7 +62,7 @@ def bug () : ...@@ -66,7 +62,7 @@ def bug () :
66 62
67 gv_engines = ("dot", "neato", "twopi", "circo", "fdp") 63 gv_engines = ("dot", "neato", "twopi", "circo", "fdp")
68 64
69 -opt = optparse.OptionParser(prog="abcd", 65 +opt = optparse.OptionParser(prog="andy",
70 usage="%prog [OPTION]... FILE") 66 usage="%prog [OPTION]... FILE")
71 opt.add_option("-l", "--load", 67 opt.add_option("-l", "--load",
72 dest="plugins", action="append", default=[], 68 dest="plugins", action="append", default=[],
...@@ -81,9 +77,6 @@ for engine in gv_engines : ...@@ -81,9 +77,6 @@ for engine in gv_engines :
81 dest="gv" + engine, action="store", default=None, 77 dest="gv" + engine, action="store", default=None,
82 help="draw net using '%s' (from GraphViz)" % engine, 78 help="draw net using '%s' (from GraphViz)" % engine,
83 metavar="OUTFILE") 79 metavar="OUTFILE")
84 -opt.add_option("-a", "--all-names",
85 - dest="allnames", action="store_true", default=False,
86 - help="draw control-flow places names (default: hide)")
87 opt.add_option("--debug", 80 opt.add_option("--debug",
88 dest="debug", action="store_true", default=False, 81 dest="debug", action="store_true", default=False,
89 help="launch debugger on compiler error (default: no)") 82 help="launch debugger on compiler error (default: no)")
...@@ -98,22 +91,13 @@ opt.add_option("--port", ...@@ -98,22 +91,13 @@ opt.add_option("--port",
98 dest="port", action="store", default=8000, type=int, 91 dest="port", action="store", default=8000, type=int,
99 help="port on which the simulator server runs", 92 help="port on which the simulator server runs",
100 metavar="PORT") 93 metavar="PORT")
101 -opt.add_option("-H", "--html",
102 - dest="html", action="store", default=None,
103 - help="save net as HTML",
104 - metavar="OUTFILE")
105 -opt.add_option("--check",
106 - dest="check", action="store_true", default=False,
107 - help="check assertions")
108 94
109 def getopts (args) : 95 def getopts (args) :
110 - global options, abcd, tmp 96 + global options, andy, tmp
111 (options, args) = opt.parse_args(args) 97 (options, args) = opt.parse_args(args)
112 plugins = [] 98 plugins = []
113 for p in options.plugins : 99 for p in options.plugins :
114 plugins.extend(t.strip() for t in p.split(",")) 100 plugins.extend(t.strip() for t in p.split(","))
115 - if "ops" not in options.plugins :
116 - plugins.append("ops")
117 if "labels" not in plugins : 101 if "labels" not in plugins :
118 plugins.append("labels") 102 plugins.append("labels")
119 for engine in gv_engines : 103 for engine in gv_engines :
...@@ -121,7 +105,7 @@ def getopts (args) : ...@@ -121,7 +105,7 @@ def getopts (args) :
121 if gvopt and "gv" not in plugins : 105 if gvopt and "gv" not in plugins :
122 plugins.append("gv") 106 plugins.append("gv")
123 break 107 break
124 - if (options.html or options.simul) and "gv" not in plugins : 108 + if (options.simul) and "gv" not in plugins :
125 plugins.append("gv") 109 plugins.append("gv")
126 options.plugins = plugins 110 options.plugins = plugins
127 if len(args) < 1 : 111 if len(args) < 1 :
...@@ -132,17 +116,13 @@ def getopts (args) : ...@@ -132,17 +116,13 @@ def getopts (args) :
132 err("more than one input file provided") 116 err("more than one input file provided")
133 opt.print_help() 117 opt.print_help()
134 die(ERR_ARG) 118 die(ERR_ARG)
135 - abcd = args[0] 119 + andy = args[0]
136 - if options.pnml == abcd : 120 + if options.pnml == andy :
137 err("input file also used as output (--pnml)") 121 err("input file also used as output (--pnml)")
138 opt.print_help() 122 opt.print_help()
139 die(ERR_ARG) 123 die(ERR_ARG)
140 - if options.html == abcd :
141 - err("input file also used as output (--html)")
142 - opt.print_help()
143 - die(ERR_ARG)
144 for engine in gv_engines : 124 for engine in gv_engines :
145 - if getattr(options, "gv%s" % engine) == abcd : 125 + if getattr(options, "gv%s" % engine) == andy :
146 err("input file also used as output (--%s)" % engine) 126 err("input file also used as output (--%s)" % engine)
147 opt.print_help() 127 opt.print_help()
148 die(ERR_ARG) 128 die(ERR_ARG)
...@@ -151,58 +131,9 @@ def getopts (args) : ...@@ -151,58 +131,9 @@ def getopts (args) :
151 ## drawing nets 131 ## drawing nets
152 ## 132 ##
153 133
154 -def place_attr (place, attr) :
155 - # fix color
156 - if place.status == snk.entry :
157 - attr["fillcolor"] = "green"
158 - elif place.status == snk.internal :
159 - pass
160 - elif place.status == snk.exit :
161 - attr["fillcolor"] = "orange"
162 - else :
163 - attr["fillcolor"] = "lightblue"
164 - # fix shape
165 - if (not options.allnames
166 - and place.status in (snk.entry, snk.internal, snk.exit)) :
167 - attr["shape"] = "circle"
168 - # render marking
169 - if place._check == snk.tBlackToken :
170 - count = len(place.tokens)
171 - if count == 0 :
172 - marking = " "
173 - elif count == 1 :
174 - marking = "&#8226;"
175 - else :
176 - marking = "%s&#8226;" % count
177 - else :
178 - marking = str(place.tokens)
179 - # node label
180 - if (options.allnames
181 - or place.status not in (snk.entry, snk.internal, snk.exit)) :
182 - attr["label"] = "%s\\n%s" % (place.name, marking)
183 - else :
184 - attr["label"] = "%s" % marking
185 -
186 -def trans_attr (trans, attr) :
187 - pass
188 -
189 -def arc_attr (label, attr) :
190 - if label == snk.Value(snk.dot) :
191 - del attr["label"]
192 - elif isinstance(label, snk.Test) :
193 - attr["arrowhead"] = "none"
194 - attr["label"] = " %s " % label._annotation
195 - elif isinstance(label, snk.Flush) :
196 - attr["arrowhead"] = "box"
197 - attr["label"] = " %s " % label._annotation
198 -
199 -
200 def draw (net, target, engine="dot") : 134 def draw (net, target, engine="dot") :
201 try : 135 try :
202 - return net.draw(target, engine=engine, 136 + return net.draw(target, engine=engine)
203 - place_attr=place_attr,
204 - trans_attr=trans_attr,
205 - arc_attr=arc_attr)
206 except : 137 except :
207 die(ERR_OUTPUT, str(sys.exc_info()[1])) 138 die(ERR_OUTPUT, str(sys.exc_info()[1]))
208 139
...@@ -222,49 +153,36 @@ def save_pnml (net, target) : ...@@ -222,49 +153,36 @@ def save_pnml (net, target) :
222 ## simulator (not standalone) 153 ## simulator (not standalone)
223 ## 154 ##
224 155
225 -def simulate (source, filename="<string>") : 156 +def simulate (entities, potential, obligatory, filename='<string>') :
226 global options, snk 157 global options, snk
227 getopts(["--simul", filename]) 158 getopts(["--simul", filename])
228 - node = parse(source, filename=filename)
229 snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk") 159 snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk")
230 - build = Builder(snk) 160 + net = andy2snakes(snk, entities, potential, obligatory)
231 - net = build.build(node)
232 net.label(srcfile=filename, snakes=snk) 161 net.label(srcfile=filename, snakes=snk)
233 - return ABCDSimulator(node, net, draw(net, None)) 162 + return AndySimulator(net)
234 163
235 ## 164 ##
236 ## main 165 ## main
237 ## 166 ##
238 167
239 -def main (args=sys.argv[1:], src=None) : 168 +def main (args=sys.argv[1:]) :
240 global options, snk 169 global options, snk
241 # get options 170 # get options
242 try: 171 try:
243 - if src is None : 172 + getopts(args)
244 - getopts(args)
245 - else :
246 - getopts(list(args) + ["<string>"])
247 except SystemExit : 173 except SystemExit :
248 raise 174 raise
249 except : 175 except :
250 die(ERR_OPT, str(sys.exc_info()[1])) 176 die(ERR_OPT, str(sys.exc_info()[1]))
251 - # read source 177 + # read andy spec
252 - if src is not None : 178 + try:
253 - source = src 179 + env = {}
254 - else : 180 + execfile(andy, env)
255 - try : 181 + del env['__builtins__']
256 - source = open(abcd).read() 182 + except:
257 - except : 183 + die(ERR_IO, "could not read input file %r" % andy)
258 - die(ERR_IO, "could not read input file %r" % abcd) 184 + # compile to net
259 - # parse 185 + dirname = os.path.dirname(andy)
260 - try :
261 - node = parse(source, filename=abcd)
262 - except ParseError :
263 - die(ERR_PARSE, str(sys.exc_info()[1]))
264 - except :
265 - bug()
266 - # compile
267 - dirname = os.path.dirname(abcd)
268 if dirname and dirname not in sys.path : 186 if dirname and dirname not in sys.path :
269 sys.path.append(dirname) 187 sys.path.append(dirname)
270 elif "." not in sys.path : 188 elif "." not in sys.path :
...@@ -273,14 +191,13 @@ def main (args=sys.argv[1:], src=None) : ...@@ -273,14 +191,13 @@ def main (args=sys.argv[1:], src=None) :
273 snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk") 191 snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk")
274 except : 192 except :
275 die(ERR_PLUGIN, str(sys.exc_info()[1])) 193 die(ERR_PLUGIN, str(sys.exc_info()[1]))
276 - build = Builder(snk) 194 +
277 - try : 195 + try:
278 - net = build.build(node) 196 + net = andy2snakes(snk, env['entities'], env['potential'],
279 - net.label(srcfile=abcd, snakes=snk) 197 + env['obligatory'])
280 - except (CompilationError, DeclarationError) : 198 + except:
281 - die(ERR_COMPILE, str(sys.exc_info()[1]))
282 - except :
283 bug() 199 bug()
200 +
284 # output 201 # output
285 if options.pnml : 202 if options.pnml :
286 save_pnml(net, options.pnml) 203 save_pnml(net, options.pnml)
...@@ -288,17 +205,10 @@ def main (args=sys.argv[1:], src=None) : ...@@ -288,17 +205,10 @@ def main (args=sys.argv[1:], src=None) :
288 target = getattr(options, "gv%s" % engine) 205 target = getattr(options, "gv%s" % engine)
289 if target : 206 if target :
290 draw(net, target, engine) 207 draw(net, target, engine)
291 - if options.html :
292 - try :
293 - html(abcd, node, net, draw(net, None), options.html)
294 - except :
295 - bug()
296 trace, lineno = [], None 208 trace, lineno = [], None
297 - if options.check :
298 - lineno, trace = Checker(net).run()
299 if options.simul : 209 if options.simul :
300 try : 210 try :
301 - simul = Simulator(node, net, draw(net, None), options.port) 211 + simul = Simulator(net, options.port)
302 except : 212 except :
303 bug() 213 bug()
304 simul.start() 214 simul.start()
......
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <html> 2 <html>
3 - <head> 3 +<head>
4 - <link type="text/css" href="r/css/bootstrap-theme.css" rel="stylesheet"/> 4 + <link type="text/css" href="r/css/bootstrap-theme.css" rel="stylesheet"/>
5 - <link type="text/css" href="r/css/bootstrap.css" rel="stylesheet"/> 5 + <link type="text/css" href="r/css/bootstrap.css" rel="stylesheet"/>
6 - <link type="text/css" href="r/css/docs.css" rel="stylesheet"/> 6 + <link type="text/css" href="r/css/docs.css" rel="stylesheet"/>
7 - <link type="text/css" href="r/simulator.css" rel="stylesheet"/> 7 + <link type="text/css" href="r/simulator.css" rel="stylesheet"/>
8 - <link type="text/css" href="r/model.css" rel="stylesheet"/> 8 + <link type="text/css" href="r/model.css" rel="stylesheet"/>
9 - <script src="r/jquery.min.js"></script> 9 + <script src="r/jquery.min.js"></script>
10 - <script src="r/js/bootstrap.min.js"></script> 10 + <script src="r/js/bootstrap.min.js"></script>
11 - <script src="r/jquery.periodic.js"></script> 11 + <script src="r/jquery.periodic.js"></script>
12 - <script src="r/js/bootstrap.file-input.js"></script> 12 + <script src="r/js/bootstrap.file-input.js"></script>
13 - <script src="r/d3.min.js"></script> 13 + <script src="r/d3.min.js"></script>
14 - <script src="r/js/petri.js"></script> 14 + <script src="r/js/petri.js"></script>
15 - <script src="r/simulator.js"></script> 15 + <script src="r/simulator.js"></script>
16 - </head>
17 <style> 16 <style>
18 - path { 17 + path { stroke: steelblue;
19 - stroke: steelblue; 18 + stroke-width: 2;
20 - stroke-width: 2; 19 + fill: none; }
21 - fill: none; 20 + line { stroke: black; }
22 - } 21 + text { font-family: Arial;
23 - 22 + font-size: 9pt; }
24 - line {
25 - stroke: black;
26 - }
27 -
28 - text {
29 - font-family: Arial;
30 - font-size: 9pt;
31 - }
32 -
33 </style> 23 </style>
34 - <body> 24 +</head>
35 - 25 +<body>
36 <header class="navbar navbar-static-top"> 26 <header class="navbar navbar-static-top">
37 - <div class="container">
38 <nav class="navbar navbar-default" role="navigation"> 27 <nav class="navbar navbar-default" role="navigation">
39 <div class="container-fluid"> 28 <div class="container-fluid">
40 - <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> 29 + <div class="navbar-header">
41 - <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-6"> 30 + <button type="button" class="navbar-toggle"
42 - <ul id="nav_sim" class="nav navbar-nav"> 31 + data-toggle="collapse"
43 - <li><a href="#" id="ui-reset">Reset Simulation</a></li> 32 + data-target="#bs-example-navbar-collapse-6">
44 - <li><a href="#" id="ui-quit">Stop Simulation</a></li> 33 + <span class="sr-only">Toggle navigation</span>
45 - <li><a href="#" id="ui-help">Help</a></li> 34 + </button>
46 - </ul> 35 + <a class="navbar-brand" href="#">Simulation SNAKES</a>
47 </div> 36 </div>
37 + <div class="collapse navbar-collapse"
38 + id="bs-example-navbar-collapse-6">
39 + <ul class="nav navbar-nav" id="nav_sim">
40 + <li><a id="ui-reset">Reset Simulation</a></li>
41 + <li><a id="ui-quit">Stop Simulation</a></li>
42 + <li><a id="ui-help">Help</a></li>
43 + </ul>
44 + </div><!-- /.navbar-collapse -->
48 </div> 45 </div>
49 </nav> 46 </nav>
50 - </div>
51 </header> 47 </header>
52 - <div class="container"> 48 + <!-- model to be simulated -->
53 - 49 + %(model)s
54 - %(model)s
55 50
56 - <div class="modal fade" id="about" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> 51 + <!-- information about the simulator -->
57 - <div class="modal-dialog"> 52 + <div aria-hidden="true" aria-labelledby="myModalLabel" class="modal fade"
58 - <div class="modal-content"> 53 + id="about" role="dialog" tabindex="-1">
59 - <div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> 54 + <div class="modal-dialog">
60 - <h4 class="modal-title" id="myModalLabel">Petri Net</h4> 55 + <div class="modal-content">
61 - </div> 56 + <div class="modal-header">
62 - <div class="modal-body"> 57 + <button aria-hidden="true" class="close"
63 - <p><span class="title">ABCD simulator is part of the SNAKES toolkit</span><br /> (C) 2014 Franck Pommereau</p> 58 + data-dismiss="modal" type="button">x</button>
64 - <p><a href="http://www.ibisc.univ-evry.fr/~fpommereau/SNAKES" target="_blank">SNAKES homepage</a></p> 59 + <h4 class="modal-title" id="myModalLabel">Petri Net</h4>
65 - </div> 60 + </div>
66 - <div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div> 61 + <div class="modal-body">
62 + <p>
63 + <span class="title">Andy simulator is part of the
64 + SNAKES toolkit</span><br />
65 + (C) 2014 Franck Pommereau
66 + </p>
67 + <p>
68 + <a href="http://www.ibisc.univ-evry.fr/~fpommereau/SNAKES"
69 + target="_blank">SNAKES homepage</a>
70 + </p>
71 + </div>
72 + <div class="modal-footer">
73 + <button class="btn btn-default" data-dismiss="modal"
74 + type="button">Close</button>
67 </div> 75 </div>
68 </div> 76 </div>
69 </div> 77 </div>
70 -<script> 78 + </div>
71 - $(document).ready(function(){ 79 + <script>
72 - $.simisc({ 80 + $(document).ready(function(){
73 - "nav":{ 81 + $.simisc({ "nav":{ "about": { "text": "About",
74 - "about": { 82 + "attr": { "id":"ui-about",
75 - "text": "About", 83 + "data-toggle": "modal",
76 - "attr": { 84 + "data-target": "#about"
77 - "id":"ui-about", 85 + } } },
78 - "data-toggle": "modal", 86 + "graph": { "color": { "y":"red",
79 - "data-target": "#about" 87 + "x":"blue" } } });
80 - } 88 + });
81 - }, 89 + </script>
82 - "net": {
83 - "text": "Petri Net",
84 - "attr": {
85 - "id":"ui-net",
86 - "data-toggle": "modal",
87 - "data-target": "#net"
88 - }
89 - }
90 - },
91 - "graph": {
92 - "activate": false
93 - }
94 - });
95 - });
96 -</script>
97 </body> 90 </body>
98 </html> 91 </html>
......
1 +<div class="container-fluid">
2 +<div class="row">
1 <div class="page-header"> 3 <div class="page-header">
2 - <h1><tt>%(filename)s</tt> <small> powered by Franck</small></h1> 4 + <h1><tt>Andy Simulator</tt> <small> powered by Franck</small></h1>
5 +</div>
3 </div> 6 </div>
4 -<div class="row">
5 - <div class="col-md-3">
6 7
8 +<div class="row">
9 + <div class="col-md-4">
7 <div class="row"> 10 <div class="row">
8 <h3>Player</h3> 11 <h3>Player</h3>
9 - <div id="player"></div> 12 + <div id="player">&nbsp;</div>
10 </div> 13 </div>
11 - </div>
12 -</div>
13 -<div id="model" class="row">
14 - <div class="col-md-6">
15 <div class="row"> 14 <div class="row">
16 - <h3>ABCD</h3> 15 + <h3>Modes</h3>
17 - <div class="abcd">%(abcd)s</div> 16 + <div id="modes">&nbsp;</div>
18 </div> 17 </div>
19 18
20 - </div>
21 - <div class=col-md-6>
22 <div class="row"> 19 <div class="row">
23 - <h3>Tree</h3> 20 + <h3>Command Panel</h3>
24 - <div class="tree">%(tree)s</div> 21 + <div id="Command_center">&nbsp;</div>
25 </div> 22 </div>
26 </div> 23 </div>
27 24
28 - <div class="col-md-12"> 25 + <div class="col-md-8">
29 - <div id="trace_zone"></div> 26 + <div class="row">
27 + <h3>Net Graph</h3>
28 + <div id="graph">&nbsp;</div>
29 + </div>
30 </div> 30 </div>
31 </div> 31 </div>
32 32
33 -<div class="modal fade" id="net" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> 33 +<div class="row">
34 - <div class="modal-dialog" style="width:auto;"> 34 + <div class="col-md-12">
35 - <div class="modal-content" style="overflow: scroll;"> 35 + <div id="trace_zone">&nbsp;</div>
36 - %(net)s
37 - </div>
38 </div> 36 </div>
39 -</div>
...\ No newline at end of file ...\ No newline at end of file
37 +</div>
38 +</div>
......
1 from snakes.utils.simul import BaseSimulator, BaseHTTPSimulator 1 from snakes.utils.simul import BaseSimulator, BaseHTTPSimulator
2 -import snakes.utils.abcd.html as html
3 2
4 -class ABCDSimulator (BaseSimulator) : 3 +class AndySimulator (BaseSimulator) :
5 - def __init__ (self, node, net, gv) :
6 - BaseSimulator.__init__(self, net)
7 - a2html = html.ABCD2HTML(node)
8 - n2html = html.Net2HTML(net, gv, a2html)
9 - self.info = {"filename" : node.st.filename,
10 - "abcd" : a2html.html(),
11 - "tree" : n2html.html(),
12 - "net" : n2html.svg()}
13 - self.tree = {}
14 - for node in net.node() :
15 - nid = gv.nodemap[node.name]
16 - if nid in n2html.n2t :
17 - self.tree[node.name] = "#" + n2html.n2t[nid]
18 - self.places = [place.name for place in net.place()
19 - if place.name in self.tree]
20 - self.abcd = {}
21 - self.transid = []
22 - for trans in net.transition() :
23 - nid = gv.nodemap[trans.name]
24 - self.transid.append(self.tree[trans.name])
25 - if nid in n2html.n2a :
26 - self.abcd[trans.name] = ", ".join("#" + i for i in
27 - n2html.n2a[nid])
28 - def init (self, state=-1) :
29 - res = BaseSimulator.init(self, state)
30 - res.update(self.info)
31 - res["help"] = self.init_help()
32 - return res
33 - def init_help (self) :
34 - help = BaseSimulator.init_help(self)
35 - help.update({
36 - "#model .abcd" : {
37 - "title" : "Source",
38 - "content" : "ABCD source code"
39 - },
40 - "#model .tree" : {
41 - "title" : "State",
42 - "content" : "hierarchy of ABCD objects",
43 - },
44 - "#model .petrinet" : {
45 - "title" : "Net",
46 - "content" : "Petri nets semantics"
47 - }})
48 - return help
49 def getstate (self, state) : 4 def getstate (self, state) :
5 + ret = BaseSimulator.getstate(self, state)
50 marking = self.states[state] 6 marking = self.states[state]
51 - modes = dict((t, []) for t in self.transid) 7 + ret["variables"] = dict((place, tokens.items()[0])
52 - for i, (trans, mode) in enumerate(marking.modes) : 8 + for place, tokens in marking.items())
53 - modes[self.tree[trans.name]].append({"state" : state, 9 + ret["groups"] = ["timed", "even", "odd"]
54 - "mode" : i, 10 + modes = []
55 - "html" : str(mode)}) 11 + for i, (trans, binding) in enumerate(marking.modes) :
56 - return {"id" : state, 12 + if (state + i) % 5 == 0 :
57 - "states" : 13 + groups = ["timed"]
58 - [{"do" : "dropclass", 14 + else :
59 - "select" : "#model .active", 15 + groups = []
60 - "class" : "active"}] 16 + modes.append(
61 - + [{"do" : "addclass", 17 + {"state" : state,
62 - "select" : self.abcd[trans.name], 18 + "mode" : i,
63 - "class" : "active"} for trans, mode in marking.modes] 19 + "html" : "%s (%s)" % (trans.name[7:], binding),
64 - + [{"do" : "addclass", 20 + "groups" : groups + ["odd" if (state % 2) else "even"]
65 - "select" : self.tree[trans.name], 21 + })
66 - "class" : "active"} for trans, mode in marking.modes] 22 + ret["modes"] = [{"select": "#modes", "items": modes}]
67 - + [{"do" : "settext", 23 + return ret
68 - "select" : "%s .content" % self.tree[place], 24 +
69 - "text" : "{}"} for place in self.places 25 +#class Simulator (BaseHTTPSimulator) :
70 - if place not in marking] 26 +# def __init__ (self, **system) :
71 - + [{"do" : "settext", 27 +# simul = AndySimulator(**system)
72 - "select" : "%s .content" % self.tree[place], 28 +# BaseHTTPSimulator.__init__(self, simulator=simul)
73 - "text" : str(marking[place])} for place in marking
74 - if place in self.tree],
75 - "modes" : [{"select" : "%s + .modes" % trans,
76 - "items" : items}
77 - for trans, items in modes.items()],
78 - }
79 29
80 class Simulator (BaseHTTPSimulator) : 30 class Simulator (BaseHTTPSimulator) :
81 - def __init__ (self, node, net, gv, port) : 31 + def __init__ (self, net, port) :
82 - simul = ABCDSimulator(node, net, gv) 32 + simul = AndySimulator(net)
83 BaseHTTPSimulator.__init__(self, net, simulator=simul, port=port) 33 BaseHTTPSimulator.__init__(self, net, simulator=simul, port=port)
84 - def init_model (self) : 34 +# def init_model (self) :
85 - return self.res["model.html"] % self.simul.info 35 +# return self.res["model.html"] % self.simul.info
86 - def init_ui (self) : 36 +# def init_ui (self) :
87 - return BaseHTTPSimulator.init_ui(self)[:-1] + [{ 37 +# return BaseHTTPSimulator.init_ui(self)[:-1] + [{
88 - "label" : "Show net", 38 +# "label" : "Show net",
89 - "id" : "ui-shownet", 39 +# "id" : "ui-shownet",
90 - "href" : "#", 40 +# "href" : "#",
91 - "script" : "dialog($('#model .petrinet').html())" 41 +# "script" : "dialog($('#model .petrinet').html())"
92 - }] 42 +# }]
43 +
......
1 -from snakes.lang.abcd.parser import ast
2 -
3 -class NodeCopier (ast.NodeTransformer) :
4 - def copy (self, node, **replace) :
5 - args = {}
6 - for name in node._fields + node._attributes :
7 - old = getattr(node, name, None)
8 - if name in replace :
9 - new = replace[name]
10 - elif isinstance(old, list):
11 - new = []
12 - for val in old :
13 - if isinstance(val, ast.AST) :
14 - new.append(self.visit(val))
15 - else :
16 - new.append(val)
17 - elif isinstance(old, ast.AST):
18 - new = self.visit(old)
19 - else :
20 - new = old
21 - args[name] = new
22 - if hasattr(node, "st") :
23 - args["st"] = node.st
24 - return node.__class__(**args)
25 - def generic_visit (self, node) :
26 - return self.copy(node)
27 -
28 -class ArgsBinder (NodeCopier) :
29 - def __init__ (self, args, buffers, nets, tasks) :
30 - NodeCopier.__init__(self)
31 - self.args = args
32 - self.buffers = buffers
33 - self.nets = nets
34 - self.tasks = tasks
35 - def visit_Name (self, node) :
36 - if node.id in self.args :
37 - return self.copy(self.args[node.id])
38 - else :
39 - return self.copy(node)
40 - def visit_Instance (self, node) :
41 - if node.net in self.nets :
42 - return self.copy(node, net=self.nets[node.net])
43 - else :
44 - return self.copy(node)
45 - def _visit_access (self, node) :
46 - if node.buffer in self.buffers :
47 - return self.copy(node, buffer=self.buffers[node.buffer])
48 - else :
49 - return self.copy(node)
50 - def visit_SimpleAccess (self, node) :
51 - return self._visit_access(node)
52 - def visit_FlushAccess (self, node) :
53 - return self._visit_access(node)
54 - def visit_SwapAccess (self, node) :
55 - return self._visit_access(node)
56 - def _visit_task (self, node) :
57 - if node.net in self.tasks :
58 - return self.copy(node, net=self.tasks[node.net])
59 - else :
60 - return self.copy(node)
61 - def visit_Spawn (self, node) :
62 - return self._visit_task(node)
63 - def visit_Wait (self, node) :
64 - return self._visit_task(node)
65 - def visit_Suspend (self, node) :
66 - return self._visit_task(node)
67 - def visit_Resume (self, node) :
68 - return self._visit_task(node)
69 - def visit_AbcdNet (self, node) :
70 - args = self.args.copy()
71 - buffers = self.buffers.copy()
72 - nets = self.nets.copy()
73 - tasks = self.tasks.copy()
74 - netargs = ([a.arg for a in node.args.args + node.args.kwonlyargs]
75 - + [node.args.vararg, node.args.kwarg])
76 - copy = True
77 - for a in netargs :
78 - for d in (args, buffers, nets, tasks) :
79 - if a in d :
80 - del d[a]
81 - copy = False
82 - if copy :
83 - return self.copy(node)
84 - else :
85 - return self.__class__(args, buffers, nets, tasks).visit(node)
86 -
87 -if __name__ == "__main__" :
88 - import doctest
89 - doctest.testmod()