Exemple #1
0
source = PetriNet.Place("source")
sink = PetriNet.Place("sink")
p_1 = PetriNet.Place("p_1")
# add the places to the Petri Net
net.places.add(source)
net.places.add(sink)
net.places.add(p_1)
# Create transitions
t_1 = PetriNet.Transition("name_1", "label_1")
t_2 = PetriNet.Transition("name_2", "label_2")
# Add the transitions to the Petri Net
net.transitions.add(t_1)
net.transitions.add(t_2)
# Add arcs
from pm4py.objects.petri import utils
utils.add_arc_from_to(source, t_1, net)
utils.add_arc_from_to(t_1, p_1, net)
utils.add_arc_from_to(p_1, t_2, net)
utils.add_arc_from_to(t_2, sink, net)
# Adding tokens
initial_marking = Marking()
initial_marking[source] = 1
final_marking = Marking()
final_marking[sink] = 1
from pm4py.objects.petri.exporter import pnml as pnml_exporter
pnml_exporter.export_net(net,
                         initial_marking,
                         "createdPetriNet1.pnml",
                         final_marking=final_marking)

from pm4py.visualization.petrinet import factory as pn_vis_factory
def construct_cost_aware(pn1, im1, fm1, pn2, im2, fm2, skip, pn1_costs,
                         pn2_costs, sync_costs):
    """
    Constructs the synchronous product net of two given Petri nets.


    :param pn1: Petri net 1
    :param im1: Initial marking of Petri net 1
    :param fm1: Final marking of Petri net 1
    :param pn2: Petri net 2
    :param im2: Initial marking of Petri net 2
    :param fm2: Final marking of Petri net 2
    :param skip: Symbol to be used as skip
    :param pn1_costs: dictionary mapping transitions of pn1 to corresponding costs
    :param pn2_costs: dictionary mapping transitions of pn2 to corresponding costs
    :param pn1_costs: dictionary mapping pairs of transitions in pn1 and pn2 to costs
    :param sync_costs: Costs of sync moves

    Returns
    -------
    :return: Synchronous product net and associated marking labels are of the form (a,>>)
    """
    sync_net = PetriNet('synchronous_product_net of %s and %s' %
                        (pn1.name, pn2.name))
    t1_map, p1_map = __copy_into(pn1, sync_net, True, skip)
    t2_map, p2_map = __copy_into(pn2, sync_net, False, skip)
    costs = dict()

    for t1 in pn1.transitions:
        costs[t1_map[t1]] = pn1_costs[t1]
    for t2 in pn2.transitions:
        costs[t2_map[t2]] = pn2_costs[t2]

    for t1 in pn1.transitions:
        for t2 in pn2.transitions:
            if t1.label == t2.label:
                sync = PetriNet.Transition((t1.name, t2.name),
                                           (t1.label, t2.label))
                sync_net.transitions.add(sync)
                costs[sync] = sync_costs[(t1, t2)]
                for a in t1.in_arcs:
                    add_arc_from_to(p1_map[a.source], sync, sync_net)
                for a in t2.in_arcs:
                    add_arc_from_to(p2_map[a.source], sync, sync_net)
                for a in t1.out_arcs:
                    add_arc_from_to(sync, p1_map[a.target], sync_net)
                for a in t2.out_arcs:
                    add_arc_from_to(sync, p2_map[a.target], sync_net)

    sync_im = Marking()
    sync_fm = Marking()
    for p in im1:
        sync_im[p1_map[p]] = im1[p]
    for p in im2:
        sync_im[p2_map[p]] = im2[p]
    for p in fm1:
        sync_fm[p1_map[p]] = fm1[p]
    for p in fm2:
        sync_fm[p2_map[p]] = fm2[p]

    # update 06/02/2021: to distinguish the sync nets that are output of this method, put a property in the sync net
    sync_net.properties[properties.IS_SYNC_NET] = True

    return sync_net, sync_im, sync_fm, costs
Exemple #3
0
def apply(bpmn_graph, parameters=None):
    """
    Apply conversion from a BPMN graph to a Petri net
    along with an initial and final marking

    Parameters
    -----------
    bpmn_graph
        BPMN graph
    parameters
        Parameters of the algorithm

    Returns
    -----------
    net
        Petri net
    initial_marking
        Initial marking of the Petri net
    final_marking
        Final marking of the Petri net
    elements_correspondence
        Correspondence between meaningful elements of the Petri net (objects) and meaningful elements of the
        BPMN graph (dicts)
    inv_elements_correspondence
        Correspondence between meaningful elements of the BPMN graph (dicts) and meaningful elements of the
        Petri net (objects)
    el_corr_keys_map
        Correspondence between string-ed keys of elements_correspondence with the corresponding elements
    """
    if parameters is None:
        parameters = {}
    enable_reduction = parameters[
        "enable_reduction"] if "enable_reduction" in parameters else False

    del parameters
    net = PetriNet("converted_net")
    nodes = bpmn_graph.get_nodes()
    corresponding_in_nodes = {}
    corresponding_out_nodes = {}
    elements_correspondence = {}
    inv_elements_correspondence = {}
    el_corr_keys_map = {}
    start_event_subprocess = {}
    end_event_subprocess = {}
    sources = []
    targets = []
    # adds nodes
    for node in nodes:
        node_id = node[1]['id'] if 'id' in node[1] else node[0]
        node_name = node[1]['node_name'].replace("\r", " ").replace(
            "\n", " ").strip() if 'node_name' in node[1] else None
        node_type = node[1]['type'].lower() if 'type' in node[1] else ""
        node_process = node[1]['process'] if 'process' in node[1] else None

        if not "type" in node[1]:
            # some problem with the importing of inclusive gateways
            node_type = 'inclusivegateway'

        trans = None
        if "task" in node_type:
            trans = get_transition(node_id, node_name)
            net.transitions.add(trans)
            elements_correspondence[trans] = node[1]
            if not str(node[1]) in inv_elements_correspondence:
                inv_elements_correspondence[str(node[1])] = []
            inv_elements_correspondence[str(node[1])].append(trans)
            input_place = PetriNet.Place('it_' + node_id)
            net.places.add(input_place)
            output_place = PetriNet.Place('ot_' + node_id)
            net.places.add(output_place)
            corresponding_in_nodes[node_id] = [input_place]
            corresponding_out_nodes[node_id] = [output_place]
            utils.add_arc_from_to(input_place, trans, net)
            utils.add_arc_from_to(trans, output_place, net)
        elif "gateway" in node_type:
            if "parallelgateway" in node_type:
                place = PetriNet.Place('pp_' + node_id)
                net.places.add(place)
                corresponding_in_nodes[node_id] = []
                corresponding_out_nodes[node_id] = []
                htrans = get_transition(str(uuid.uuid4()), None)
                net.transitions.add(htrans)
                utils.add_arc_from_to(htrans, place, net)
                for edge in node[1]['incoming']:
                    str(edge)
                    hplace = PetriNet.Place(str(uuid.uuid4()))
                    net.places.add(hplace)
                    utils.add_arc_from_to(hplace, htrans, net)
                    corresponding_in_nodes[node_id].append(hplace)
                htrans = get_transition(str(uuid.uuid4()), None)
                net.transitions.add(htrans)
                utils.add_arc_from_to(place, htrans, net)
                for edge in node[1]['outgoing']:
                    str(edge)
                    hplace = PetriNet.Place(str(uuid.uuid4()))
                    net.places.add(hplace)
                    utils.add_arc_from_to(htrans, hplace, net)
                    corresponding_out_nodes[node_id].append(hplace)
            elif "inclusivegateway" in node_type:
                input_place = PetriNet.Place('i_' + node_id)
                net.places.add(input_place)
                corresponding_in_nodes[node_id] = []
                added_places_input = []
                for edge in node[1]['incoming']:
                    str(edge)
                    hplace = PetriNet.Place(str(uuid.uuid4()))
                    net.places.add(hplace)
                    added_places_input.append(hplace)
                    corresponding_in_nodes[node_id].append(hplace)
                for i in range(1, len(added_places_input) + 1):
                    subsets = findsubsets(set(added_places_input), i)
                    for subset in subsets:
                        htrans = get_transition(str(uuid.uuid4()), None)
                        net.transitions.add(htrans)
                        utils.add_arc_from_to(htrans, input_place, net)
                        for place in subset:
                            utils.add_arc_from_to(place, htrans, net)
                corresponding_out_nodes[node_id] = []
                added_places_output = []
                for edge in node[1]['outgoing']:
                    str(edge)
                    hplace = PetriNet.Place(str(uuid.uuid4()))
                    net.places.add(hplace)
                    added_places_output.append(hplace)
                    corresponding_out_nodes[node_id].append(hplace)
                for i in range(1, len(added_places_output) + 1):
                    subsets = findsubsets(set(added_places_output), i)
                    for subset in subsets:
                        htrans = get_transition(str(uuid.uuid4()), None)
                        net.transitions.add(htrans)
                        utils.add_arc_from_to(input_place, htrans, net)
                        for place in subset:
                            utils.add_arc_from_to(htrans, place, net)
            else:
                input_place = PetriNet.Place('i_' + node_id)
                net.places.add(input_place)
                output_place = PetriNet.Place('o_' + node_id)
                net.places.add(output_place)
                trans = get_transition(node_id, None)
                net.transitions.add(trans)
                utils.add_arc_from_to(input_place, trans, net)
                utils.add_arc_from_to(trans, output_place, net)
                corresponding_in_nodes[node_id] = [input_place] * len(
                    node[1]['incoming'])
                corresponding_out_nodes[node_id] = [output_place] * len(
                    node[1]['outgoing'])
        elif node_type == "startevent":
            source_place_source = PetriNet.Place("sourceplacesource_" +
                                                 str(node_id))
            net.places.add(source_place_source)
            sources.append(source_place_source)
            corresponding_in_nodes[node_id] = [source_place_source]
            if node_process not in corresponding_in_nodes:
                corresponding_in_nodes[node_process] = []
            corresponding_in_nodes[node_process].append(source_place_source)
            start_event_subprocess[node_process] = source_place_source
            if not node_name.lower().startswith("start"):
                trans = get_transition("stt_" + node_id, node_name)
                net.transitions.add(trans)
                source_place_target = PetriNet.Place("stp_" + node_id)
                net.places.add(source_place_target)
                utils.add_arc_from_to(source_place_source, trans, net)
                utils.add_arc_from_to(trans, source_place_target, net)
                corresponding_out_nodes[node_id] = [source_place_target]
            else:
                corresponding_out_nodes[node_id] = [source_place_source]
        elif node_type == "endevent":
            sink_place_target = PetriNet.Place("sinkplacetarget_" +
                                               str(node_id))
            net.places.add(sink_place_target)
            targets.append(sink_place_target)
            corresponding_out_nodes[node_id] = [sink_place_target]
            if node_process not in corresponding_out_nodes:
                corresponding_out_nodes[node_process] = []
            corresponding_out_nodes[node_process].append(sink_place_target)
            end_event_subprocess[node_process] = sink_place_target
            if not node_name.lower().startswith("end"):
                trans = get_transition("ett_" + node_id, node_name)
                net.transitions.add(trans)
                sink_place_source = PetriNet.Place("etp_" + node_id)
                net.places.add(sink_place_source)
                utils.add_arc_from_to(sink_place_source, trans, net)
                utils.add_arc_from_to(trans, sink_place_target, net)
                corresponding_in_nodes[node_id] = [sink_place_source]
            else:
                corresponding_in_nodes[node_id] = [sink_place_target]
        elif "event" in node_type:
            input_place = PetriNet.Place('i_' + node_id)
            net.places.add(input_place)
            output_place = PetriNet.Place('o_' + node_id)
            net.places.add(output_place)
            if not node_id == node_name:
                trans = get_transition(node_id, node_name)
            else:
                trans = get_transition(node_id, None)
            net.transitions.add(trans)
            corresponding_in_nodes[node_id] = [input_place]
            corresponding_out_nodes[node_id] = [output_place]
            utils.add_arc_from_to(input_place, trans, net)
            utils.add_arc_from_to(trans, output_place, net)

    flows = bpmn_graph.get_flows()
    for flow in flows:
        flow_id = flow[2]['id']
        source_ref = flow[2]['sourceRef']
        target_ref = flow[2]['targetRef']
        if source_ref in corresponding_out_nodes and target_ref in corresponding_in_nodes and corresponding_out_nodes[
                source_ref] and corresponding_in_nodes[target_ref]:
            trans = get_transition(flow_id, None)
            net.transitions.add(trans)
            source_arc = utils.add_arc_from_to(
                corresponding_out_nodes[source_ref][0], trans, net)
            target_arc = utils.add_arc_from_to(
                trans, corresponding_in_nodes[target_ref][0], net)
            if len(corresponding_out_nodes[source_ref]) > 1:
                del corresponding_out_nodes[source_ref][0]
            if len(corresponding_in_nodes[target_ref]) > 1:
                del corresponding_in_nodes[target_ref][0]
            elements_correspondence[target_arc] = flow
            if not str(flow) in inv_elements_correspondence:
                inv_elements_correspondence[str(flow[2])] = []
            inv_elements_correspondence[str(flow[2])].append(target_arc)
            inv_elements_correspondence[str(flow[2])].append(source_arc)

    net = remove_unconnected_places(net, sources, targets)

    for el in elements_correspondence:
        el_corr_keys_map[str(el)] = el

    if enable_reduction:
        net = reduce(net)
        #net, initial_marking = remove_places_im_that_go_to_fm_through_hidden(net, initial_marking, final_marking)

    net, initial_marking = get_initial_marking(net)
    net, final_marking = get_final_marking(net)

    return net, initial_marking, final_marking, elements_correspondence, inv_elements_correspondence, el_corr_keys_map
Exemple #4
0
    def transform_net(self, net0, initial_marking0, final_marking0, s_map,
                      avg_time_starts):
        """
        Transform the source Petri net removing the initial and final marking, and connecting
        to each "initial" place a hidden timed transition mimicking the case start

        Parameters
        -------------
        net0
            Initial Petri net provided to the object
        initial_marking0
            Initial marking of the Petri net provided to the object
        final_marking0
            Final marking of the Petri net provided to the object
        s_map
            Stochastic map of transitions (EXPONENTIAL distribution since we assume a Markovian process)
        avg_time_starts
            Average time interlapsed between case starts

        Returns
        -------------
        net
            Petri net that will be simulated
        initial_marking
            Initial marking of the Petri net that will be simulated (empty)
        final_marking
            Final marking of the Petri net that will be simulated (empty)
        s_map
            Stochastic map of transitions enriched by new hidden case-generator transitions
        """
        # copy the Petri net object (assure that we do not change the original Petri net)
        [net1, initial_marking1,
         final_marking1] = copy([net0, initial_marking0, final_marking0])
        # on the copied Petri net, add a sucking transition for the final marking
        for index, place in enumerate(final_marking1):
            suck_transition = PetriNet.Transition(
                "SUCK_TRANSITION" + str(index), None)
            net1.transitions.add(suck_transition)
            add_arc_from_to(place, suck_transition, net1)
            hidden_generator_distr = Exponential()
            hidden_generator_distr.scale = avg_time_starts
            s_map[suck_transition] = hidden_generator_distr
        # on the copied Petri net, remove both the place(s) in the initial marking and
        # the immediate transitions that are connected to it.
        target_places = []
        for place in initial_marking1:
            out_arcs = list(place.out_arcs)
            for target_arc in out_arcs:
                target_trans = target_arc.target
                if len(target_trans.in_arcs) == 1:
                    out_arcs_lev2 = list(target_trans.out_arcs)
                    for arc in out_arcs_lev2:
                        target_place = arc.target
                        target_places.append(target_place)
                    net1 = remove_transition(net1, target_trans)
            net1 = remove_place(net1, place)
        # add hidden case-generation transitions to the model.
        # all places that are left orphan by the previous operation are targeted.
        for index, place in enumerate(target_places):
            hidden_generator_trans = PetriNet.Transition(
                "HIDDEN_GENERATOR_TRANS" + str(index), None)
            net1.transitions.add(hidden_generator_trans)
            add_arc_from_to(hidden_generator_trans, place, net1)
            hidden_generator_distr = Exponential()
            hidden_generator_distr.scale = avg_time_starts
            s_map[hidden_generator_trans] = hidden_generator_distr
        # the simulated Petri net is assumed to start from an empty initial and final marking
        initial_marking = Marking()
        final_marking = Marking()
        return net1, initial_marking, final_marking, s_map
    def setUp(self):
        self.trace_net = PetriNet('trace net of %s' % str(1))

        activities = ['a', 'b', 'c', 'd']
        transitions = []
        artificial_start_transition = PetriNet.Transition('start', 'start')
        artificial_end_transition = PetriNet.Transition('end', 'end')

        place = PetriNet.Place('p_0')
        self.trace_net.places.add(place)
        utils.add_arc_from_to(place, artificial_start_transition,
                              self.trace_net)
        self.trace_net.transitions.add(artificial_start_transition)
        self.trace_net.transitions.add(artificial_end_transition)

        i = 0
        for index, activity in enumerate(activities):
            place = PetriNet.Place('p_' + str(i))
            self.trace_net.places.add(place)
            utils.add_arc_from_to(artificial_start_transition, place,
                                  self.trace_net)
            transition = PetriNet.Transition(
                't_' + activities[index] + '_' + str(index), activities[index])
            self.trace_net.transitions.add(transition)
            utils.add_arc_from_to(place, transition, self.trace_net)
            place = PetriNet.Place('p_' + str(i + 1))
            self.trace_net.places.add(place)
            utils.add_arc_from_to(transition, place, self.trace_net)
            utils.add_arc_from_to(place, artificial_end_transition,
                                  self.trace_net)
            i = i + 1

        place = PetriNet.Place('p_' + str(i))
        self.trace_net.places.add(place)
        utils.add_arc_from_to(artificial_end_transition, place, self.trace_net)

        transition_a = [
            transition for transition in self.trace_net.transitions
            if transition.label == 'a'
        ][0]
        transition_b = [
            transition for transition in self.trace_net.transitions
            if transition.label == 'b'
        ][0]
        transition_c = [
            transition for transition in self.trace_net.transitions
            if transition.label == 'c'
        ][0]
        transition_d = [
            transition for transition in self.trace_net.transitions
            if transition.label == 'd'
        ][0]

        place = PetriNet.Place('p_' + str(i + 1))
        self.trace_net.places.add(place)
        utils.add_arc_from_to(transition_a, place, self.trace_net)
        utils.add_arc_from_to(place, transition_b, self.trace_net)

        place = PetriNet.Place('p_' + str(i + 2))
        self.trace_net.places.add(place)
        utils.add_arc_from_to(transition_a, place, self.trace_net)
        utils.add_arc_from_to(place, transition_c, self.trace_net)

        place = PetriNet.Place('p_' + str(i + 3))
        self.trace_net.places.add(place)
        utils.add_arc_from_to(transition_a, place, self.trace_net)
        utils.add_arc_from_to(place, transition_d, self.trace_net)

        place = PetriNet.Place('p_' + str(i + 4))
        self.trace_net.places.add(place)
        utils.add_arc_from_to(transition_b, place, self.trace_net)
        utils.add_arc_from_to(place, transition_d, self.trace_net)

        place = PetriNet.Place('p_' + str(i + 5))
        self.trace_net.places.add(place)
        utils.add_arc_from_to(transition_c, place, self.trace_net)
        utils.add_arc_from_to(place, transition_d, self.trace_net)

        filename = "partially_ordered_test_log.xes"
        path = os.path.join("/GitHub/pm4py-source/tests/input_data", filename)
        self.log = importer.import_log(path)
 def test_figure415(self):
     net = PetriNet("figure_4_15")
     p_1 = PetriNet.Place("p_1")
     p_2 = PetriNet.Place("p_2")
     p_3 = PetriNet.Place("p_3")
     p_4 = PetriNet.Place("p_4")
     p_5 = PetriNet.Place("p_5")
     p_6 = PetriNet.Place("p_6")
     p_7 = PetriNet.Place("p_7")
     net.places.add(p_1)
     net.places.add(p_2)
     net.places.add(p_3)
     net.places.add(p_4)
     net.places.add(p_5)
     net.places.add(p_6)
     net.places.add(p_7)
     t_1 = PetriNet.Transition("t_1", "t_1")
     t_2 = PetriNet.Transition("t_2", "t_2")
     t_3 = PetriNet.Transition("t_3", "t_3")
     t_4 = PetriNet.Transition("t_4", "t_4")
     t_5 = PetriNet.Transition("t_5", "t_5")
     t_6 = PetriNet.Transition("t_6", "t_6")
     net.transitions.add(t_1)
     net.transitions.add(t_2)
     net.transitions.add(t_3)
     net.transitions.add(t_4)
     net.transitions.add(t_5)
     net.transitions.add(t_6)
     utils.add_arc_from_to(p_1, t_1, net)
     utils.add_arc_from_to(t_1, p_3, net)
     utils.add_arc_from_to(t_1, p_2, net)
     utils.add_arc_from_to(t_1, p_5, net)
     utils.add_arc_from_to(p_5, t_2, net)
     utils.add_arc_from_to(p_5, t_5, net)
     utils.add_arc_from_to(p_3, t_2, net)
     utils.add_arc_from_to(p_3, t_4, net)
     utils.add_arc_from_to(t_2, p_6, net)
     utils.add_arc_from_to(t_2, p_4, net)
     utils.add_arc_from_to(t_5, p_5, net)
     utils.add_arc_from_to(t_5, p_3, net)
     utils.add_arc_from_to(p_2, t_2, net)
     utils.add_arc_from_to(t_3, p_2, net)
     utils.add_arc_from_to(t_3, p_3, net)
     utils.add_arc_from_to(t_3, p_4, net)
     utils.add_arc_from_to(p_6, t_5, net)
     utils.add_arc_from_to(p_6, t_6, net)
     utils.add_arc_from_to(p_6, t_3, net)
     utils.add_arc_from_to(t_4, p_6, net)
     utils.add_arc_from_to(t_4, p_5, net)
     utils.add_arc_from_to(p_4, t_3, net)
     utils.add_arc_from_to(p_4, t_6, net)
     utils.add_arc_from_to(p_4, t_4, net)
     utils.add_arc_from_to(t_6, p_7, net)
     initial_marking = Marking()
     initial_marking[p_1] = 1
     final_marking = Marking()
     final_marking[p_7] = 1
     self.assertTrue(woflan.apply(net, initial_marking, final_marking))
Exemple #7
0
def __add_sink(net, end_activities, label_transition_dict):
    end = PetriNet.Place('end')
    net.places.add(end)
    for e in end_activities:
        add_arc_from_to(label_transition_dict[e], end, net)
    return end
 def test_figure42(self):
     net = PetriNet("figure_4_2")
     p_1 = PetriNet.Place("p_1")
     p_2 = PetriNet.Place("p_2")
     p_3 = PetriNet.Place("p_3")
     p_4 = PetriNet.Place("p_4")
     p_5 = PetriNet.Place("p_5")
     p_6 = PetriNet.Place("p_6")
     p_7 = PetriNet.Place("p_7")
     p_8 = PetriNet.Place("p_8")
     net.places.add(p_1)
     net.places.add(p_2)
     net.places.add(p_3)
     net.places.add(p_4)
     net.places.add(p_5)
     net.places.add(p_6)
     net.places.add(p_7)
     net.places.add(p_8)
     t_1 = PetriNet.Transition("t_1", "t_1")
     t_2 = PetriNet.Transition("t_2", "t_2")
     t_3 = PetriNet.Transition("t_3", "t_3")
     t_4 = PetriNet.Transition("t_4", "t_4")
     t_5 = PetriNet.Transition("t_5", "t_5")
     t_6 = PetriNet.Transition("t_6", "t_6")
     t_7 = PetriNet.Transition("t_7", "t_7")
     t_8 = PetriNet.Transition("t_8", "t_8")
     net.transitions.add(t_1)
     net.transitions.add(t_2)
     net.transitions.add(t_3)
     net.transitions.add(t_4)
     net.transitions.add(t_5)
     net.transitions.add(t_6)
     net.transitions.add(t_7)
     net.transitions.add(t_8)
     utils.add_arc_from_to(p_1, t_1, net)
     utils.add_arc_from_to(t_1, p_6, net)
     utils.add_arc_from_to(t_1, p_4, net)
     utils.add_arc_from_to(p_4, t_4, net)
     utils.add_arc_from_to(p_4, t_5, net)
     utils.add_arc_from_to(t_2, p_6, net)
     utils.add_arc_from_to(t_2, p_4, net)
     utils.add_arc_from_to(t_4, p_3, net)
     utils.add_arc_from_to(t_4, p_5, net)
     utils.add_arc_from_to(t_5, p_7, net)
     utils.add_arc_from_to(t_7, p_4, net)
     utils.add_arc_from_to(p_3, t_2, net)
     utils.add_arc_from_to(p_3, t_3, net)
     utils.add_arc_from_to(p_5, t_2, net)
     utils.add_arc_from_to(p_5, t_3, net)
     utils.add_arc_from_to(p_5, t_4, net)
     utils.add_arc_from_to(p_7, t_6, net)
     utils.add_arc_from_to(p_8, t_7, net)
     utils.add_arc_from_to(p_8, t_8, net)
     utils.add_arc_from_to(t_3, p_2, net)
     utils.add_arc_from_to(p_6, t_6, net)
     utils.add_arc_from_to(t_6, p_5, net)
     utils.add_arc_from_to(t_8, p_8, net)
     initial_marking = Marking()
     initial_marking[p_1] = 1
     final_marking = Marking()
     final_marking[p_2] = 1
     self.assertFalse(
         woflan.apply(net,
                      initial_marking,
                      final_marking,
                      parameters={"print_diagnostics": False}))
Exemple #9
0
def apply_dfg_sa_ea(dfg, start_activities, end_activities, parameters=None):
    """
    Applying Alpha Miner starting from the knowledge of the Directly Follows graph,
    and of the start activities and end activities in the log (possibly inferred from the DFG)

    Parameters
    ------------
    dfg
        Directly-Follows graph
    start_activities
        Start activities
    end_activities
        End activities
    parameters
        Parameters of the algorithm including:
            activity key -> name of the attribute that contains the activity

    Returns
    -------
    net : :class:`pm4py.entities.petri.petrinet.PetriNet`
        A Petri net describing the event log that is provided as an input
    initial marking : :class:`pm4py.models.net.Marking`
        marking object representing the initial marking
    final marking : :class:`pm4py.models.net.Marking`
        marking object representing the final marking, not guaranteed that it is actually reachable!
    """
    if parameters is None:
        parameters = {}

    activity_key = exec_utils.get_param_value(
        Parameters.ACTIVITY_KEY, parameters,
        pm_util.xes_constants.DEFAULT_NAME_KEY)

    if start_activities is None:
        start_activities = dfg_utils.infer_start_activities(dfg)

    if end_activities is None:
        end_activities = dfg_utils.infer_end_activities(dfg)

    labels = set()
    for el in dfg:
        labels.add(el[0])
        labels.add(el[1])
    for a in start_activities:
        labels.add(a)
    for a in end_activities:
        labels.add(a)
    labels = list(labels)

    alpha_abstraction = alpha_classic_abstraction.ClassicAlphaAbstraction(
        start_activities, end_activities, dfg, activity_key=activity_key)
    pairs = list(
        map(
            lambda p: ({p[0]}, {p[1]}),
            filter(
                lambda p: __initial_filter(alpha_abstraction.parallel_relation,
                                           p),
                alpha_abstraction.causal_relation)))
    for i in range(0, len(pairs)):
        t1 = pairs[i]
        for j in range(i, len(pairs)):
            t2 = pairs[j]
            if t1 != t2:
                if t1[0].issubset(t2[0]) or t1[1].issubset(t2[1]):
                    if not (__check_is_unrelated(
                            alpha_abstraction.parallel_relation,
                            alpha_abstraction.causal_relation, t1[0], t2[0])
                            or __check_is_unrelated(
                                alpha_abstraction.parallel_relation,
                                alpha_abstraction.causal_relation, t1[1],
                                t2[1])):
                        new_alpha_pair = (t1[0] | t2[0], t1[1] | t2[1])
                        if new_alpha_pair not in pairs:
                            pairs.append((t1[0] | t2[0], t1[1] | t2[1]))
    internal_places = filter(lambda p: __pair_maximizer(pairs, p), pairs)
    net = PetriNet('alpha_classic_net_' + str(time.time()))
    label_transition_dict = {}

    for i in range(0, len(labels)):
        label_transition_dict[labels[i]] = PetriNet.Transition(
            labels[i], labels[i])
        net.transitions.add(label_transition_dict[labels[i]])

    src = __add_source(net, alpha_abstraction.start_activities,
                       label_transition_dict)
    sink = __add_sink(net, alpha_abstraction.end_activities,
                      label_transition_dict)

    for pair in internal_places:
        place = PetriNet.Place(str(pair))
        net.places.add(place)
        for in_arc in pair[0]:
            add_arc_from_to(label_transition_dict[in_arc], place, net)
        for out_arc in pair[1]:
            add_arc_from_to(place, label_transition_dict[out_arc], net)
    return net, Marking({src: 1}), Marking({sink: 1})
Exemple #10
0
def __add_source(net, start_activities, label_transition_dict):
    source = PetriNet.Place('start')
    net.places.add(source)
    for s in start_activities:
        add_arc_from_to(source, label_transition_dict[s], net)
    return source
def _add_src_sink_transitions(net, p_s, p_t):
    src = pn_util.add_transition(net)
    pn_util.add_arc_from_to(src, p_s, net)
    sink = pn_util.add_transition(net)
    pn_util.add_arc_from_to(p_t, sink, net)
    return net, petrinet.Marking(), petrinet.Marking()
net.places.add(p_2)
net.places.add(p_3)
net.places.add(p_4)

t_1 = PetriNet.Transition("Activity A", "Activity A")
t_2 = PetriNet.Transition("Activity B", "Activity B")
t_3 = PetriNet.Transition("Activity C", "Activity C")
t_4 = PetriNet.Transition("Activity D", "Activity D")
# Add the transitions to the Petri Net
net.transitions.add(t_1)
net.transitions.add(t_2)
net.transitions.add(t_3)
net.transitions.add(t_4)

from pm4py.objects.petri import utils
utils.add_arc_from_to(start, t_1, net)
utils.add_arc_from_to(t_4, end, net)
utils.add_arc_from_to(t_1, p_1, net)
utils.add_arc_from_to(t_1, p_2, net)
utils.add_arc_from_to(p_1, t_2, net)
utils.add_arc_from_to(p_2, t_3, net)
utils.add_arc_from_to(t_2, p_3, net)
utils.add_arc_from_to(t_3, p_4, net)
utils.add_arc_from_to(p_3, t_4, net)
utils.add_arc_from_to(p_4, t_4, net)
initial_marking = Marking()
initial_marking[start] = 1
final_marking = Marking()
final_marking[end] = 1

from pm4py.objects.petri.exporter import exporter as pnml_exporter
Exemple #13
0
def processing(log, causal, follows):
    """
    Applying the Alpha Miner with the new relations

    Parameters
    -------------
    log
        Filtered log
    causal
        Pairs that have a causal relation (->)
    follows
        Pairs that have a follow relation (>)

    Returns
    -------------
    net
        Petri net
    im
        Initial marking
    fm
        Final marking
    """
    # create list of all events
    labels = set()
    start_activities = set()
    end_activities = set()
    for trace in log:
        start_activities.add(trace.__getitem__(0))
        end_activities.add(trace.__getitem__(len(trace) - 1))
        for events in trace:
            labels.add(events)
    labels = list(labels)
    pairs = []

    for key, element in causal.items():
        for item in element:
            if get_sharp_relation(follows, key, key):
                if get_sharp_relation(follows, item, item):
                    pairs.append(({key}, {item}))

    # combining pairs
    for i in range(0, len(pairs)):
        t1 = pairs[i]
        for j in range(i, len(pairs)):
            t2 = pairs[j]
            if t1 != t2:
                if t1[0].issubset(t2[0]) or t1[1].issubset(t2[1]):
                    if get_sharp_relations_for_sets(
                            follows, t1[0],
                            t2[0]) and get_sharp_relations_for_sets(
                                follows, t1[1], t2[1]):
                        new_alpha_pair = (t1[0] | t2[0], t1[1] | t2[1])
                        if new_alpha_pair not in pairs:
                            pairs.append((t1[0] | t2[0], t1[1] | t2[1]))
    # maximize pairs
    cleaned_pairs = list(filter(lambda p: __pair_maximizer(pairs, p), pairs))
    # create transitions
    net = PetriNet('alpha_plus_net_' + str(time.time()))
    label_transition_dict = {}
    for label in labels:
        if label != 'artificial_start' and label != 'artificial_end':
            label_transition_dict[label] = PetriNet.Transition(label, label)
            net.transitions.add(label_transition_dict[label])
        else:
            label_transition_dict[label] = PetriNet.Transition(label, None)
            net.transitions.add(label_transition_dict[label])
    # and source and sink
    src = add_source(net, start_activities, label_transition_dict)
    sink = add_sink(net, end_activities, label_transition_dict)
    # create places
    for pair in cleaned_pairs:
        place = PetriNet.Place(str(pair))
        net.places.add(place)
        for in_arc in pair[0]:
            add_arc_from_to(label_transition_dict[in_arc], place, net)
        for out_arc in pair[1]:
            add_arc_from_to(place, label_transition_dict[out_arc], net)

    return net, Marking({src: 1}), Marking({sink: 1}), cleaned_pairs
def apply(heu_net, parameters=None):
    """
    Converts an Heuristics Net to a Petri net

    Parameters
    --------------
    heu_net
        Heuristics net
    parameters
        Possible parameters of the algorithm

    Returns
    --------------
    net
        Petri net
    im
        Initial marking
    fm
        Final marking
    """
    if parameters is None:
        parameters = {}
    net = PetriNet("")
    im = Marking()
    fm = Marking()
    source_places = []
    sink_places = []
    hid_trans_count = 0
    for index, sa_list in enumerate(heu_net.start_activities):
        source = PetriNet.Place("source" + str(index))
        source_places.append(source)
        net.places.add(source)
        im[source] = 1
    for index, ea_list in enumerate(heu_net.end_activities):
        sink = PetriNet.Place("sink" + str(index))
        sink_places.append(sink)
        net.places.add(sink)
        fm[sink] = 1
    act_trans = {}
    who_is_entering = {}
    who_is_exiting = {}
    for act1_name in heu_net.nodes:
        act1 = heu_net.nodes[act1_name]
        if act1_name not in act_trans:
            act_trans[act1_name] = PetriNet.Transition(act1_name, act1_name)
            net.transitions.add(act_trans[act1_name])
            who_is_entering[act1_name] = set()
            who_is_exiting[act1_name] = set()
            for index, sa_list in enumerate(heu_net.start_activities):
                if act1_name in sa_list:
                    who_is_entering[act1_name].add((None, index))
            for index, ea_list in enumerate(heu_net.end_activities):
                if act1_name in ea_list:
                    who_is_exiting[act1_name].add((None, index))
        for act2 in act1.output_connections:
            act2_name = act2.node_name
            if act2_name not in act_trans:
                act_trans[act2_name] = PetriNet.Transition(
                    act2_name, act2_name)
                net.transitions.add(act_trans[act2_name])
                who_is_entering[act2_name] = set()
                who_is_exiting[act2_name] = set()
                for index, sa_list in enumerate(heu_net.start_activities):
                    if act2_name in sa_list:
                        who_is_entering[act2_name].add((None, index))
                for index, ea_list in enumerate(heu_net.end_activities):
                    if act2_name in ea_list:
                        who_is_exiting[act2_name].add((None, index))
            who_is_entering[act2_name].add((act1_name, None))
            who_is_exiting[act1_name].add((act2_name, None))
    places_entering = {}
    for act1 in who_is_entering:
        cliques = find_bindings(heu_net.nodes[act1].and_measures_in)
        places_entering[act1] = {}
        entering_activities = list(who_is_entering[act1])
        entering_activities_wo_source = sorted(
            [x for x in entering_activities if x[0] is not None],
            key=lambda x: x[0])
        entering_activities_only_source = [
            x for x in entering_activities if x[0] is None
        ]
        if entering_activities_wo_source:
            master_place = PetriNet.Place("pre_" + act1)
            net.places.add(master_place)
            add_arc_from_to(master_place, act_trans[act1], net)
            if len(entering_activities) == 1:
                places_entering[act1][entering_activities[0]] = master_place
            else:
                for index, act in enumerate(entering_activities_wo_source):
                    if act[0] in heu_net.nodes[act1].and_measures_in:
                        z = 0
                        while z < len(cliques):
                            if act[0] in cliques[z]:
                                hid_trans_count = hid_trans_count + 1
                                hid_trans = PetriNet.Transition(
                                    "hid_" + str(hid_trans_count), None)
                                net.transitions.add(hid_trans)
                                add_arc_from_to(hid_trans, master_place, net)
                                for act2 in cliques[z]:
                                    if (act2,
                                            None) not in places_entering[act1]:
                                        s_place = PetriNet.Place("splace_in_" +
                                                                 act1 + "_" +
                                                                 act2 + "_" +
                                                                 str(index))
                                        net.places.add(s_place)
                                        places_entering[act1][(act2,
                                                               None)] = s_place
                                    add_arc_from_to(
                                        places_entering[act1][(act2, None)],
                                        hid_trans, net)
                                del cliques[z]
                                continue
                            z = z + 1
                        pass
                    elif act not in places_entering[act1]:
                        hid_trans_count = hid_trans_count + 1
                        hid_trans = PetriNet.Transition(
                            "hid_" + str(hid_trans_count), None)
                        net.transitions.add(hid_trans)
                        add_arc_from_to(hid_trans, master_place, net)
                        if act not in places_entering[act1]:
                            s_place = PetriNet.Place("splace_in_" + act1 +
                                                     "_" + str(index))
                            net.places.add(s_place)
                            places_entering[act1][act] = s_place
                        add_arc_from_to(places_entering[act1][act], hid_trans,
                                        net)
        for el in entering_activities_only_source:
            if len(entering_activities) == 1:
                add_arc_from_to(source_places[el[1]], act_trans[act1], net)
            else:
                hid_trans_count = hid_trans_count + 1
                hid_trans = PetriNet.Transition("hid_" + str(hid_trans_count),
                                                None)
                net.transitions.add(hid_trans)
                add_arc_from_to(source_places[el[1]], hid_trans, net)
                add_arc_from_to(hid_trans, master_place, net)
    for act1 in who_is_exiting:
        cliques = find_bindings(heu_net.nodes[act1].and_measures_out)
        exiting_activities = list(who_is_exiting[act1])
        exiting_activities_wo_sink = sorted(
            [x for x in exiting_activities if x[0] is not None],
            key=lambda x: x[0])
        exiting_activities_only_sink = [
            x for x in exiting_activities if x[0] is None
        ]
        if exiting_activities_wo_sink:
            if len(exiting_activities) == 1 and len(
                    exiting_activities_wo_sink) == 1:
                ex_act = exiting_activities_wo_sink[0]
                if (act1, None) in places_entering[ex_act[0]]:
                    add_arc_from_to(act_trans[act1],
                                    places_entering[ex_act[0]][(act1, None)],
                                    net)
            else:
                int_place = PetriNet.Place("intplace_" + str(act1))
                net.places.add(int_place)
                add_arc_from_to(act_trans[act1], int_place, net)
                for ex_act in exiting_activities_wo_sink:
                    if (act1, None) in places_entering[ex_act[0]]:
                        if ex_act[0] in heu_net.nodes[act1].and_measures_out:
                            z = 0
                            while z < len(cliques):
                                if ex_act[0] in cliques[z]:
                                    hid_trans_count = hid_trans_count + 1
                                    hid_trans = PetriNet.Transition(
                                        "hid_" + str(hid_trans_count), None)
                                    net.transitions.add(hid_trans)
                                    add_arc_from_to(int_place, hid_trans, net)
                                    for act in cliques[z]:
                                        add_arc_from_to(
                                            hid_trans,
                                            places_entering[act][(act1, None)],
                                            net)
                                    del cliques[z]
                                    continue
                                z = z + 1
                        else:
                            hid_trans_count = hid_trans_count + 1
                            hid_trans = PetriNet.Transition(
                                "hid_" + str(hid_trans_count), None)
                            net.transitions.add(hid_trans)
                            add_arc_from_to(int_place, hid_trans, net)
                            add_arc_from_to(
                                hid_trans,
                                places_entering[ex_act[0]][(act1, None)], net)
        for el in exiting_activities_only_sink:
            if len(exiting_activities) == 1:
                add_arc_from_to(act_trans[act1], sink_places[el[1]], net)
            else:
                hid_trans_count = hid_trans_count + 1
                hid_trans = PetriNet.Transition("hid_" + str(hid_trans_count),
                                                None)
                net.transitions.add(hid_trans)
                add_arc_from_to(int_place, hid_trans, net)
                add_arc_from_to(hid_trans, sink_places[el[1]], net)
    net = remove_rendundant_invisible_transitions(net)
    return net, im, fm
Exemple #15
0
def import_net_from_xml_object(root, parameters=None):
    """
    Import a Petri net from an etree XML object

    Parameters
    ----------
    root
        Root object of the XML
    parameters
        Other parameters of the algorithm
    """
    if parameters is None:
        parameters = {}

    net = PetriNet('imported_' + str(time.time()))
    marking = Marking()
    fmarking = Marking()

    nett = None
    page = None
    finalmarkings = None

    stochastic_information = {}

    for child in root:
        nett = child

    places_dict = {}
    trans_dict = {}

    if nett is not None:
        for child in nett:
            if "page" in child.tag:
                page = child
            if "finalmarkings" in child.tag:
                finalmarkings = child

    if page is None:
        page = nett

    if page is not None:
        for child in page:
            if "place" in child.tag:
                position_X = None
                position_Y = None
                dimension_X = None
                dimension_Y = None
                place_id = child.get("id")
                place_name = place_id
                number = 0
                for child2 in child:
                    if child2.tag.endswith('name'):
                        for child3 in child2:
                            if child3.text:
                                place_name = child3.text
                    if child2.tag.endswith('initialMarking'):
                        for child3 in child2:
                            if child3.tag.endswith("text"):
                                number = int(child3.text)
                    if child2.tag.endswith('graphics'):
                        for child3 in child2:
                            if child3.tag.endswith('position'):
                                position_X = float(child3.get("x"))
                                position_Y = float(child3.get("y"))
                            elif child3.tag.endswith("dimension"):
                                dimension_X = float(child3.get("x"))
                                dimension_Y = float(child3.get("y"))
                places_dict[place_id] = PetriNet.Place(place_id)
                places_dict[place_id].properties[
                    constants.PLACE_NAME_TAG] = place_name
                net.places.add(places_dict[place_id])
                if position_X is not None and position_Y is not None and dimension_X is not None and dimension_Y is not None:
                    places_dict[place_id].properties[
                        constants.LAYOUT_INFORMATION_PETRI] = ((position_X,
                                                                position_Y),
                                                               (dimension_X,
                                                                dimension_Y))
                if number > 0:
                    marking[places_dict[place_id]] = number
                del place_name

    if page is not None:
        for child in page:
            if child.tag.endswith("transition"):
                position_X = None
                position_Y = None
                dimension_X = None
                dimension_Y = None
                trans_name = child.get("id")
                trans_label = trans_name
                trans_visible = True

                random_variable = None

                for child2 in child:
                    if child2.tag.endswith("name"):
                        for child3 in child2:
                            if child3.text:
                                if trans_label == trans_name:
                                    trans_label = child3.text
                    if child2.tag.endswith("graphics"):
                        for child3 in child2:
                            if child3.tag.endswith("position"):
                                position_X = float(child3.get("x"))
                                position_Y = float(child3.get("y"))
                            elif child3.tag.endswith("dimension"):
                                dimension_X = float(child3.get("x"))
                                dimension_Y = float(child3.get("y"))
                    if child2.tag.endswith("toolspecific"):
                        tool = child2.get("tool")
                        if "ProM" in tool:
                            activity = child2.get("activity")
                            if "invisible" in activity:
                                trans_visible = False
                        elif "StochasticPetriNet" in tool:
                            distribution_type = None
                            distribution_parameters = None
                            priority = None
                            weight = None

                            for child3 in child2:
                                key = child3.get("key")
                                value = child3.text

                                if key == "distributionType":
                                    distribution_type = value
                                elif key == "distributionParameters":
                                    distribution_parameters = value
                                elif key == "priority":
                                    priority = int(value)
                                elif key == "weight":
                                    weight = float(value)

                            random_variable = RandomVariable()
                            random_variable.read_from_string(
                                distribution_type, distribution_parameters)
                            random_variable.set_priority(priority)
                            random_variable.set_weight(weight)

                if not trans_visible:
                    trans_label = None
                # if "INVISIBLE" in trans_label:
                #    trans_label = None

                trans_dict[trans_name] = PetriNet.Transition(
                    trans_name, trans_label)
                net.transitions.add(trans_dict[trans_name])

                if random_variable is not None:
                    trans_dict[trans_name].properties[
                        constants.STOCHASTIC_DISTRIBUTION] = random_variable
                if position_X is not None and position_Y is not None and dimension_X is not None and dimension_Y is not None:
                    trans_dict[trans_name].properties[
                        constants.LAYOUT_INFORMATION_PETRI] = ((position_X,
                                                                position_Y),
                                                               (dimension_X,
                                                                dimension_Y))

    if page is not None:
        for child in page:
            if child.tag.endswith("arc"):
                arc_source = child.get("source")
                arc_target = child.get("target")
                arc_weight = 1

                for arc_child in child:
                    if arc_child.tag.endswith("inscription"):
                        for text_arcweight in arc_child:
                            if text_arcweight.tag.endswith("text"):
                                arc_weight = int(text_arcweight.text)

                if arc_source in places_dict and arc_target in trans_dict:
                    add_arc_from_to(places_dict[arc_source],
                                    trans_dict[arc_target],
                                    net,
                                    weight=arc_weight)
                elif arc_target in places_dict and arc_source in trans_dict:
                    add_arc_from_to(trans_dict[arc_source],
                                    places_dict[arc_target],
                                    net,
                                    weight=arc_weight)

    if finalmarkings is not None:
        for child in finalmarkings:
            for child2 in child:
                place_id = child2.get("idref")
                for child3 in child2:
                    if child3.tag.endswith("text"):
                        number = int(child3.text)
                        if number > 0:
                            fmarking[places_dict[place_id]] = number

    # generate the final marking in the case has not been found
    if len(fmarking) == 0:
        fmarking = final_marking.discover_final_marking(net)

    return net, marking, fmarking
 def test_mcg(self):
     net = PetriNet("mcg")
     p_1 = PetriNet.Place("p_1")
     p_2 = PetriNet.Place("p_2")
     p_3 = PetriNet.Place("p_3")
     p_4 = PetriNet.Place("p_4")
     p_5 = PetriNet.Place("p_5")
     net.places.add(p_1)
     net.places.add(p_2)
     net.places.add(p_3)
     net.places.add(p_4)
     net.places.add(p_5)
     t_1 = PetriNet.Transition("t_1", "t_1")
     t_2 = PetriNet.Transition("t_2", "t_2")
     t_3 = PetriNet.Transition("t_3", "t_3")
     t_4 = PetriNet.Transition("t_4", "t_4")
     t_5 = PetriNet.Transition("t_5", "t_5")
     t_6 = PetriNet.Transition("t_6", "t_6")
     net.transitions.add(t_1)
     net.transitions.add(t_2)
     net.transitions.add(t_3)
     net.transitions.add(t_4)
     net.transitions.add(t_5)
     net.transitions.add(t_6)
     utils.add_arc_from_to(p_1, t_1, net)
     utils.add_arc_from_to(t_1, p_2, net)
     utils.add_arc_from_to(p_2, t_3, net)
     utils.add_arc_from_to(t_3, p_3, net, weight=2)
     utils.add_arc_from_to(p_3, t_4, net)
     utils.add_arc_from_to(t_4, p_2, net)
     utils.add_arc_from_to(p_1, t_2, net)
     utils.add_arc_from_to(t_2, p_4, net)
     utils.add_arc_from_to(p_4, t_5, net)
     utils.add_arc_from_to(t_5, p_5, net, weight=2)
     utils.add_arc_from_to(p_5, t_6, net)
     utils.add_arc_from_to(t_6, p_4, net)
     initial_marking = Marking()
     initial_marking[p_1] = 1
     mcg = minimal_coverability_graph.apply(net, initial_marking)
Exemple #17
0
def apply(dfg, parameters=None):
    """
    Applies the DFG mining on a given object (if it is a Pandas dataframe or a log, the DFG is calculated)

    Parameters
    -------------
    dfg
        Object (DFG) (if it is a Pandas dataframe or a log, the DFG is calculated)
    parameters
        Parameters
    """
    if parameters is None:
        parameters = {}

    dfg = dfg
    start_activities = parameters[
        PARAM_KEY_START_ACTIVITIES] if PARAM_KEY_START_ACTIVITIES in parameters else dfg_utils.infer_start_activities(
            dfg)
    end_activities = parameters[
        PARAM_KEY_END_ACTIVITIES] if PARAM_KEY_END_ACTIVITIES in parameters else dfg_utils.infer_end_activities(
            dfg)
    activities = dfg_utils.get_activities_from_dfg(dfg)

    net = PetriNet("")
    im = Marking()
    fm = Marking()

    source = PetriNet.Place("source")
    net.places.add(source)
    im[source] = 1
    sink = PetriNet.Place("sink")
    net.places.add(sink)
    fm[sink] = 1

    places_corr = {}
    index = 0

    for act in activities:
        places_corr[act] = PetriNet.Place(act)
        net.places.add(places_corr[act])

    for act in start_activities:
        if act in places_corr:
            index = index + 1
            trans = PetriNet.Transition(act + "_" + str(index), act)
            net.transitions.add(trans)
            add_arc_from_to(source, trans, net)
            add_arc_from_to(trans, places_corr[act], net)

    for act in end_activities:
        if act in places_corr:
            index = index + 1
            inv_trans = PetriNet.Transition(act + "_" + str(index), None)
            net.transitions.add(inv_trans)
            add_arc_from_to(places_corr[act], inv_trans, net)
            add_arc_from_to(inv_trans, sink, net)

    for el in dfg.keys():
        act1 = el[0]
        act2 = el[1]

        index = index + 1
        trans = PetriNet.Transition(act2 + "_" + str(index), act2)
        net.transitions.add(trans)

        add_arc_from_to(places_corr[act1], trans, net)
        add_arc_from_to(trans, places_corr[act2], net)

    return net, im, fm
