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
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
def apply_playout(net, initial_marking, no_traces=100, max_trace_length=100, case_id_key=xes_constants.DEFAULT_TRACEID_KEY, activity_key=xes_constants.DEFAULT_NAME_KEY, timestamp_key=xes_constants.DEFAULT_TIMESTAMP_KEY, final_marking=None, smap=None, log=None, return_visited_elements=False): """ Do the playout of a Petrinet generating a log Parameters ---------- net Petri net to play-out initial_marking Initial marking of the Petri net no_traces Number of traces to generate max_trace_length Maximum number of events per trace (do break) case_id_key Trace attribute that is the case ID activity_key Event attribute that corresponds to the activity timestamp_key Event attribute that corresponds to the timestamp final_marking If provided, the final marking of the Petri net smap Stochastic map log Log """ if final_marking is None: # infer the final marking from the net final_marking = final_marking_discovery.discover_final_marking(net) if smap is None: if log is None: raise Exception("please provide at least one between stochastic map and log") smap = replay.get_map_from_log_and_net(log, net, initial_marking, final_marking, parameters={Parameters.ACTIVITY_KEY: activity_key, Parameters.TIMESTAMP_KEY: timestamp_key}) # assigns to each event an increased timestamp from 1970 curr_timestamp = 10000000 all_visited_elements = [] for i in range(no_traces): visited_elements = [] visible_transitions_visited = [] marking = copy(initial_marking) while len(visible_transitions_visited) < max_trace_length: visited_elements.append(marking) if not semantics.enabled_transitions(net, marking): # supports nets with possible deadlocks break all_enabled_trans = semantics.enabled_transitions(net, marking) if final_marking is not None and marking == final_marking: en_t_list = list(all_enabled_trans.union({None})) else: en_t_list = list(all_enabled_trans) trans = stochastic_utils.pick_transition(en_t_list, smap) if trans is None: break visited_elements.append(trans) if trans.label is not None: visible_transitions_visited.append(trans) marking = semantics.execute(trans, net, marking) all_visited_elements.append(tuple(visited_elements)) if return_visited_elements: return all_visited_elements log = log_instance.EventLog() for index, visited_elements in enumerate(all_visited_elements): trace = log_instance.Trace() trace.attributes[case_id_key] = str(index) for element in visited_elements: if type(element) is PetriNet.Transition and element.label is not None: event = log_instance.Event() event[activity_key] = element.label event[timestamp_key] = datetime.datetime.fromtimestamp(curr_timestamp) trace.append(event) # increases by 1 second curr_timestamp += 1 log.append(trace) return log
def import_net(input_file_path, return_stochastic_information=False, parameters=None): """ Import a Petri net from a PNML file Parameters ---------- input_file_path Input file path return_stochastic_information Enables return of stochastic information if found in the PNML parameters Other parameters of the algorithm """ if parameters is None: parameters = {} tree = etree.parse(input_file_path) root = tree.getroot() net = petri.petrinet.PetriNet('imported_' + str(time.time())) marking = petri.petrinet.Marking() fmarking = petri.petrinet.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: place_id = child.get("id") place_name = place_id number = 0 for child2 in child: if "name" in child2.tag: for child3 in child2: if child3.text: place_name = child3.text if "initialMarking" in child2.tag: for child3 in child2: if child3.tag == "text": number = int(child3.text) places_dict[place_id] = petri.petrinet.PetriNet.Place(place_id) net.places.add(places_dict[place_id]) if number > 0: marking[places_dict[place_id]] = number del place_name if page is not None: for child in page: if "transition" in child.tag: trans_name = child.get("id") trans_label = trans_name trans_visible = True random_variable = None for child2 in child: if child2.tag == "name": for child3 in child2: if child3.text: if trans_label == trans_name: trans_label = child3.text if "toolspecific" in child2.tag: 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) if return_stochastic_information: 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] = petri.petrinet.PetriNet.Transition( trans_name, trans_label) net.transitions.add(trans_dict[trans_name]) if random_variable is not None: stochastic_information[ trans_dict[trans_name]] = random_variable if page is not None: for child in page: if "arc" in child.tag: arc_source = child.get("source") arc_target = child.get("target") arc_weight = 1 for arc_child in child: if "inscription" in arc_child.tag: for text_arcweight in arc_child: if "text" in text_arcweight.tag: arc_weight = int(text_arcweight.text) if arc_source in places_dict and arc_target in trans_dict: petri.utils.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: petri.utils.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 "text" in child3.tag: 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) if return_stochastic_information and len( list(stochastic_information.keys())) > 0: return net, marking, fmarking, stochastic_information return net, marking, fmarking
def import_net(input_file_path, parameters=None): """ Import a Petri net from a PNML file Parameters ---------- input_file_path Input file path parameters Other parameters of the algorithm """ if parameters is None: parameters = {} parser = etree.XMLParser(remove_comments=True) tree = objectify.parse(input_file_path, parser=parser) root = tree.getroot() 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