CPN Tools does not natively support inhibitor arcs. It is however possible to simulate the behavior of inhibitor arcs.
This can be done in at least two different ways. It can be done using lists. This way is a bit more cumbersome, but can be made to work in all cases. Simulation of inhibitor arcs can also be done using anti-places. This is a lot easier, but only works if the number of tokens is limited on the place you want to attach the inhibitor arc to.
The net models a simple producer/consumer.
The producer (not modeled explicitly) sends packets onto the network.
If the consumer is ready, it can receive the packet, process it and again be ready (the blue cycle). If no packet is present on the network, the consumer can go to sleep, and wake up again (the brown cycle).
The problem is the part “if no packet is present on the network”. This is modeled using an inhibitor arc (the fat red one). Alas CPN Tools do not support this…
One way to overcome the missing inhibitor arcs is by using lists.
Basically, one models inhibitor arcs by changing the type from e.g. `T' to `list T', change all incoming arcs (in to the place) to add to the list, and all outgoing arcs must then remove a random element from the list (and send the list back to the place). Your inhibitor arc is then a double-arc, which removes (and again adds) the empty list.
When this is done for the above example, the result is
Incoming arcs are treated just like I would for a stack.
Outgoing arcs are a bit more complicated than for queues or stacks, because I have to pick a random element.
Now we have two problems: the “p” I used originally is no longer bound from the place and the newly introduced “rest” is not bound either. I choose to bind both in the guard of the transition.
Finally I have to put a reasonable inscription in the inhibitor arc.
Now the transition connected to the inhibitor-arc can only fire if there is an empty list on the involved place, which is exactly the desired behavior of an inhibitor arc.
The list-based inhibitor arc-solution is quire complex, and in some cases not needed. If the number of tokens on the involved place is bounded one can add inhibitor arcs easier by adding an anti-place and letting the inhibitor arc be a double arc, which removes (and adds) all tokens from the anti-place.
In the above example, I can see that the network can at most have 4 tokens, so this method can be used here. When this is done, I obtain:
First I have found an arbitrary bound for the involved place, in this case 5. (I could have chosen 4, 7, or 1000000 as bound as well).
I have then added an anti-place, to turn the place into a limit place, with the selected limit, as described here.
Now it is easy to add the inhibitor arc:
If the place was bounded before, adding the anti-place has not changed its behavior, and this construction is correct.
This solution is more general than the one using anti-places (as it works for unbounded nets) and better for timed models than the one using lists as it represents tokens individually. The basic idea is to use a separate place always keeping count of the number of tokens on the place. In a sense, this can be thought of as a anti-place where, instead of removing, we add tokens when adding tokens to the original place.
Using the same example, we get
I have added a new place Network counter of type INT with the initial marking 0. Whenever I add a token to network, I increase the value of the counter and whenever I consume a token, I decrement the value. The inhibitor arc is simply a double arc reading the value 0.
The models described in this document can be downloaded: