Source code for pm4py.objects.petri_net.utils.projection

'''
    PM4Py – A Process Mining Library for Python
Copyright (C) 2024 Process Intelligence Solutions UG (haftungsbeschränkt)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or any later version.

This program 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 Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see this software project's root or 
visit <https://www.gnu.org/licenses/>.

Website: https://processintelligence.solutions
Contact: info@processintelligence.solutions
'''
import numpy as np

from pm4py.objects.petri_net.obj import PetriNet, Marking
from pm4py.objects.petri_net.utils.petri_utils import add_arc_from_to


[docs] def project_net_on_place(place): """ Project a Petri net on a place Parameters ------------- place Place Returns ------------- net (Place) net im Empty initial marking fm Empty final marking """ place_net = PetriNet() place_net_im = Marking() place_net_fm = Marking() input_trans = [arc.source for arc in place.in_arcs] output_trans = [arc.target for arc in place.out_arcs] if len(input_trans) == 0 or len(output_trans) == 0: raise Exception("place projection not available on source/sink places") input_trans_visible = [trans for trans in input_trans if trans.label] output_trans_visible = [trans for trans in output_trans if trans.label] if not len(input_trans) == len(input_trans_visible) or not len( output_trans ) == len(output_trans_visible): raise Exception( "place projection not available on places that have invisible transitions as preset/postset" ) new_place = PetriNet.Place(place.name) place_net.places.add(new_place) for trans in input_trans: new_trans = PetriNet.Transition(trans.name, trans.label) place_net.transitions.add(new_trans) add_arc_from_to(new_trans, new_place, place_net) for trans in output_trans: new_trans = PetriNet.Transition(trans.name, trans.label) place_net.transitions.add(new_trans) add_arc_from_to(new_place, new_trans, place_net) return place_net, place_net_im, place_net_fm
[docs] def project_net_on_matrix(net, activities, parameters=None): """ Project a Petri net with: - only visible transitions - where each place preset/postset is disjoint - with unique visible transitions on a numeric matrix Parameters -------------- net Petri net activities List of activities parameters Possible parameters of the algorithm """ inv_trans_map = {} for trans in net.transitions: if not trans.label: raise Exception( "the project_net_on_matrix works only with Petri net that do not contain invisible transitions" ) if trans.label in inv_trans_map: raise Exception( "the project_net_on_matrix works only with Petri net that contains unique visible transitions" ) inv_trans_map[trans.label] = trans places_matrix = [] for place in net.places: place_repr = [0] * len(activities) input_trans_labels = set([arc.source.label for arc in place.in_arcs]) output_trans_labels = set([arc.target.label for arc in place.out_arcs]) if len(input_trans_labels.intersection(output_trans_labels)) > 0: raise Exception( "place has a transition that belongs to both preset and postset" ) for arc in place.in_arcs: input_trans_label = arc.source.label input_arc_weight = arc.weight if input_trans_label in activities: place_repr[activities.index(input_trans_label)] = ( -input_arc_weight ) for arc in place.out_arcs: output_trans_label = arc.target.label output_arc_weight = arc.weight if output_trans_label in activities: place_repr[activities.index(output_trans_label)] = ( output_arc_weight ) if min(place_repr) < 0 < max(place_repr): places_matrix.append(place_repr) if len(places_matrix) == 0: raise Exception("no places numeric representation could be found") places_matrix = np.transpose(np.asmatrix(places_matrix)) return places_matrix