2 Classes for the implementation of the Control Flow Structure Syntax. 4 @see: https://github.com/lhcb/scheduling-event-model/tree/master/controlflow_syntax 6 from __future__
import print_function
11 Basic entry in the control flow graph. 43 return (repr(self) == repr(other))
46 """Return a unique identifier for this object. 48 As we use the `repr` of this object to check for equality, we use it 49 here to define uniqueness. 52 return hash((repr(self), ))
56 Allow use of an expression as an algorihtm/sequence in a Gaudi job 59 Convert the expression in nested sequencers and return the full name of 62 if not hasattr(self,
'_fullname'):
70 Class used to identify a note without sub-nodes. 75 class ControlFlowBool(ControlFlowLeaf):
80 return rhs
if self.
value else self
83 return self
if self.
value else rhs
86 return CFFalse
if self.
value else CFTrue
89 return 'CFTrue' if self.
value else 'CFFalse' 99 Represent order of execution of nodes. 107 return "(%r >> %r)" % (self.
lhs, self.
rhs)
116 And operation between control flow nodes. 124 return "(%r & %r)" % (self.
lhs, self.
rhs)
133 Or operation between control flow nodes. 141 return "(%r | %r)" % (self.
lhs, self.
rhs)
150 Invert logic (negation) of a control flow node. 157 return "~%r" % self.
item 165 Treat a control flow node as always successful, equivalent to (a | ~ a). 172 return "ignore(%r)" % self.
item 183 return "par(%r)" % self.
item 194 return "seq(%r)" % self.
item 206 return "line(%r, %r)" % (self.
name, self.
item)
209 self.
item.visitNode(visitor)
218 print(
"%sEntering %s" % (self.
depths *
" ",
type(visitee)))
219 if isinstance(visitee, ControlFlowLeaf):
220 print(
"%s Algorithm name: %s" % (
" " * self.
depths, visitee))
223 print(
"%sLeaving %s" % (self.
depths *
" ",
type(visitee)))
247 if visitee
not in self.
ids:
249 dot_id = self.
ids[visitee] =
'T%s' % self.
number 250 dot_id = self.
ids[visitee]
253 if isinstance(visitee, ControlFlowLeaf):
254 entry =
'%s [label="%s", shape=box]' % (dot_id, visitee.name())
255 elif isinstance(visitee, OrNode):
256 entry =
'%s [label="OR", shape=invhouse]' % dot_id
257 elif isinstance(visitee, AndNode):
258 entry =
'%s [label="AND", shape=invhouse]' % dot_id
259 elif isinstance(visitee, OrderedNode):
260 entry =
'%s [label=">>", shape=point]' % dot_id
261 elif isinstance(visitee, InvertNode):
262 entry =
'%s [label="NOT", shape=circle, color=red]' % dot_id
263 elif isinstance(visitee, par):
264 entry =
'%s [label="PAR", shape=circle]' % dot_id
265 elif isinstance(visitee, seq):
266 entry =
'%s [label="SEQ", shape=circle]' % dot_id
268 entry =
'%s [label="%s", shape=circle]' % (dot_id,
270 self.
nodes.append(entry)
271 if len(self.
stack) != 0:
275 mother = self.
stack[-1][1]
276 edge =
"%s->%s" % (dot_id, mother)
277 self.
edges.append(edge)
278 self.
stack.append((visitee, dot_id))
285 If AND nodes are inside AND nodes, the graph could be simplified 286 to not contain those (same true for OR and ordered) 289 if len(self.
stack) != 0:
290 mother = self.
stack[-1][1]
291 for entry
in self.
stack[::-1]:
292 if type(entry[0]) != thetype:
300 Check whether this node is actually needed 302 if len(self.
stack) != 0:
303 return not isinstance(visitee,
type(self.
stack[-1][0]))
316 """ % (
"\n".join(self.
nodes),
"\n".join(self.
edges))
318 with open(filename,
"w")
as outfile:
319 outfile.write(output)
323 Algorithm = _TestAlgorithm
332 sequence =
seq(b >> a >> f)
333 expression = sequence | ~c &
par(d & e & g)
334 a = (expression == expression)
335 aLine =
line(
"MyTriggerPath", expression)
338 print(
"\nPrinting trigger line:")
340 print(
"\nPrinting expression:")
342 print(
"\nTraversing through expression:\n")
343 expression.visitNode(visitor)
344 expression.visitNode(visitor2)
345 visitor2.write(
"out.dot")
def _visitSubNodes(self, visitor)
def makeSequences(expression)
def __init__(self, value)
def __init__(self, name, item)
def collapse_identical_ancestors(self, thetype)
def _visitSubNodes(self, visitor)
def __rshift__(self, rhs)
def __init__(self, lhs, rhs)
def _visitSubNodes(self, visitor)
def write(self, filename)
def visitNode(self, visitor)
def _visitSubNodes(self, visitor)
def _visitSubNodes(self, visitor)
def __init__(self, lhs, rhs)
def _visitSubNodes(self, visitor)
def is_needed(self, visitee)
Alias for backward compatibility.
def __init__(self, lhs, rhs)
def _visitSubNodes(self, visitor)
def _visitSubNodes(self, visitor)
def _visitSubNodes(self, visitor)