Franck Pommereau

added plugin modules

1 +"""A plugin to record for each not to which modules it belongs.
2 +
3 +Modules are arbitrary values, each `PetriNet`, `Place` or transition
4 +is attached a set of modules. These modules can be given at
5 +construction time, as a single value or a collection of values.
6 +Moreover, when nodes are attached to a net, they inherit the modules
7 +from this net. When nodes are merged, their sets of modules is added
8 +to build the set of modules of the new node.
9 +
10 +Internally, modules are stored in a label called `"modules"` (see
11 +plugin `snakes.plugins.labels`).
12 +
13 +>>> import snakes.plugins
14 +>>> snakes.plugins.load(["ops", "modules"], "snakes.nets", "snk")
15 +<module 'snk' ...>
16 +>>> from snk import *
17 +>>> n1 = PetriNet("n1", modules="hello")
18 +>>> n1.add_place(Place("p"))
19 +>>> n1.place("p").modules()
20 +set(['hello'])
21 +>>> n1.add_place(Place("q"))
22 +>>> n2 = PetriNet("n2", modules="world")
23 +>>> n2.add_place(Place("r"))
24 +>>> n2.add_place(Place("s", modules="spam"))
25 +>>> n = n1|n2
26 +>>> list(sorted((p.name, p.modules()) for p in n.place()))
27 +[('[p|]', set(['hello'])),
28 + ('[q|]', set(['hello'])),
29 + ('[|r]', set(['world'])),
30 + ('[|s]', set(['world', 'spam']))]
31 +"""
32 +
33 +from snakes.plugins import plugin, new_instance
34 +from snakes.data import iterate
35 +from snakes.pnml import Tree
36 +
37 +@plugin("snakes.nets",
38 + depends=["snakes.plugins.labels"])
39 +def extend (module) :
40 + class Transition (module.Transition) :
41 + def __init__ (self, name, guard=None, **options) :
42 + mod = set(iterate(options.pop("modules", [])))
43 + module.Transition.__init__(self, name, guard, **options)
44 + self.modules(mod)
45 + def modules (self, modules=None) :
46 + if modules is None :
47 + return self.label("modules")
48 + else :
49 + self.label(modules=set(iterate(modules)))
50 + class Place (module.Place) :
51 + def __init__ (self, name, tokens=[], check=None, **options) :
52 + mod = set(iterate(options.pop("modules", [])))
53 + module.Place.__init__(self, name, tokens, check, **options)
54 + self.modules(mod)
55 + def modules (self, modules=None) :
56 + if modules is None :
57 + return self.label("modules")
58 + else :
59 + self.label(modules=set(iterate(modules)))
60 + class PetriNet (module.PetriNet) :
61 + def __init__ (self, name, **options) :
62 + mod = set(iterate(options.pop("modules", [])))
63 + module.PetriNet.__init__(self, name, **options)
64 + self.modules(mod)
65 + def modules (self, modules=None) :
66 + if modules is None :
67 + return self.label("modules")
68 + else :
69 + self.label(modules=set(iterate(modules)))
70 + def add_place (self, place, **options) :
71 + mod = set(iterate(options.pop("modules", self.modules())))
72 + module.PetriNet.add_place(self, place, **options)
73 + place.modules(place.modules() | mod)
74 + def add_transition (self, trans, **options) :
75 + mod = set(iterate(options.pop("modules", self.modules())))
76 + module.PetriNet.add_transition(self, trans, **options)
77 + trans.modules(trans.modules() | mod)
78 + def merge_places (self, target, sources, **options) :
79 + mod = set(iterate(options.pop("modules", self.modules())))
80 + module.PetriNet.merge_places(self, target, sources, **options)
81 + new = self.place(target)
82 + new.modules(reduce(set.__or__,
83 + (self.place(p).lmodules()
84 + for p in sources),
85 + mod))
86 + def merge_transitions (self, target, sources, **options) :
87 + mod = set(iterate(options.pop("modules", self.modules())))
88 + module.PetriNet.merge_transitions(self, target, sources, **options)
89 + new = self.transition(target)
90 + new.modules(reduce(set.__or__,
91 + (self.place(p).modules()
92 + for p in sources),
93 + mod))
94 + return Transition, Place, PetriNet