Esempio n. 1
0
def clean_token_flood(net, prev_marking, curr_marking, t, remaining_activities,
                      current_remaining_map):
    """
    Cleans the token flood

    Parameters
    ------------
    net
        Petri net
    prev_marking
        Previous marking of the Petri net
    curr_marking
        Current marking of the Petri net
    t
        Transition that is fired with missing problems
    remaining_activities
        Remaining activities of the trace
    current_remaining_map
        Map of remaining tokens (to avoid losing them)

    Returns
    ------------
    curr_marking
        Cleaned marking
    current_remaining_map
        Map of remaining tokens (to avoid losing them)
    """
    for place in prev_marking:
        if place in curr_marking:
            curr_marking_wo_place = copy(curr_marking)
            if place in curr_marking_wo_place:
                del curr_marking_wo_place[place]
            en_t_in_curr_marking = set([
                x for x in semantics.enabled_transitions(net, curr_marking)
                if x.label
            ])
            en_t_in_curr_m_wo_place = set([
                x for x in semantics.enabled_transitions(
                    net, curr_marking_wo_place) if x.label
            ])
            en_t_in_curr_marking = en_t_in_curr_marking - en_t_in_curr_m_wo_place
            en_t_in_curr_marking = en_t_in_curr_marking.intersection(
                remaining_activities)
            if len(en_t_in_curr_marking) == 0:
                if place not in current_remaining_map:
                    current_remaining_map[place] = 0
                current_remaining_map[
                    place] = current_remaining_map[place] + curr_marking[place]
                del curr_marking[place]
    return curr_marking, current_remaining_map
Esempio n. 2
0
def get_visible_transitions_eventually_enabled_by_marking(net, marking):
    """
    Get visible transitions eventually enabled by marking (passing possibly through hidden transitions)
    Parameters
    ----------
    net
        Petri net
    marking
        Current marking
    """
    all_enabled_transitions = sorted(list(
        semantics.enabled_transitions(net, marking)),
                                     key=lambda x: (str(x.name), id(x)))
    initial_all_enabled_transitions_marking_dictio = {}
    all_enabled_transitions_marking_dictio = {}
    for trans in all_enabled_transitions:
        all_enabled_transitions_marking_dictio[trans] = marking
        initial_all_enabled_transitions_marking_dictio[trans] = marking
    visible_transitions = set()
    visited_transitions = set()

    i = 0
    while i < len(all_enabled_transitions):
        t = all_enabled_transitions[i]
        marking_copy = copy(all_enabled_transitions_marking_dictio[t])

        if repr([t, marking_copy]) not in visited_transitions:
            if t.label is not None:
                visible_transitions.add(t)
            else:
                if semantics.is_enabled(t, net, marking_copy):
                    new_marking = semantics.execute(t, net, marking_copy)
                    new_enabled_transitions = sorted(list(
                        semantics.enabled_transitions(net, new_marking)),
                                                     key=lambda x:
                                                     (str(x.name), id(x)))
                    for t2 in new_enabled_transitions:
                        all_enabled_transitions.append(t2)
                        all_enabled_transitions_marking_dictio[
                            t2] = new_marking
            visited_transitions.add(repr([t, marking_copy]))
        i = i + 1

    return visible_transitions
def make_enabledlog_alphaminer(log_file_path, output_file_name):
    '''
    Convert XES to XES++ based on alpha miner (event log with enabled activities)
    (for test)

    Parameters
    ----------
    log_file_path
        log's file path to be changed into XES++

    output_file_name
        output file (XES++)'s name

    '''

    log = xes_importer.import_log(log_file_path)
    net, initial_marking, final_marking = alpha_miner.apply(log)

    doc = ET.parse(log_file_path)
    root = doc.getroot()

    for glob in root.iter("global"):
        if glob.attrib["scope"] == "event":
            enabled = ET.SubElement(glob, "string")
            enabled.set("key", "enabled")
            enabled.set("value", "enabled")

    for trace in root.iter("trace"):
        m = ini.discover_initial_marking(net)
        for event in trace.iter("event"):
            for string in event.iter("string"):
                if string.attrib["key"] == "concept:name":
                    act = string.attrib["value"]  # act: current activity in the event log
                    break
            for trans in net.transitions:
                if act == trans.label:
                    t = trans
                    break
            en = semantics.enabled_transitions(net, m)
            enabled = ET.SubElement(event, "string")
            enabled.set("key", "enabled")
            enabled.set("value", en) #write on the XES file
            if m == final_marking:
                break
            m = semantics.execute(t, net, m)


    doc.write(output_file_name, encoding="utf-8", xml_declaration=True)
Esempio n. 4
0
def __calculate_prefix_alignment_for_next_event(process_net,
                                                sync_net,
                                                initial_marking,
                                                final_marking,
                                                marking_after_prefix_alignment,
                                                cost_function,
                                                skip,
                                                prefix_alignment,
                                                trace,
                                                activity_key,
                                                window_size,
                                                debug_print=False):
    start_time = time.time()
    event_to_align = trace[len(trace) - 1]

    activity_name = event_to_align.get_dict()[activity_key]
    if debug_print:
        print("Next Event: ", activity_name)

    if window_size > 0:
        prefix_alignment_reverted = []
        marking_after_prefix_alignment = initial_marking
        cost_so_far = 0
        upper_limit_for_search = 1999

        if len(prefix_alignment) > 0:
            upper_limit_for_search = prefix_alignment[-1]['cost_so_far'] + 1999
            # revert prefix alignment by window size
            prefix_alignment_reverted = prefix_alignment[:-window_size]
            if len(prefix_alignment_reverted) > 0:
                marking_after_prefix_alignment = prefix_alignment_reverted[-1][
                    "marking_after_transition"]
                cost_so_far = prefix_alignment_reverted[-1]['cost_so_far']
                # cost for log move = 1000 plus 999 to allow to execute 999 times arbitrary silent transitions
            else:
                marking_after_prefix_alignment = initial_marking
                cost_so_far = 0

        if debug_print:
            print("START FROM SCRATCH Reverted Marking")
            gviz = petri_net_visualization_factory.apply(
                sync_net,
                marking_after_prefix_alignment,
                final_marking,
                parameters={
                    'debug': True,
                    "format": "svg"
                })
            petri_net_visualization_factory.view(gviz)
        res = __search(sync_net,
                       marking_after_prefix_alignment,
                       final_marking,
                       cost_function,
                       skip,
                       cost_so_far,
                       upper_limit_for_search=upper_limit_for_search)
        return {
            'alignment': prefix_alignment_reverted + res['alignment'],
            'cost': res['cost'],
            'visited_states': res['visited_states'],
            'queued_states': res['queued_states'],
            'traversed_arcs': res['traversed_arcs'],
            'total_computation_time': time.time() - start_time,
            'heuristic_computation_time': res['heuristic_computation_time'],
            'number_solved_lps': res['number_solved_lps']
        }

    if len(prefix_alignment) > 0:
        cost_so_far = prefix_alignment[-1]['cost_so_far']
        upper_limit_for_search = prefix_alignment[-1]['cost_so_far'] + 1999
    else:
        cost_so_far = 0
        upper_limit_for_search = math.inf

    # check if there is a model move/ synchronous move transition that is labelled equally to event_to_align
    for t in process_net.transitions:
        if t.label == activity_name:
            # there is a corresponding transition in the process net

            synchronous_move_transition = None
            for t_s in sync_net.transitions:
                if t_s.label[0] == t_s.label[1] == activity_name and \
                        t_s in enabled_transitions(sync_net, marking_after_prefix_alignment):
                    # there is a corresponding activated synchronous move transition in the synchronous product net
                    synchronous_move_transition = t_s
                    break

            if synchronous_move_transition:
                # ADD SYNCHRONOUS MOVE
                if debug_print:
                    print("ADD SYNCHRONOUS MOVE ")
                new_marking = petri.semantics.execute(
                    synchronous_move_transition, sync_net,
                    marking_after_prefix_alignment)

                cost_of_synchronous_move = cost_function[
                    synchronous_move_transition]
                if len(prefix_alignment) > 0:
                    cost_prefix_alignment = cost_so_far + cost_of_synchronous_move
                else:
                    # first step in alignment
                    cost_prefix_alignment = cost_of_synchronous_move
                    # add sync move to alignment
                prefix_alignment = prefix_alignment + [{
                    "marking_before_transition":
                    marking_after_prefix_alignment,
                    "label":
                    synchronous_move_transition.label,
                    "name":
                    synchronous_move_transition.name,
                    "cost_so_far":
                    cost_so_far + cost_function[synchronous_move_transition],
                    "marking_after_transition":
                    new_marking
                }]
                return {
                    'alignment': prefix_alignment,
                    'cost': cost_prefix_alignment,
                    'visited_states': 0,
                    'queued_states': 0,
                    'traversed_arcs': 0,
                    'total_computation_time': time.time() - start_time,
                    'heuristic_computation_time': 0,
                    'number_solved_lps': 0
                }
            else:
                # USE A* TO FIND NEW OPTIMAL ALIGNMENT
                if debug_print:
                    print("START FROM SCRATCH -> A*")
                res = __search(sync_net,
                               initial_marking,
                               final_marking,
                               cost_function,
                               skip,
                               0,
                               upper_limit_for_search=upper_limit_for_search)
                return {
                    'alignment': res['alignment'],
                    'cost': res['cost'],
                    'visited_states': res['visited_states'],
                    'queued_states': res['queued_states'],
                    'traversed_arcs': res['traversed_arcs'],
                    'total_computation_time': time.time() - start_time,
                    'heuristic_computation_time':
                    res['heuristic_computation_time'],
                    'number_solved_lps': res['number_solved_lps']
                }
    # no corresponding transition found -> ADD LOG MOVE
    if debug_print:
        print("ADD LOG MOVE")
    for t in sync_net.transitions:
        if is_log_move(t, skip) and t.label[0] == activity_name and \
                petri.semantics.is_enabled(t, sync_net, marking_after_prefix_alignment):
            new_marking = petri.semantics.execute(
                t, sync_net, marking_after_prefix_alignment)
            prefix_alignment = prefix_alignment + [
                {
                    "marking_before_transition":
                    marking_after_prefix_alignment,
                    "label": t.label,
                    "name": t.name,
                    "cost_so_far": 1000 + cost_so_far,
                    "marking_after_transition": new_marking
                }
            ]
            return {
                'alignment': prefix_alignment,
                'cost': 1000 + cost_so_far,
                'visited_states': 0,
                'queued_states': 0,
                'traversed_arcs': 0,
                'total_computation_time': time.time() - start_time,
                'heuristic_computation_time': 0,
                'number_solved_lps': 0
            }

    raise Exception('No corresponding log move transition found in sync net')