Skip to content

Instantly share code, notes, and snippets.

@tmori3y2
Created May 28, 2017 00:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmori3y2/2278e63e2834eabb69fa361fe3fce41e to your computer and use it in GitHub Desktop.
Save tmori3y2/2278e63e2834eabb69fa361fe3fce41e to your computer and use it in GitHub Desktop.
Petri Net Class
# Petri Net graph module.
# References
# Petri Nets World: http://www.informatik.uni-hamburg.de/TGI/PetriNets
# (Tutorilas): http://www.informatik.uni-hamburg.de/TGI/PetriNets/introductions/
# pnml.org: http://www.pnml.org
# (Schema): http://www.pnml.org/version-2009/version-2009.php
# import Digraph from graphviz pakage.
# http://graphviz.readthedocs.io/en/latest/manual.html
from graphviz import Digraph
from xLabelNode import XLabeledNode
# XPath: /pnml/net/page/place
class PetriNetPlace(XLabeledNode):
# class global properties.
shape = 'circle'
style = 'solid, filled'
height = '1'
width = '1'
@classmethod
def change_circlestyles(cls, *, style='solid, filled', size='1'):
cls.style = style
cls.height = size
cls.width = size
# constructor
def __init__(self,
identifier, # node name and subgraph name without prefix 'cluster_'.
xlabel, # subgraph label (external label of node).
*,
xlabelloc = 'b', # overwrites subgraph label location.
xlabeljust = 'c', # overwrites subgraph label justification.
xbgcolor = 'white', # overwrites subgraph bgcolor.
color = 'black', # overwrites node color.
fillcolor = 'white', # overwrites node fillcolor.
label = ''): # overwirutes node label.
super().__init__(identifier, xlabel,
xlabelloc=xlabelloc, xlabeljust=xlabeljust, xbgcolor=xbgcolor,
fixsize=True, color=color, fillcolor=fillcolor, label=label)
# XPath: /pnml/net/page/transition
class PetriNetTransition(XLabeledNode):
# class global properties.
shape = 'box'
height = '1'
width = '0.1'
# constructor
def __init__(self,
identifier, # node name and subgraph name without prefix 'cluster_'.
xlabel, # subgraph label (external label of node).
*,
xlabelloc = 'b', # overwrites subgraph label location.
xlabeljust = 'c', # overwrites subgraph label justification.
xbgcolor = 'white', # overwrites subgraph bgcolor.
color = 'black', # overwrites node color.
fillcolor = 'white', # overwrites node fillcolor.
label = ''): # overwirutes node label.
super().__init__(identifier, xlabel,
xlabelloc=xlabelloc, xlabeljust=xlabeljust, xbgcolor=xbgcolor,
fixsize=True, color=color, fillcolor=fillcolor, label=label)
# Petri Net subgraph class.
class PetriNetSubGraph(object):
# constructor
def __init__(self,
identifier, # subgraph name without prefix 'cluster_'.
label, # subgraph label.
*,
labelloc = 'b', # overwrites subgraph label location.
labeljust = 'c', # overwrites subgraph label justification.
penwidth = '0', # overwrites graph penwidth.
bgcolor = 'white'): # overwrites graph bgcolor.
self.xgraph = Digraph('cluster_' + identifier)
self.xgraph.attr('graph', style='filled',
label=label, labelloc=labelloc, labeljust=labeljust,
penwidth=penwidth, bgcolor=bgcolor)
def register_xnode(self, *children):
for child in children:
self.xgraph.subgraph(child.xnode)
def register_subgraph(self, *children):
for child in children:
self.xgraph.subgraph(child.xgraph)
def arc(self,
source, # tail of edge.
target, # head of edge.
*,
label='1'): #
self.xgraph.edge(source.identifier, target.identifier, label)
def layout(self, source, target, *, constraint='false'):
self.xgraph.edge(source.identifier, target.identifier, style='invis', constraint=constraint)
# Petri Net root class.
# XPath: /pnml
class PetriNet(PetriNetSubGraph):
# constructor
def __init__(self, identifier, label, *,
labelloc = 't', # overwrites Petri Net label location.
labeljust = 'l', # overwrites Petri Net label justification.
filename = '', # overwrites dot file name.
ext = 'dot', # overwrites dot file extension.
output = 'png', # overwrites graphical output format.
ranksep = '0.5', # overwrites rank separation.
nodesep = '0.5', # overwrites node separation.
penwidth = '0', # overwrites graph penwidth.
bgcolor = 'white'): # overwrites graph bgcolor.
if filename == '':
filename = identifier
self.xgraph = Digraph(identifier)
self.xgraph.filename = filename + '.' + ext
self.xgraph.format = output
self.xgraph.attr('graph', rankdir='LR', style='filled',
label=label, labelloc=labelloc, labeljust=labeljust,
nodesep=nodesep, ranksep=ranksep,
penwidth=penwidth, bgcolor=bgcolor)
def dump(self):
print(self.xgraph)
def save(self):
self.xgraph.save()
def render(self, *, view=False):
self.xgraph.render(view=view)
# Petri Net net class.
# XPath: /pnml/net
class PetriNetNet(PetriNetSubGraph):
# constructor
def __init__(self,
identifier, # subgraph name without prefix 'cluster_'.
label, # subgraph label.
*,
labelloc = 'b', # overwrites subgraph label location.
labeljust = 'c', # overwrites subgraph label justification.
penwidth = '0', # overwrites graph penwidth.
bgcolor = 'white'): # overwrites graph bgcolor.
super().__init__(identifier, label,
labelloc=labelloc, labeljust=labeljust,
penwidth=penwidth, bgcolor=bgcolor)
# Petri Net page class.
# XPath: /pnml/net/page
class PetriNetPage(PetriNetSubGraph):
# constructor
def __init__(self,
identifier, # subgraph name without prefix 'cluster_'.
label, # subgraph label.
*,
labelloc = 'b', # overwrites subgraph label location.
labeljust = 'c', # overwrites subgraph label justification.
penwidth = '0', # overwrites graph penwidth.
bgcolor = 'white'): # overwrites graph bgcolor.
super().__init__(identifier, label,
labelloc=labelloc, labeljust=labeljust,
penwidth=penwidth, bgcolor=bgcolor)
def petrinet_test():
fig = PetriNet('PetriNet', 'PetriNet Sample', filename='PetriNetSample')
net = PetriNetNet('net', 'PCB Etching Process')
pageTop = PetriNetPage('pageTop', 'PCB Etching Phase', penwidth='1')
placeCu = PetriNetPlace('placeCu', 'Copper Layer', xlabelloc='t', label="1")
placeFeCl3 = PetriNetPlace('placeFeCl3', 'Iron(III) chloride', label='2')
placeCuCl2 = PetriNetPlace('placeCuCl2', 'Copper(II) chloride', xlabelloc='t')
placeFeCl2 = PetriNetPlace('placeFeCl2', 'Iron(II) chloride')
transReaction = PetriNetTransition('transitionReaction', 'Etching Reaction')
pageTop.register_xnode(placeCu, placeFeCl3, placeCuCl2, placeFeCl2, transReaction)
pageTop.layout(placeCu, placeFeCl3)
pageTop.layout(placeCuCl2, placeFeCl2)
pageTop.layout(placeCu, placeCuCl2, constraint='true')
pageTop.layout(placeFeCl3, placeFeCl2, constraint='true')
pageTop.arc(placeCu, transReaction)
pageTop.arc(placeFeCl3, transReaction, label='2')
pageTop.arc(transReaction, placeCuCl2)
pageTop.arc(transReaction, placeFeCl2, label='2')
net.register_subgraph(pageTop)
fig.register_subgraph(net)
fig.dump()
fig.save()
fig.render(view=True)
if __name__ == '__main__':
petrinet_test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment