Source code for pm4py.objects.petri.exporter.variants.pnml

'''
    This file is part of PM4Py (More Info: https://pm4py.fit.fraunhofer.de).

    PM4Py is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    PM4Py is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PM4Py.  If not, see <https://www.gnu.org/licenses/>.
'''
import uuid

from lxml import etree

from pm4py.objects.petri.obj import Marking
from pm4py.objects.petri.obj import PetriNet
from pm4py.util import constants


[docs]def export_petri_tree(petrinet, marking, final_marking=None, export_prom5=False, parameters=None): """ Export a Petrinet to a XML tree Parameters ---------- petrinet: :class:`pm4py.entities.petri.petrinet.PetriNet` Petri net marking: :class:`pm4py.entities.petri.petrinet.Marking` Marking final_marking: :class:`pm4py.entities.petri.petrinet.Marking` Final marking (optional) export_prom5 Enables exporting PNML files in a format that is ProM5-friendly parameters Other parameters of the algorithm Returns ---------- tree XML tree """ if parameters is None: parameters = {} if final_marking is None: final_marking = Marking() root = etree.Element("pnml") net = etree.SubElement(root, "net") net.set("id", petrinet.name) netname = etree.SubElement(net, "name") netnametext = etree.SubElement(netname, "text") netnametext.text = petrinet.name net.set("type", "http://www.pnml.org/version-2009/grammar/pnmlcoremodel") if export_prom5 is True: page = net else: page = etree.SubElement(net, "page") page.set("id", "n0") places_map = {} for place in petrinet.places: places_map[place] = place.name pl = etree.SubElement(page, "place") pl.set("id", place.name) pl_name = etree.SubElement(pl, "name") pl_name_text = etree.SubElement(pl_name, "text") pl_name_text.text = place.properties[ constants.PLACE_NAME_TAG] if constants.PLACE_NAME_TAG in place.properties else place.name if place in marking: pl_initial_marking = etree.SubElement(pl, "initialMarking") pl_initial_marking_text = etree.SubElement(pl_initial_marking, "text") pl_initial_marking_text.text = str(marking[place]) if constants.LAYOUT_INFORMATION_PETRI in place.properties: graphics = etree.SubElement(pl, "graphics") position = etree.SubElement(graphics, "position") position.set("x", str(place.properties[constants.LAYOUT_INFORMATION_PETRI][0][0])) position.set("y", str(place.properties[constants.LAYOUT_INFORMATION_PETRI][0][1])) dimension = etree.SubElement(graphics, "dimension") dimension.set("x", str(place.properties[constants.LAYOUT_INFORMATION_PETRI][1][0])) dimension.set("y", str(place.properties[constants.LAYOUT_INFORMATION_PETRI][1][1])) transitions_map = {} for transition in petrinet.transitions: transitions_map[transition] = transition.name trans = etree.SubElement(page, "transition") trans.set("id", transition.name) trans_name = etree.SubElement(trans, "name") trans_text = etree.SubElement(trans_name, "text") if constants.LAYOUT_INFORMATION_PETRI in transition.properties: graphics = etree.SubElement(trans, "graphics") position = etree.SubElement(graphics, "position") position.set("x", str(transition.properties[constants.LAYOUT_INFORMATION_PETRI][0][0])) position.set("y", str(transition.properties[constants.LAYOUT_INFORMATION_PETRI][0][1])) dimension = etree.SubElement(graphics, "dimension") dimension.set("x", str(transition.properties[constants.LAYOUT_INFORMATION_PETRI][1][0])) dimension.set("y", str(transition.properties[constants.LAYOUT_INFORMATION_PETRI][1][1])) if constants.STOCHASTIC_DISTRIBUTION in transition.properties: random_variable = transition.properties[constants.STOCHASTIC_DISTRIBUTION] stochastic_information = etree.SubElement(trans, "toolspecific") stochastic_information.set("tool", "StochasticPetriNet") stochastic_information.set("version", "0.2") distribution_type = etree.SubElement(stochastic_information, "property") distribution_type.set("key", "distributionType") distribution_type.text = random_variable.get_distribution_type() if not random_variable.get_distribution_type() == "IMMEDIATE": distribution_parameters = etree.SubElement(stochastic_information, "property") distribution_parameters.set("key", "distributionParameters") distribution_parameters.text = random_variable.get_distribution_parameters() distribution_priority = etree.SubElement(stochastic_information, "property") distribution_priority.set("key", "priority") distribution_priority.text = str(random_variable.get_priority()) distribution_invisible = etree.SubElement(stochastic_information, "property") distribution_invisible.set("key", "invisible") distribution_invisible.text = str(True if transition.label is None else False).lower() distribution_weight = etree.SubElement(stochastic_information, "property") distribution_weight.set("key", "weight") distribution_weight.text = str(random_variable.get_weight()) if transition.label is not None: trans_text.text = transition.label else: trans_text.text = transition.name tool_specific = etree.SubElement(trans, "toolspecific") tool_specific.set("tool", "ProM") tool_specific.set("version", "6.4") tool_specific.set("activity", "$invisible$") tool_specific.set("localNodeID", str(uuid.uuid4())) if export_prom5 is True: if transition.label is not None: prom5_specific = etree.SubElement(trans, "toolspecific") prom5_specific.set("tool", "ProM") prom5_specific.set("version", "5.2") log_event_prom5 = etree.SubElement(prom5_specific, "logevent") event_name = transition.label.split("+")[0] event_transition = transition.label.split("+")[1] if len( transition.label.split("+")) > 1 else "complete" log_event_prom5_name = etree.SubElement(log_event_prom5, "name") log_event_prom5_name.text = event_name log_event_prom5_type = etree.SubElement(log_event_prom5, "type") log_event_prom5_type.text = event_transition for arc in petrinet.arcs: arc_el = etree.SubElement(page, "arc") arc_el.set("id", str(hash(arc))) if type(arc.source) is PetriNet.Place: arc_el.set("source", str(places_map[arc.source])) arc_el.set("target", str(transitions_map[arc.target])) else: arc_el.set("source", str(transitions_map[arc.source])) arc_el.set("target", str(places_map[arc.target])) if arc.weight > 1: inscription = etree.SubElement(arc_el, "inscription") arc_weight = etree.SubElement(inscription, "text") arc_weight.text = str(arc.weight) if len(final_marking) > 0: finalmarkings = etree.SubElement(net, "finalmarkings") marking = etree.SubElement(finalmarkings, "marking") for place in final_marking: placem = etree.SubElement(marking, "place") placem.set("idref", place.name) placem_text = etree.SubElement(placem, "text") placem_text.text = str(final_marking[place]) tree = etree.ElementTree(root) return tree
[docs]def export_petri_as_string(petrinet, marking, final_marking=None, export_prom5=False, parameters=None): """ Parameters ---------- petrinet: :class:`pm4py.entities.petri.petrinet.PetriNet` Petri net marking: :class:`pm4py.entities.petri.petrinet.Marking` Marking final_marking: :class:`pm4py.entities.petri.petrinet.Marking` Final marking (optional) export_prom5 Enables exporting PNML files in a format that is ProM5-friendly Returns ---------- string Petri net as string """ if parameters is None: parameters = {} # gets the XML tree tree = export_petri_tree(petrinet, marking, final_marking=final_marking, export_prom5=export_prom5) # removing default decoding (return binary string as in other parts of the application) return etree.tostring(tree, xml_declaration=True, encoding=constants.DEFAULT_ENCODING)
[docs]def export_net(petrinet, marking, output_filename, final_marking=None, export_prom5=False, parameters=None): """ Export a Petrinet to a PNML file Parameters ---------- petrinet: :class:`pm4py.entities.petri.petrinet.PetriNet` Petri net marking: :class:`pm4py.entities.petri.petrinet.Marking` Marking final_marking: :class:`pm4py.entities.petri.petrinet.Marking` Final marking (optional) output_filename: Absolute output file name for saving the pnml file export_prom5 Enables exporting PNML files in a format that is ProM5-friendly """ if parameters is None: parameters = {} # gets the XML tree tree = export_petri_tree(petrinet, marking, final_marking=final_marking, export_prom5=export_prom5) # write the tree to a file tree.write(output_filename, pretty_print=True, xml_declaration=True, encoding=constants.DEFAULT_ENCODING)