I have released the gen_pnet 0.1.1. gen_pnet is a generic OTP behavior for defining and running Petri nets. It is available as a hex.pm package.


  • The callbacks have been separated into a structural part which describes the petri net structure and initial marking and an interface part which describes the net instance’s appearance as an Erlang actor. However, it is still possible to provide all callback functions in a single module by implementing the gen_pnet behavior.
  • The net does not carry an extra user-info term anymore. Now, all state must be encoded in the Petri net marking.
  • The callback enum_consume_map/3 which expected you to enumerate all firing modes enabling a particular transition has been replaced with is_enabled/2 which lets you return true or false to signal whether a transition is enabled in a given firing mode or not.
  • The execution semantics now depend on the lib_combin libary to enumerate possible firing modes.
  • The initial marking given in the Petri net structure can now be superimposed with a marking defined at net instance start time.
  • The get_marking_map/2 function has been replaced with marking/1 which returns the global state of the net.
  • The functions produce/2, consume/2, and add/3 have been removed from the API because they allow the net state to be directly updated from the outside. Outside requests must be handled with the handle_call/3, handle_cast/2, and handle_info/2 interface callbacks now.
  • The execution of the Petri net is now completely sequential. The gen_pnet behavior can, thus, serve as a baseline for parallel implementations to benchmark against.
  • The Petri net structure has been extended with the init_marking/1 callback which allows the definition of the initial marking per place, replacing the init/1 callback which expected you to generate the initial marking as a marking map in a single call.
  • Hot code reload is now possible via the code_change/3 callback which is handed up as is to the underlying gen_server behavior.
  • On stopping the module, additional side effects can be generated by implementing the terminate/2 callback which is handed up as is to the underlying gen_server behavior.
  • Any token to be generated as part of a net state update can now be defined to generate additional side effects by implementing the trigger/2 callback accordingly. Afterwards, the token can be produced normally or can be dropped.
  • The interface has been extended to expose the functionality of the underlying gen_server behavior and also to hide the particularities of Petri net form and semantics to the outside, making the interface as similar to the gen_server behavior as possible. This means that the interface callbacks have been extended to include the handle_call/3, handle_cast/2, and handle_info/2 callbacks.