def make_petrinet_from_automaton(auto):
    '''
    Make petri net from automaton based on state-based region theory
    :param auto: automaton
    :return: derived petri net
    '''
    min_region_set, di, ger = minimal_region_set(auto)

    id = 0
    net = PetriNet('new_net')
    trans_set = set()
    for trans in auto.transitions:
        if trans.name not in trans_set:
            t = PetriNet.Transition(trans.name, trans.name)
            net.transitions.add(t)
            trans_set.add(trans.name)

    for min_region in di.items():
        place = PetriNet.Place(id)
        net.places.add(place)
        for trans in min_region[1][0]:
            for transs in net.transitions:
                if trans == transs.name:
                    petri_utils.add_arc_from_to(transs, place, net)
        for trans in min_region[1][1]:
            for transs in net.transitions:
                if trans == transs.name:
                    petri_utils.add_arc_from_to(place, transs, net)
        id += 1

    im = discover_initial_marking(net)
    fm = discover_final_marking(net)

    return net, im, fm
Ejemplo n.º 2
0
def to(net0, im0, fm0):
    net = PetriNet("")
    im = Marking()
    fm = Marking()
    dp = {}
    dt = {}
    i = 0
    while i < len(net0[0]):
        p = PetriNet.Place(str(net0[0][i]))
        net.places.add(p)
        dp[i] = p
        i = i + 1
    i = 0
    while i < len(net0[1]):
        t = PetriNet.Transition("t%d" % (i), net0[1][i][0])
        net.transitions.add(t)
        dt[i] = t
        i = i + 1
    i = 0
    while i < len(net0[1]):
        for p in net0[1][i][1]:
            petri_utils.utils.add_arc_from_to(dp[p], dt[i], net)
        for p in net0[1][i][2]:
            petri_utils.utils.add_arc_from_to(dt[i], dp[p], net)
        i = i + 1
    for p in im0:
        im[dp[p]] = im0[p]
    for p in fm0:
        fm[dp[p]] = fm0[p]
    return net, im, fm
Ejemplo n.º 3
0
def construct_trace_net(trace,
                        trace_name_key=xes_util.DEFAULT_NAME_KEY,
                        activity_key=xes_util.DEFAULT_NAME_KEY):
    """
    Creates a trace net, i.e. a trace in Petri net form.

    Parameters
    ----------
    trace: :class:`list` input trace, assumed to be a list of events
    trace_name_key: :class:`str` key of the attribute that defines the name of the trace
    activity_key: :class:`str` key of the attribute of the events that defines the activity name

    Returns
    -------
    tuple: :class:`tuple` of the net, initial marking and the final marking

    """
    net = PetriNet('trace net of %s' %
                   trace.attributes[trace_name_key] if trace_name_key in
                   trace.attributes else ' ')
    place_map = {0: PetriNet.Place('p_0')}
    net.places.add(place_map[0])
    for i in range(0, len(trace)):
        t = PetriNet.Transition('t_' + trace[i][activity_key] + '_' + str(i),
                                trace[i][activity_key])
        net.transitions.add(t)
        place_map[i + 1] = PetriNet.Place('p_' + str(i + 1))
        net.places.add(place_map[i + 1])
        add_arc_from_to(place_map[i], t, net)
        add_arc_from_to(t, place_map[i + 1], net)
    return net, Marking({place_map[0]: 1}), Marking({place_map[len(trace)]: 1})
Ejemplo n.º 4
0
def __copy_into(source_net, target_net, upper, skip):
    t_map = {}
    p_map = {}
    for t in source_net.transitions:
        name = (t.name, skip) if upper else (skip, t.name)
        label = (t.label, skip) if upper else (skip, t.label)
        t_map[t] = PetriNet.Transition(name, label)
        if properties.TRACE_NET_TRANS_INDEX in t.properties:
            # 16/02/2021: copy the index property from the transition of the trace net
            t_map[t].properties[
                properties.TRACE_NET_TRANS_INDEX] = t.properties[
                    properties.TRACE_NET_TRANS_INDEX]
        target_net.transitions.add(t_map[t])

    for p in source_net.places:
        name = (p.name, skip) if upper else (skip, p.name)
        p_map[p] = PetriNet.Place(name)
        if properties.TRACE_NET_PLACE_INDEX in p.properties:
            # 16/02/2021: copy the index property from the place of the trace net
            p_map[p].properties[
                properties.TRACE_NET_PLACE_INDEX] = p.properties[
                    properties.TRACE_NET_PLACE_INDEX]
        target_net.places.add(p_map[p])

    for t in source_net.transitions:
        for a in t.in_arcs:
            add_arc_from_to(p_map[a.source], t_map[t], target_net)
        for a in t.out_arcs:
            add_arc_from_to(t_map[t], p_map[a.target], target_net)

    return t_map, p_map
Ejemplo n.º 5
0
    def petrinetcreator(self, places, transitions, arcs):
        net = PetriNet("new_petri_net")

        source = PetriNet.Place("source")
        sink = PetriNet.Place("sink")
        for i in range(1, places + 1):
            p = PetriNet.Place("p_" + str(i))
            net.places.add(p)
        net.places.add(source)
        net.places.add(sink)

        for i in range(1, transitions + 1):
            t = PetriNet.Transition("name_" + str(i), "label_" + str(i))
            net.transitions.add(t)

        for i in range(1, len(arcs + 1)):
            arc = arcs[i].split()
            utils.add_arc_from_to(arc[0], arc[1], net)

        initial_marking = Marking()
        initial_marking[source] = 1
        final_marking = Marking()
        final_marking[sink] = 1

        return net
Ejemplo n.º 6
0
def test_marking_equality():
    net = PetriNet()

    p0 = PetriNet.Place('p0')
    p1 = PetriNet.Place('p1')
    net.places.update([p0, p1])

    m0 = Marking([p0])
    m1 = Marking([p0])

    assert m0 == m1
