Petrex.PNML (petrex v1.0.0)

Copy Markdown View Source

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

Reads a PT-net PNML document.

Encodes a net as a PNML document.

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.

Functions

decode(xml)

@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]

encode(net, opts \\ [])

@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 the name label, or the original identifier when there is none; labels need not be unique, as PNML allows. :ids writes 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

ids(net)

@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"}