Franck Pommereau

fixed Inhibitor arcs, misc fixes/improvements

...@@ -1637,22 +1637,23 @@ class Inhibitor (Test) : ...@@ -1637,22 +1637,23 @@ class Inhibitor (Test) :
1637 def __hash__ (self) : 1637 def __hash__ (self) :
1638 return hash(("inhibitor", self._annotation, self._condition)) 1638 return hash(("inhibitor", self._annotation, self._condition))
1639 def bind (self, binding) : 1639 def bind (self, binding) :
1640 - """Return the value of the annotation evaluated through 1640 + """Return no tokens since arc corresponds to an absence of tokens.
1641 - `binding`, or raise `ValueError` of this binding does not 1641 + Raise `ValueError` if this binding does not validate the
1642 - validate the condition. 1642 + condition.
1643 1643
1644 >>> Inhibitor(Expression('x+1'), Expression('x>0')).bind(Substitution(x=2)) 1644 >>> Inhibitor(Expression('x+1'), Expression('x>0')).bind(Substitution(x=2))
1645 - Token(3) 1645 + ()
1646 >>> try : Inhibitor(Expression('x+1'), Expression('x<0')).bind(Substitution(x=2)) 1646 >>> try : Inhibitor(Expression('x+1'), Expression('x<0')).bind(Substitution(x=2))
1647 ... except ValueError : print(sys.exc_info()[1]) 1647 ... except ValueError : print(sys.exc_info()[1])
1648 condition not True for {x -> 2} 1648 condition not True for {x -> 2}
1649 1649
1650 @param binding: a substitution 1650 @param binding: a substitution
1651 @type binding: `Substitution` 1651 @type binding: `Substitution`
1652 - @return: a value 1652 + @return: empty tuple
1653 +
1653 """ 1654 """
1654 if self._condition(binding) : 1655 if self._condition(binding) :
1655 - return self._annotation.bind(binding) 1656 + return ()
1656 else : 1657 else :
1657 raise ValueError("condition not True for %s" % str(binding)) 1658 raise ValueError("condition not True for %s" % str(binding))
1658 def modes (self, values) : 1659 def modes (self, values) :
...@@ -2731,6 +2732,9 @@ class Marking (hdict) : ...@@ -2731,6 +2732,9 @@ class Marking (hdict) :
2731 """ 2732 """
2732 return cls(((child["id"], child.child("tokens").child().to_obj()) 2733 return cls(((child["id"], child.child("tokens").child().to_obj())
2733 for child in tree.get_children("place"))) 2734 for child in tree.get_children("place")))
2735 + def __str__ (self) :
2736 + base = "{%s}" % ", ".join("%s=%s" % pair for pair in sorted(self.items()))
2737 + return base.replace("={dot}", "")
2734 def __call__ (self, place) : 2738 def __call__ (self, place) :
2735 """Return the marking of `place`. The empty multiset is 2739 """Return the marking of `place`. The empty multiset is
2736 returned if `place` is not explicitely given in the marking. 2740 returned if `place` is not explicitely given in the marking.
......
...@@ -105,7 +105,7 @@ class Graph (Cluster) : ...@@ -105,7 +105,7 @@ class Graph (Cluster) :
105 def dot (self) : 105 def dot (self) :
106 self.done = set() 106 self.done = set()
107 return "\n".join(self._dot_text(["digraph {", 107 return "\n".join(self._dot_text(["digraph {",
108 - 'charset="UTF-8"', 108 +# 'charset="UTF-8"',
109 ['node [label="N",' 109 ['node [label="N",'
110 ' fillcolor="#FFFFFF",' 110 ' fillcolor="#FFFFFF",'
111 ' fontcolor="#000000",' 111 ' fontcolor="#000000",'
...@@ -120,7 +120,9 @@ class Graph (Cluster) : ...@@ -120,7 +120,9 @@ class Graph (Cluster) :
120 return text 120 return text
121 else : 121 else :
122 return '"%s"' % text.replace('"', r'\"') 122 return '"%s"' % text.replace('"', r'\"')
123 - def render (self, filename, engine="dot", debug=False) : 123 + def render (self, filename, engine=None, debug=False) :
124 + if engine is None :
125 + engine = getattr(self, "engine", "dot")
124 if engine not in ("dot", "neato", "twopi", "circo", "fdp") : 126 if engine not in ("dot", "neato", "twopi", "circo", "fdp") :
125 raise ValueError("unknown GraphViz engine %r" % engine) 127 raise ValueError("unknown GraphViz engine %r" % engine)
126 with codecs.open(filename + ".dot", "w", "utf-8") as outfile : 128 with codecs.open(filename + ".dot", "w", "utf-8") as outfile :
...@@ -134,12 +136,15 @@ class Graph (Cluster) : ...@@ -134,12 +136,15 @@ class Graph (Cluster) :
134 "-o" + filename, outfile.name], 136 "-o" + filename, outfile.name],
135 stdin=subprocess.PIPE, 137 stdin=subprocess.PIPE,
136 stdout=subprocess.PIPE, 138 stdout=subprocess.PIPE,
137 - stderr=subprocess.PIPE) 139 + stderr=subprocess.STDOUT)
138 - dot.communicate() 140 + stdout, stderr = dot.communicate()
139 if not debug : 141 if not debug :
140 os.unlink(outfile.name) 142 os.unlink(outfile.name)
141 if dot.returncode != 0 : 143 if dot.returncode != 0 :
142 - raise IOError("%s exited with status %s" % (engine, dot.returncode)) 144 + if stdout.strip() + stderr.strip() :
145 + stdout = "\n*** Original error message follows ***\n " + stdout
146 + raise IOError("%s exited with status %s%s"
147 + % (engine, dot.returncode, stdout))
143 def layout (self, engine="dot", debug=False) : 148 def layout (self, engine="dot", debug=False) :
144 if engine not in ("dot", "neato", "twopi", "circo", "fdp") : 149 if engine not in ("dot", "neato", "twopi", "circo", "fdp") :
145 raise ValueError("unknown GraphViz engine %r" % engine) 150 raise ValueError("unknown GraphViz engine %r" % engine)
...@@ -226,6 +231,7 @@ def extend (module) : ...@@ -226,6 +231,7 @@ def extend (module) :
226 for num, node in enumerate(self.node())) 231 for num, node in enumerate(self.node()))
227 g = self._copy(nodemap, self.clusters, cluster_attr, 232 g = self._copy(nodemap, self.clusters, cluster_attr,
228 place_attr, trans_attr) 233 place_attr, trans_attr)
234 + g.engine = engine
229 self._copy_edges(nodemap, g, arc_attr) 235 self._copy_edges(nodemap, g, arc_attr)
230 if graph_attr : 236 if graph_attr :
231 graph_attr(self, g.attr) 237 graph_attr(self, g.attr)
......
...@@ -90,8 +90,11 @@ class Builder (object) : ...@@ -90,8 +90,11 @@ class Builder (object) :
90 """raise an exception with appropriate location 90 """raise an exception with appropriate location
91 """ 91 """
92 if self.stack : 92 if self.stack :
93 - pos = "[%s:%s]: " % (self.stack[-1].lineno, 93 + try :
94 - self.stack[-1].col_offset) 94 + pos = "[%s:%s]: " % (self.stack[-1].lineno,
95 + self.stack[-1].col_offset)
96 + except :
97 + pos = ""
95 else : 98 else :
96 pos = "" 99 pos = ""
97 raise error(pos+message) 100 raise error(pos+message)
......
...@@ -297,8 +297,13 @@ def main (args=sys.argv[1:], src=None) : ...@@ -297,8 +297,13 @@ def main (args=sys.argv[1:], src=None) :
297 if options.check : 297 if options.check :
298 lineno, trace = Checker(net).run() 298 lineno, trace = Checker(net).run()
299 if options.simul : 299 if options.simul :
300 + engine = "dot"
301 + for eng in gv_engines :
302 + if getattr(options, "gv%s" % eng) :
303 + engine = eng
304 + break
300 try : 305 try :
301 - simul = Simulator(node, net, draw(net, None), options.port) 306 + simul = Simulator(node, net, draw(net, None, engine), options.port)
302 except : 307 except :
303 bug() 308 bug()
304 simul.start() 309 simul.start()
......