Thanks to class `Expression`

, one may execute arbitrary Python
expressions, however, it is often necessary to import modules or use
existing objects (in particular functions), which is not possible from
within expressions.

To address this need, every instance of `PetriNet`

is equipped with an
attribute `globalise`

that holds a dict-like object used as the context
for evaluating the expressions embedded in the net and its components.
Consider for example, a net in which we use a guard that needs
constant `math.pi`

:

>>> from snakes.nets import * >>> net = PetriNet("my net") >>> trans = Transition("t", Expression("math.pi > 3")) >>> net.add_transition(trans) >>> net.add_place(Place("p", [dot])) >>> net.add_input("p", "t", Value(dot)) >>> trans.modes() Traceback (most recent call last): ... NameError: name 'math' is not defined

(Note that we add a place and an input arc because disconnected
transitions in SNAKES have no modes at all so that `trans.modes()`

would return `[]`

without even trying to evaluate the guard.) Because
module `math`

is not imported, we have a `NameError`

. But importing
`math`

will not solve the problem because we do it in the context of
your Python shell but not in that of the net:

>>> import math >>> trans.modes() Traceback (most recent call last): ... NameError: name 'math' is not defined

The solution is to execute statement `import math`

in the context of
`globals`

as follows:

>>> net.globals.declare("import math") >>> trans.modes() [Substitution()]

Method `net.globals.declare`

expects a Python statement that is
`exec`

-ed in the context of the dict-like `net.globals`

. So our
`import math`

now has an effect that is remembered for all the
evaluations that will take place within the net. Because `net.globals`

is a dict-like structure, it is also possible to assign keys directly
to objects.

>>> bis = Transition("b", Expression("math.pi > THREE")) >>> net.add_transition(bis) >>> net.add_input("p", "b", Value(dot)) >>> bis.modes() Traceback (most recent call last): ... NameError: name 'THREE' is not defined >>> net.globals["THREE"] = 3 >>> bis.modes() [Substitution()]