def recursively_add_tree(parent_tree,
                         tree,
                         net,
                         initial_entity_subtree,
                         final_entity_subtree,
                         counts,
                         rec_depth,
                         force_add_skip=False):
    """
    Recursively add the subtrees to the Petri net

    Parameters
    -----------
    parent_tree
        Parent tree
    tree
        Current subtree
    net
        Petri net
    initial_entity_subtree
        Initial entity (place/transition) that should be attached from the subtree
    final_entity_subtree
        Final entity (place/transition) that should be attached from the subtree
    counts
        Counts object (keeps the number of places, transitions and hidden transitions)
    rec_depth
        Recursion depth of the current iteration
    force_add_skip
        Boolean value that tells if the addition of a skip is mandatory

    Returns
    ----------
    net
        Updated Petri net
    counts
        Updated counts object (keeps the number of places, transitions and hidden transitions)
    final_place
        Last place added in this recursion
    """
    if type(initial_entity_subtree) is PetriNet.Transition:
        initial_place = get_new_place(counts)
        net.places.add(initial_place)
        add_arc_from_to(initial_entity_subtree, initial_place, net)
    else:
        initial_place = initial_entity_subtree
    if final_entity_subtree is not None and type(
            final_entity_subtree) is PetriNet.Place:
        final_place = final_entity_subtree
    else:
        final_place = get_new_place(counts)
        net.places.add(final_place)
        if final_entity_subtree is not None and type(
                final_entity_subtree) is PetriNet.Transition:
            add_arc_from_to(final_place, final_entity_subtree, net)
    tree_childs = [child for child in tree.children]

    if force_add_skip:
        invisible = get_new_hidden_trans(counts, type_trans="skip")
        add_arc_from_to(initial_place, invisible, net)
        add_arc_from_to(invisible, final_place, net)

    if tree.operator is None:
        trans = tree
        if trans.label is None:
            petri_trans = get_new_hidden_trans(counts, type_trans="skip")
        else:
            petri_trans = get_transition(counts, trans.label)
        net.transitions.add(petri_trans)
        add_arc_from_to(initial_place, petri_trans, net)
        add_arc_from_to(petri_trans, final_place, net)

    if tree.operator == Operator.XOR:
        for subtree in tree_childs:
            net, counts, intermediate_place = recursively_add_tree(
                tree, subtree, net, initial_place, final_place, counts,
                rec_depth + 1)
    elif tree.operator == Operator.OR:
        new_initial_trans = get_new_hidden_trans(counts, type_trans="tauSplit")
        net.transitions.add(new_initial_trans)
        add_arc_from_to(initial_place, new_initial_trans, net)
        new_final_trans = get_new_hidden_trans(counts, type_trans="tauJoin")
        net.transitions.add(new_final_trans)
        add_arc_from_to(new_final_trans, final_place, net)
        terminal_place = get_new_place(counts)
        net.places.add(terminal_place)
        add_arc_from_to(terminal_place, new_final_trans, net)
        first_place = get_new_place(counts)
        net.places.add(first_place)
        add_arc_from_to(new_initial_trans, first_place, net)

        for subtree in tree_childs:
            subtree_init_place = get_new_place(counts)
            net.places.add(subtree_init_place)
            add_arc_from_to(new_initial_trans, subtree_init_place, net)
            subtree_start_place = get_new_place(counts)
            net.places.add(subtree_start_place)
            subtree_end_place = get_new_place(counts)
            net.places.add(subtree_end_place)
            trans_start = get_new_hidden_trans(counts,
                                               type_trans="inclusiveStart")
            trans_later = get_new_hidden_trans(counts,
                                               type_trans="inclusiveLater")
            trans_skip = get_new_hidden_trans(counts,
                                              type_trans="inclusiveSkip")
            net.transitions.add(trans_start)
            net.transitions.add(trans_later)
            net.transitions.add(trans_skip)
            add_arc_from_to(first_place, trans_start, net)
            add_arc_from_to(subtree_init_place, trans_start, net)
            add_arc_from_to(trans_start, subtree_start_place, net)
            add_arc_from_to(trans_start, terminal_place, net)

            add_arc_from_to(terminal_place, trans_later, net)
            add_arc_from_to(subtree_init_place, trans_later, net)
            add_arc_from_to(trans_later, subtree_start_place, net)
            add_arc_from_to(trans_later, terminal_place, net)

            add_arc_from_to(terminal_place, trans_skip, net)
            add_arc_from_to(subtree_init_place, trans_skip, net)
            add_arc_from_to(trans_skip, terminal_place, net)
            add_arc_from_to(trans_skip, subtree_end_place, net)

            add_arc_from_to(subtree_end_place, new_final_trans, net)

            net, counts, intermediate_place = recursively_add_tree(
                tree, subtree, net, subtree_start_place, subtree_end_place,
                counts, rec_depth + 1)

    elif tree.operator == Operator.PARALLEL:
        new_initial_trans = get_new_hidden_trans(counts, type_trans="tauSplit")
        net.transitions.add(new_initial_trans)
        add_arc_from_to(initial_place, new_initial_trans, net)
        new_final_trans = get_new_hidden_trans(counts, type_trans="tauJoin")
        net.transitions.add(new_final_trans)
        add_arc_from_to(new_final_trans, final_place, net)

        for subtree in tree_childs:
            net, counts, intermediate_place = recursively_add_tree(
                tree, subtree, net, new_initial_trans, new_final_trans, counts,
                rec_depth + 1)
    elif tree.operator == Operator.SEQUENCE:
        intermediate_place = initial_place
        for i in range(len(tree_childs)):
            final_connection_place = None
            if i == len(tree_childs) - 1:
                final_connection_place = final_place
            net, counts, intermediate_place = recursively_add_tree(
                tree, tree_childs[i], net, intermediate_place,
                final_connection_place, counts, rec_depth + 1)
    elif tree.operator == Operator.LOOP:
        # if not parent_tree.operator == Operator.SEQUENCE:
        new_initial_place = get_new_place(counts)
        net.places.add(new_initial_place)
        init_loop_trans = get_new_hidden_trans(counts, type_trans="init_loop")
        net.transitions.add(init_loop_trans)
        add_arc_from_to(initial_place, init_loop_trans, net)
        add_arc_from_to(init_loop_trans, new_initial_place, net)
        initial_place = new_initial_place
        loop_trans = get_new_hidden_trans(counts, type_trans="loop")
        net.transitions.add(loop_trans)
        if len(tree_childs) == 1:
            net, counts, intermediate_place = recursively_add_tree(
                tree, tree_childs[0], net, initial_place, final_place, counts,
                rec_depth + 1)
            add_arc_from_to(final_place, loop_trans, net)
            add_arc_from_to(loop_trans, initial_place, net)
        else:
            dummy = ProcessTree()
            do = tree_childs[0]
            redo = tree_childs[1]
            exit = tree_childs[2] if len(tree_childs) > 2 and (
                tree_childs[2].label is not None
                or tree_childs[2].children) else dummy

            net, counts, int1 = recursively_add_tree(tree, do, net,
                                                     initial_place, None,
                                                     counts, rec_depth + 1)
            net, counts, int2 = recursively_add_tree(tree, redo, net, int1,
                                                     None, counts,
                                                     rec_depth + 1)
            net, counts, int3 = recursively_add_tree(tree, exit, net, int1,
                                                     final_place, counts,
                                                     rec_depth + 1)

            looping_place = int2

            add_arc_from_to(looping_place, loop_trans, net)
            add_arc_from_to(loop_trans, initial_place, net)

    return net, counts, final_place
def execute_script():
    net = PetriNet("")
    start = PetriNet.Place("start")
    end = PetriNet.Place("end")
    c1 = PetriNet.Place("c1")
    c2 = PetriNet.Place("c2")
    c3 = PetriNet.Place("c3")
    c4 = PetriNet.Place("c4")
    c5 = PetriNet.Place("c5")
    c6 = PetriNet.Place("c6")
    c7 = PetriNet.Place("c7")
    c8 = PetriNet.Place("c8")
    c9 = PetriNet.Place("c9")
    net.places.add(c1)
    net.places.add(c2)
    net.places.add(c3)
    net.places.add(c4)
    net.places.add(c5)
    net.places.add(c6)
    net.places.add(c7)
    net.places.add(c8)
    net.places.add(c9)
    net.places.add(start)
    net.places.add(end)
    t1 = PetriNet.Transition("t1", "a")
    t2 = PetriNet.Transition("t2", None)
    t3 = PetriNet.Transition("t3", "b")
    t4 = PetriNet.Transition("t4", "c")
    t5 = PetriNet.Transition("t5", "d")
    t6 = PetriNet.Transition("t6", "e")
    t7 = PetriNet.Transition("t7", None)
    t8 = PetriNet.Transition("t8", "f")
    t9 = PetriNet.Transition("t9", "g")
    t10 = PetriNet.Transition("t10", "h")
    t11 = PetriNet.Transition("t11", None)
    net.transitions.add(t1)
    net.transitions.add(t2)
    net.transitions.add(t3)
    net.transitions.add(t4)
    net.transitions.add(t5)
    net.transitions.add(t6)
    net.transitions.add(t7)
    net.transitions.add(t8)
    net.transitions.add(t9)
    net.transitions.add(t10)
    net.transitions.add(t11)
    add_arc_from_to(start, t1, net)
    add_arc_from_to(t1, c1, net)
    add_arc_from_to(t1, c2, net)
    add_arc_from_to(c1, t2, net)
    add_arc_from_to(c1, t3, net)
    add_arc_from_to(c2, t4, net)
    add_arc_from_to(t2, c3, net)
    add_arc_from_to(t3, c3, net)
    add_arc_from_to(t4, c4, net)
    add_arc_from_to(c3, t5, net)
    add_arc_from_to(c4, t5, net)
    add_arc_from_to(t5, c5, net)
    add_arc_from_to(c5, t6, net)
    add_arc_from_to(t6, c1, net)
    add_arc_from_to(t6, c2, net)
    add_arc_from_to(c5, t7, net)
    add_arc_from_to(t7, c7, net)
    add_arc_from_to(t7, c6, net)
    add_arc_from_to(c7, t8, net)
    add_arc_from_to(c6, t9, net)
    add_arc_from_to(t8, c8, net)
    add_arc_from_to(t9, c9, net)
    add_arc_from_to(c8, t11, net)
    add_arc_from_to(c9, t11, net)
    add_arc_from_to(t11, end, net)
    add_arc_from_to(c5, t10, net)
    add_arc_from_to(t10, end, net)
    im = Marking()
    im[start] = 1
    fm = Marking()
    fm[end] = 1
    gvizs = []
    gvizs.append(
        visualizer.apply(net,
                         im,
                         final_marking=fm,
                         parameters={"format": "svg"}))
    visualizer.view(gvizs[len(gvizs) - 1])
    decomposed_net = decomposition.decompose(net, im, fm)
    for snet, sim, sfm in decomposed_net:
        gvizs.append(
            visualizer.apply(snet,
                             sim,
                             final_marking=sfm,
                             parameters={"format": "svg"}))
        visualizer.view(gvizs[len(gvizs) - 1])