Ejemplo n.º 7
0
def construct(pn1, im1, fm1, pn2, im2, fm2, skip):
    """
    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

    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)

    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)
                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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
def merge_comp(comp1, comp2):
    net = PetriNet("")
    im = Marking()
    fm = Marking()
    places = {}
    trans = {}

    for pl in comp1[0].places:
        places[pl.name] = PetriNet.Place(pl.name)
        net.places.add(places[pl.name])
        if pl in comp1[1]:
            im[places[pl.name]] = comp1[1][pl]
        if pl in comp1[2]:
            fm[places[pl.name]] = comp1[2][pl]

    for pl in comp2[0].places:
        places[pl.name] = PetriNet.Place(pl.name)
        net.places.add(places[pl.name])
        if pl in comp2[1]:
            im[places[pl.name]] = comp2[1][pl]
        if pl in comp2[2]:
            fm[places[pl.name]] = comp2[2][pl]

    for tr in comp1[0].transitions:
        trans[tr.name] = PetriNet.Transition(tr.name, tr.label)
        net.transitions.add(trans[tr.name])

    for tr in comp2[0].transitions:
        if not tr.name in trans:
            trans[tr.name] = PetriNet.Transition(tr.name, tr.label)
            net.transitions.add(trans[tr.name])

    for arc in comp1[0].arcs:
        if type(arc.source) is PetriNet.Place:
            add_arc_from_to(places[arc.source.name], trans[arc.target.name],
                            net)
        else:
            add_arc_from_to(trans[arc.source.name], places[arc.target.name],
                            net)

    for arc in comp2[0].arcs:
        if type(arc.source) is PetriNet.Place:
            add_arc_from_to(places[arc.source.name], trans[arc.target.name],
                            net)
        else:
            add_arc_from_to(trans[arc.source.name], places[arc.target.name],
                            net)

    lvis_labels = sorted(
        [t.label for t in net.transitions if t.label is not None])
    t_tuple = tuple(
        sorted(
            list(
                int(hashlib.md5(t.name.encode('utf-8')).hexdigest(), 16)
                for t in net.transitions)))
    net.lvis_labels = lvis_labels
    net.t_tuple = t_tuple

    return (net, im, fm)
Ejemplo n.º 10
0
def add_transition(net, name=None, label=None):
    name = name if name is not None else 't_' + str(len(
        net.transitions)) + '_' + str(time.time()) + str(
            random.randint(0, 10000))
    t = PetriNet.Transition(name=name, label=label)
    net.transitions.add(t)
    return t
Ejemplo n.º 11
0
def postprocessing(net, initial_marking, final_marking, A, B, pairs,
                   loop_one_list):
    """
    Adding the filtered transitions to the Petri net

    Parameters
    ------------
    loop_list
        List of looped activities
    classical_alpha_result
        Result after applying the classic alpha algorithm to the filtered log
    A
        See Paper for definition
    B
        See Paper for definition

    Returns
    ------------
    net
        Petri net
    im
        Initial marking
    fm
        Final marking
    """
    label_transition_dict = {}
    for label in loop_one_list:
        label_transition_dict[label] = PetriNet.Transition(label, label)
        net.transitions.add(label_transition_dict[label])

    # F L1L
    # Key is specific loop element
    for key, value in A.items():
        if key in B:
            A_without_B = value - B[key]
            B_without_A = B[key] - value
            pair = (A_without_B, B_without_A)
            for pair_try in pairs:
                in_part = pair_try[0]
                out_part = pair_try[1]
                if pair[0].issubset(in_part) and pair[1].issubset(out_part):
                    pair_try_place = PetriNet.Place(str(pair_try))
                    add_arc_from_to(label_transition_dict[key], pair_try_place,
                                    net)
                    add_arc_from_to(pair_try_place, label_transition_dict[key],
                                    net)
    return net, initial_marking, final_marking
Ejemplo n.º 12
0
def merge(trgt=None, nets=None):
    trgt = trgt if trgt is not None else PetriNet()
    nets = nets if nets is not None else list()
    for net in nets:
        trgt.transitions.update(net.transitions)
        trgt.places.update(net.places)
        trgt.arcs.update(net.arcs)
    return trgt
Ejemplo n.º 13
0
def map_to_PN(auto, region_set):
    '''
    Make Petri net from automaton

    :param auto: automaton to change into petri net
    :return: petri net
    '''

    net = PetriNet("New Net")
    trans_set = set()
    for trans in auto.transitions:
        if trans.name not in trans_set:
            t = PetriNet.Transition(trans.name, trans.name)
            net.transitions.add(t)
            trans_set.add(trans.name)  #add transitions to petri net

    petri_trans_dict = transition_dict(net)
    id = 0
    for region in region_set:
        exit_set = set()
        enter_set = set()
        place = PetriNet.Place(id)  #add places to petri net
        net.places.add(place)
        for event, value in is_region(auto, region)[1].items():
            if value == 100:  # exit
                exit_set.add(event)
            elif value == 1000:  # enter
                enter_set.add(event)
        for t in exit_set:
            petri_utils.add_arc_from_to(place, petri_trans_dict[t], net)
        for tt in enter_set:
            petri_utils.add_arc_from_to(petri_trans_dict[tt], place, net)
        id += 1

    #add final place (optional)
    # final_place = PetriNet.Place(id)
    # net.places.add(final_place)
    # for trans in net.transitions:
    #     if len(trans.out_arcs) < 1:
    #         petri_utils.add_arc_from_to(trans, final_place, net)

    im = discover_initial_marking(net)
    fm = discover_final_marking(net)

    return net, im, fm
Ejemplo n.º 14
0
def add_sink(net, end_activities, label_transition_dict):
    """
    Adding sink pe
    """
    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
Ejemplo n.º 15
0
def add_wait_net(net, wait_label):
    '''
    Words don't have the same length. To compare them we add a "wait" transition at the end of the model and the
    traces.
    :return:
    '''
    wait_transition = PetriNet.Transition(wait_label, wait_label)
    net.transitions.add(wait_transition)
    return wait_transition
Ejemplo n.º 16
0
def add_source(net, start_activities, label_transition_dict):
    """
    Adding source pe
    """
    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
Ejemplo n.º 17
0
def log_to_Pn(traces_xes,size_of_run):
    traces = project_traces(traces_xes)
    petri_of_traces=PetriNet()
    init, end=PetriNet.Place("init"),PetriNet.Place("end")
    [petri_of_traces.places.add(place) for place in [init, end]]
    prec=init
    for t in traces:
        prec=init
        for a in range (0,min(size_of_run,len(t))):
            transition=PetriNet.Transition(t[a]+str(a), t[a])
            petri_of_traces.transitions.add(transition)
            place_suiv=end if a in [size_of_run-1,len(t)-1]  else PetriNet.Place(t[a]+str(a))
            add_arc_from_to(transition, place_suiv, petri_of_traces)
            add_arc_from_to(prec, transition, petri_of_traces)
            prec=place_suiv
    m0=Marking().__add__({init:1})
    mf=Marking().__add__({end:1})
    return petri_of_traces,m0,mf
Ejemplo n.º 18
0
def get_strongly_connected_subnets(net):
    """
    Get the strongly connected components subnets in the Petri net

    Parameters
    -------------
    net
        Petri net

    Returns
    -------------
    strongly_connected_transitions
        List of strongly connected transitions of the Petri net
    """
    import networkx as nx

    graph, inv_dictionary = create_networkx_directed_graph(net)
    sccg = list(nx.strongly_connected_components(graph))
    strongly_connected_subnets = []
    for sg in list(sccg):
        if len(sg) > 1:
            subnet = PetriNet()
            imarking = Marking()
            fmarking = Marking()
            corr = {}
            for node in sg:
                if node in inv_dictionary:
                    if type(inv_dictionary[node]) is PetriNet.Transition:
                        prev_trans = inv_dictionary[node]
                        new_trans = PetriNet.Transition(
                            prev_trans.name, prev_trans.label)
                        corr[node] = new_trans
                        subnet.transitions.add(new_trans)
                    if type(inv_dictionary[node]) is PetriNet.Place:
                        prev_place = inv_dictionary[node]
                        new_place = PetriNet.Place(prev_place.name)
                        corr[node] = new_place
                        subnet.places.add(new_place)
            for edge in graph.edges:
                if edge[0] in sg and edge[1] in sg:
                    add_arc_from_to(corr[edge[0]], corr[edge[1]], subnet)
            strongly_connected_subnets.append([subnet, imarking, fmarking])

    return strongly_connected_subnets
Ejemplo n.º 19
0
def add_wait_net_end(pn, wait_label):
    '''
    Words don't have the same length. To compare them we add a "wait" transition at the end of the model and the
    traces.
    :return:
    '''
    wait_transition = PetriNet.Transition(wait_label, wait_label)
    for place in pn.places:
        if len(place.out_arcs) == 0:
            arcIn = PetriNet.Arc(place, wait_transition)
            arcOut = PetriNet.Arc(wait_transition, place)
            pn.arcs.add(arcIn)
            pn.arcs.add(arcOut)
            wait_transition.in_arcs.add(arcIn)
            wait_transition.out_arcs.add(arcOut)
            place.out_arcs.add(arcIn)
            place.in_arcs.add(arcOut)
    pn.transitions.add(wait_transition)
    return wait_transition
 def __add_wait_net(self):
     '''
     Words don't have the same length. To compare them we add a "wait" transition at the end of the model and the
     traces.
     :return:
     '''
     wait_transition = PetriNet.Transition(WAIT_TRANSITION, WAIT_TRANSITION)
     for place in self.__pn.places:
         if len(place.out_arcs) == 0:
             arcIn = PetriNet.Arc(place, wait_transition)
             arcOut = PetriNet.Arc(wait_transition, place)
             self.__pn.arcs.add(arcIn)
             self.__pn.arcs.add(arcOut)
             wait_transition.in_arcs.add(arcIn)
             wait_transition.out_arcs.add(arcOut)
             place.out_arcs.add(arcIn)
             place.in_arcs.add(arcOut)
     self.__pn.transitions.add(wait_transition)
     return wait_transition
    def create_PetriNet(n):
        # label_set[0] = 'a',...,label_set[26]=z
        label_set = dict(enumerate(string.ascii_lowercase))
        if n >= 26:
            print("N is >= 26 but there are only 26 unique letters.")

        # create new petrinet
        net = PetriNet("PN")

        place_list = []
        # create start and end place
        start = PetriNet.Place("start")
        end = PetriNet.Place("end")
        net.places.add(start)
        net.places.add(end)
        place_list.insert(0, start)
        place_list.insert(n + 1, end)

        # create the rest of n-2 places (n+1 places are needed for a length n trace)
        for i in range(n - 1):
            p = PetriNet.Place(f"p{i}")
            net.places.add(p)
            place_list.insert(i + 1, p)

        transitions_list = []
        # create n transitions
        for i in range(n):
            t = PetriNet.Transition(f"t{i}", label_set[i])
            net.transitions.add(t)
            transitions_list.insert(i, t)

        for i, t in enumerate(transitions_list):
            utils.add_arc_from_to(place_list[i], t, net)
            utils.add_arc_from_to(t, place_list[i + 1], net)

        # defining initial and final marking
        im = Marking()
        im[start] = 1
        fm = Marking()
        fm[end] = 1

        return net, im
Ejemplo n.º 22
0
def construct_trace_net_cost_aware(trace,
                                   costs,
                                   trace_name_key=xes_util.DEFAULT_NAME_KEY,
                                   activity_key=xes_util.DEFAULT_NAME_KEY):
    """
    Creates a trace net, i.e. a trace in Petri net form mapping specific costs to transitions.

    Parameters
    ----------
    trace: :class:`list` input trace, assumed to be a list of events
    costs: :class:`list` list of costs, length should be equal to the length of the input trace
    trace_name_key: :class:`str` key of the attribute that defines the name of the trace
    activity_key: :class:`str` key of the attribute of the events that defines the activity name

    Returns
    -------
    tuple: :class:`tuple` of the net, initial marking, final marking and map of costs


    """
    net = PetriNet('trace net of %s' %
                   trace.attributes[trace_name_key] if trace_name_key in
                   trace.attributes else ' ')
    place_map = {0: PetriNet.Place('p_0')}
    net.places.add(place_map[0])
    cost_map = dict()
    for i in range(0, len(trace)):
        t = PetriNet.Transition('t_' + trace[i][activity_key] + '_' + str(i),
                                trace[i][activity_key])
        # 16/02/2021: set the trace index as property of the transition of the trace net
        t.properties[properties.TRACE_NET_TRANS_INDEX] = i
        cost_map[t] = costs[i]
        net.transitions.add(t)
        place_map[i + 1] = PetriNet.Place('p_' + str(i + 1))
        # 16/02/2021: set the place index as property of the place of the trace net
        place_map[i + 1].properties[properties.TRACE_NET_PLACE_INDEX] = i + 1
        net.places.add(place_map[i + 1])
        add_arc_from_to(place_map[i], t, net)
        add_arc_from_to(t, place_map[i + 1], net)
    return net, Marking({place_map[0]: 1}), Marking({place_map[len(trace)]:
                                                     1}), cost_map
Ejemplo n.º 23
0
def get_initial_marking(net, max_no_comb=4):
    """
    Get the initial marking from a Petri net
    (observing which nodes are without input connection,
    if several nodes exist, then a source place is created artificially)

    Parameters
    -------------
    net
        Petri net

    Returns
    -------------
    net
        Petri net
    initial_marking
        Initial marking of the Petri net
    """
    places = set(net.places)

    places_wo_input = []
    for place in places:
        if len(place.in_arcs) == 0:
            places_wo_input.append(place)
    places_wo_input = list(places_wo_input)

    initial_marking = Marking()

    if len(places_wo_input) > 1:
        source = PetriNet.Place('petri_source')
        net.places.add(source)
        for i in range(len(places_wo_input)):
            htrans = PetriNet.Transition("itrans_" + str(i), None)
            net.transitions.add(htrans)
            utils.add_arc_from_to(source, htrans, net)
            utils.add_arc_from_to(htrans, places_wo_input[i], net)
        initial_marking[source] = 1
    elif len(places_wo_input) == 1:
        places_wo_input = list(places_wo_input)
        initial_marking[places_wo_input[0]] = 1
    return net, initial_marking
Ejemplo n.º 24
0
def __copy_into(source_net, target_net, upper, skip):
    t_map = {}
    p_map = {}
    for t in source_net.transitions:
        name = (t.name, skip) if upper else (skip, t.name)
        label = (t.label, skip) if upper else (skip, t.label)
        t_map[t] = PetriNet.Transition(name, label)
        target_net.transitions.add(t_map[t])

    for p in source_net.places:
        name = (p.name, skip) if upper else (skip, p.name)
        p_map[p] = PetriNet.Place(name)
        target_net.places.add(p_map[p])

    for t in source_net.transitions:
        for a in t.in_arcs:
            add_arc_from_to(p_map[a.source], t_map[t], target_net)
        for a in t.out_arcs:
            add_arc_from_to(t_map[t], p_map[a.target], target_net)

    return t_map, p_map
Ejemplo n.º 25
0
def get_final_marking(net, max_no_comb=4):
    """
    Get the final marking from a Petri net
    (observing which nodes are without output connection,
    if several nodes exist, then a sink place is created artificially)

    Parameters
    -------------
    net
        Petri net

    Returns
    -------------
    net
        Petri net
    final_marking
        Final marking of the Petri net
    """
    places = set(net.places)
    places_wo_output = []
    for place in places:
        if len(place.out_arcs) == 0:
            places_wo_output.append(place)
    places_wo_output = list(places_wo_output)

    final_marking = Marking()
    if len(places_wo_output) > 1:
        sink = PetriNet.Place('petri_sink')
        net.places.add(sink)
        for i in range(len(places_wo_output)):
            htrans = PetriNet.Transition("ftrans_" + str(i), None)
            net.transitions.add(htrans)
            utils.add_arc_from_to(htrans, sink, net)
            utils.add_arc_from_to(places_wo_output[i], htrans, net)
        final_marking[sink] = 1
    elif len(places_wo_output) == 1:
        places_wo_output = list(places_wo_output)
        final_marking[places_wo_output[0]] = 1

    return net, final_marking
Ejemplo n.º 26
0
 def __addWaitTransitions(self, pn, mf):
     '''
     This function add 2 type of wait transitions :
         - log moves
         - model moves
     Those transitions cost.
     :param pn (Petrinet)
     :param mf (Marking)
     '''
     # creates the transitions with labels WAIT_LABEL_TRACE for log moves
     # and WAIT_LABEL_MODEL for model moves
     self.__wait_transition_trace = PetriNet.Transition(
         WAIT_LABEL_TRACE, WAIT_LABEL_TRACE)
     self.__wait_transition_model = PetriNet.Transition(
         WAIT_LABEL_MODEL, WAIT_LABEL_MODEL)
     final_places = [p for p in pn.places if p in mf]
     # WAIT_LABEL_MODEL is added in the Petrinet at the end of the
     # TODO I'm not sure here
     #petri.utils.add_arc_from_to(self.__wait_transition_model, final_places[0], pn)
     #petri.utils.add_arc_from_to(final_places[0],self.__wait_transition_model, pn)
     # add both transitions but notice that WAIT_LABEL_TRACE will be forbidden for the centroids
     self.__transitions.append(self.__wait_transition_trace)
     self.__transitions.append(self.__wait_transition_model)
Ejemplo n.º 27
0
def short_circuit_petri_net(net, print_diagnostics=False):
    """
    Fist, sink and source place are identified. Then, a transition from source to sink is added to short-circuited
    the given petri net. If there is no unique source and sink place, an error gets returned
    :param net: Petri net that is going to be short circuited
    :return:
    """
    s_c_net = copy.deepcopy(net)
    no_source_places = 0
    no_sink_places = 0
    sink = None
    source = None
    for place in s_c_net.places:
        if len(place.in_arcs) == 0:
            source = place
            no_source_places += 1
        if len(place.out_arcs) == 0:
            sink = place
            no_sink_places += 1
    if (sink is not None) and (
            source
            is not None) and no_source_places == 1 and no_sink_places == 1:
        # If there is one unique source and sink place, short circuit Petri Net is constructed
        t_1 = PetriNet.Transition("short_circuited_transition",
                                  "short_circuited_transition")
        s_c_net.transitions.add(t_1)
        # add arcs in short-circuited net
        utils.add_arc_from_to(sink, t_1, s_c_net)
        utils.add_arc_from_to(t_1, source, s_c_net)
        return s_c_net
    else:
        if sink is None:
            if print_diagnostics:
                print("There is no sink place.")
            return None
        elif source is None:
            if print_diagnostics:
                print("There is no source place.")
            return None
        elif no_source_places > 1:
            if print_diagnostics:
                print("There is more than one source place.")
            return None
        elif no_sink_places > 1:
            if print_diagnostics:
                print("There is more than one sink place.")
            return None
Ejemplo n.º 28
0
    def test_52(self):
        # creating an empty Petri net
        from pm4py.objects.petri.petrinet import PetriNet, Marking
        net = PetriNet("new_petri_net")

        # creating source, p_1 and sink place
        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 exporter as pnml_exporter
        pnml_exporter.apply(net, initial_marking, "createdPetriNet1.pnml", final_marking=final_marking)

        from pm4py.visualization.petrinet import visualizer as pn_visualizer
        gviz = pn_visualizer.apply(net, initial_marking, final_marking)

        from pm4py.visualization.petrinet import visualizer as pn_visualizer
        parameters = {pn_visualizer.Variants.WO_DECORATION.value.Parameters.FORMAT: "svg"}
        gviz = pn_visualizer.apply(net, initial_marking, final_marking, parameters=parameters)

        from pm4py.visualization.petrinet import visualizer as pn_visualizer
        parameters = {pn_visualizer.Variants.WO_DECORATION.value.Parameters.FORMAT: "svg"}
        gviz = pn_visualizer.apply(net, initial_marking, final_marking, parameters=parameters)
        pn_visualizer.save(gviz, "alpha.svg")

        os.remove("createdPetriNet1.pnml")
        os.remove("alpha.svg")
Ejemplo n.º 29
0
def _short_circuit_petri_net(net):
    """
    Creates a short circuited Petri net,
    whether an unique source place and sink place are there,
    by connecting the sink with the source

    Parameters
    ---------------
    net
        Petri net

    Returns
    ---------------
    boolean
        Boolean value
    """
    s_c_net = copy.deepcopy(net)
    no_source_places = 0
    no_sink_places = 0
    sink = None
    source = None
    for place in s_c_net.places:
        if len(place.in_arcs) == 0:
            source = place
            no_source_places += 1
        if len(place.out_arcs) == 0:
            sink = place
            no_sink_places += 1
    if (sink is not None) and (
            source
            is not None) and no_source_places == 1 and no_sink_places == 1:
        # If there is one unique source and sink place, short circuit Petri Net is constructed
        t_1 = PetriNet.Transition("short_circuited_transition",
                                  "short_circuited_transition")
        s_c_net.transitions.add(t_1)
        # add arcs in short-circuited net
        pn_utils.add_arc_from_to(sink, t_1, s_c_net)
        pn_utils.add_arc_from_to(t_1, source, s_c_net)
        return s_c_net
    else:
        return None
Ejemplo n.º 30
0
def add_arc_from_to(fr, to, net, weight=1):
    """
    Adds an arc from a specific element to another element in some net. Assumes from and to are in the net!

    Parameters
    ----------
    fr: transition/place from
    to:  transition/place to
    net: net to use
    weight: weight associated to the arc

    Returns
    -------
    None
    """
    a = PetriNet.Arc(fr, to, weight)
    net.arcs.add(a)
    fr.out_arcs.add(a)
    to.in_arcs.add(a)

    return a