PNML (ISO/IEC 15909-2) interchange for place/transition nets.
encode/2 produces a PT-net document with places, transitions, arc
weights, initial markings (token counts) and names. Identifiers are mapped
to valid PNML ids and the originals preserved as described in the
"PNML identifiers" section of the design notes; ids/1 returns that
mapping.
Inhibitor arcs are written the way TINA reads and writes them: an arc from
the place to the transition carrying <type value="inhibitor"/> (see the
design notes). Elements the decoder did not interpret, including graphics,
are carried on the extra field of each element and written back.
Summary
Functions
@spec decode(String.t()) :: {:ok, Petrex.Net.t(), [term()]} | {:error, term()}
Reads a PT-net PNML document.
Returns {:ok, net, warnings} or {:error, reason}. Warnings report what
the document required the decoder to decide: {:merged_parallel_arcs, from, to, weight} when arcs between the same pair were summed,
{:name_not_unique, name} when a repeated <name> could not serve as an
identifier, and {:atom_not_found, text} when an identifier recorded as
an atom does not exist in the running system and was kept as a string.
Identifiers come from the Petrex tool-specific element, then from <name>
when it is usable and unique, then from the PNML id. Elements the decoder
does not interpret are kept on extra and written back by encode/2.
iex> {:ok, xml} =
...> Petrex.new()
...> |> Petrex.place(:p, tokens: 2)
...> |> Petrex.place(:q)
...> |> Petrex.transition(:t, in: [p: 2], out: [:q])
...> |> Petrex.PNML.encode()
iex> {:ok, net, []} = Petrex.PNML.decode(xml)
iex> Petrex.Analysis.enabled(net)
[:t]
@spec encode(Petrex.Net.t(), keyword()) :: {:ok, String.t()} | {:error, {:invalid_net, [Petrex.Net.error()]}}
Encodes a net as a PNML document.
Options:
:names— what each place's and transition's<name>holds.:labels(default) writes thenamelabel, or the original identifier when there is none; labels need not be unique, as PNML allows.:idswrites the element's PNML id, which is unique; this is intended for tools that identify nodes by name (see "Known tool quirks" in the design notes).
Examples
iex> {:ok, xml} =
...> Petrex.new()
...> |> Petrex.place(:"my place", tokens: 2)
...> |> Petrex.PNML.encode()
iex> xml =~ ~s(<place id="my_place"><name><text>my place</text></name>)
true
@spec ids(Petrex.Net.t()) :: %{ required(Petrex.Place.id() | Petrex.Transition.id()) => String.t() }
Returns the PNML id assigned to every place and transition of a valid net,
as a map from Petrex identifier to id string. The assignment is the one
encode/2 uses and depends only on the net's structure.
iex> Petrex.new()
...> |> Petrex.place("3rd")
...> |> Petrex.place(:"3rd")
...> |> Petrex.PNML.ids()
%{"3rd" => "_3rd", :"3rd" => "_3rd-2"}