def test_cov_node(self): """ Testing basic properties of cov_node """ mark1 = OmegaMarking(np.array([1, 2, 3, float("inf")])) with self.assertRaises(Exception): CovNode(1, 2, 3) with self.assertRaises(Exception): CovNode(mark1, 8) node1 = CovNode(mark1, mark1.get_dim()) mark_false = OmegaMarking(np.array([1, 2, 3, float("inf"), 5])) with self.assertRaises(Exception): CovNode(mark_false, 5, 0, node1) mark2 = OmegaMarking(np.array([1, 2, 5, float("inf")])) node2 = CovNode(mark2, mark2.get_dim(), node1._depth, node1) mark0 = OmegaMarking(np.array([0, 2, 5, 0])) node0 = CovNode(mark0, mark0.get_dim()) node1.change_parent(node0) trans = [ OmegaTransition(np.array([1, 2, 3, 5]), np.array([1, 4, 3, -5])), OmegaTransition(np.array([1, float("inf"), 3, 5]), np.array([2, 3, 3, -5])), OmegaTransition(np.array([1, 1, 2, 5]), np.array([5, 5, float("inf"), 8])) ] node2.successors(trans) self.assertEqual(len(node2.get_children()), 2) node1.delete_child(node2) self.assertEqual(len(node1.get_children()), 0)
def test_petri_net(self): """ Testting basic properties of petri net """ with self.assertRaises(Exception): PetriNet(0.5) with self.assertRaises(Exception): PetriNet(0) mark1 = OmegaMarking(np.array([1, 2, 3, float("inf")])) mark2 = OmegaMarking(np.array([1, 2, 3, float("inf"), 5])) tran1 = OmegaTransition(np.array([1, 2, 3, 5]), np.array([1, 4, 3, -5])) tran2 = OmegaTransition(np.array([1, float("inf"), 3, 5]), np.array([2, 3, 3, -5])) tran3 = OmegaTransition(np.array([1, float("inf"), 2, 5]), np.array([5, 5, float("inf"), -5])) petri = PetriNet(4) with self.assertRaises(Exception): petri.mark_the_petri_net(mark2) petri.mark_the_petri_net(mark1) petri.add_transition(tran1) petri.add_transition(tran2) petri.add_transition(tran3) self.assertEqual(len(petri.get_transitions()), 3)
def single_successor(self, tran: OmegaTransition): if tran.is_fireable_from(self.marking): child_mark = deepcopy(self.marking) child = CovNode(child_mark.fire_transition(tran), self._dim, self._depth + 1, self) child.add_transition(tran) return child return None
def _accelerate(self, current_node: CovNode): """ Tries to accelerate the marking of the current node according to its ancestors :return: If accelerated return the father of the ancestor that we accelerated from, otherwise return None """ ancestor_node = current_node.get_parent() while ancestor_node is not None: # Begin - Code for performance tracing # # self.num_of_comparisons += 1 # END - Code for performance tracing # if all(current_node.marking >= ancestor_node.marking): current_node.applyed_acc = True # about to change the marking, hence need to get it out of the set self._verSet.remove(tuple(current_node.marking)) if self.keep_accelerations: # If using the new algorithm then we create an acceleration for further use: (pre, incidence) = self._compute_pre_and_incidence_acceleration( current_node, ancestor_node) acc = OmegaTransition(pre, incidence) self._add_acceleration(acc) current_node.marking = acc.apply_on_marking( current_node.marking) current_node._tranFromParent = ancestor_node.get_transitions( ) current_node.add_transition(acc) self._verSet.add(tuple(current_node.marking)) else: # If using Alain's Finkel original algorithm then just accelerate: acc = np.where( current_node.marking > ancestor_node.marking, (float("inf")), 0) current_node.marking = current_node.marking + acc self._verSet.add(tuple(current_node.marking)) return ancestor_node ancestor_node = ancestor_node.get_parent() return None
def load_petri_net_from_pnml(filename): places_names = [] transitions_names = [] pre_transitions = [] incidence_transitions = [] init_marking = [] tree = ET.parse(filename) root = tree.getroot() net = root.find("{http://www.pnml.org/version-2009/grammar/pnml}net").find( "{http://www.pnml.org/version-2009/grammar/pnml}page") for place in net.iter( '{http://www.pnml.org/version-2009/grammar/pnml}place'): places_names.append(place.attrib["id"]) init = place.find( "{http://www.pnml.org/version-2009/grammar/pnml}initialMarking") if init is None: init_marking.append(0) else: i = init.find( "{http://www.pnml.org/version-2009/grammar/pnml}text").text init_marking.append(int(i)) dim = len(places_names) for tran in net.iter( '{http://www.pnml.org/version-2009/grammar/pnml}transition'): transitions_names.append(tran.attrib["id"]) pre_transitions.append(numpy.zeros(dim)) incidence_transitions.append(numpy.zeros(dim)) for arc in net.iter('{http://www.pnml.org/version-2009/grammar/pnml}arc'): source = arc.attrib["source"] target = arc.attrib["target"] if source in places_names: p = places_names.index(source) t = transitions_names.index(target) pre_transitions[t][p] += 1 else: p = places_names.index(target) t = transitions_names.index(source) incidence_transitions[t][p] += 1 petri_net = PetriNet(dim) petri_net.mark_the_petri_net(OmegaMarking(np.array(init_marking))) for i in range(len(transitions_names)): petri_net.add_transition( OmegaTransition(pre_transitions[i], incidence_transitions[i])) return petri_net
def from_solution_to_acceleration(sol, trans_var, trans: [OmegaTransition], dim): fired_trans = [0] * len(trans) for i in range(len(trans_var)): fired_trans[i] = sol[trans_var[i]].as_long() pre = np.zeros(dim) incidence = np.zeros(dim) # index_trans = [] # for i in range(len(trans_var)): # index_trans.append(i) # random.shuffle(index_trans) # for i in index_trans: # tran = trans[i] # for j in range(fired_trans[i]): # incidence = incidence + tran.get_incidence() # for p in range(dim): # if pre[p] - (tran.get_incidence())[p] < (tran.get_pre())[p]: # pre[p] = (tran.get_pre())[p] # else: # pre[p] = pre[p] - (tran.get_incidence())[p] # for p in range(dim): # if incidence[p] < 0: # pre[p] = float("inf") # if incidence[p] > 0: # incidence[p] = float("inf") to_fire = [] for t in range(len(fired_trans)): if fired_trans[t] > 0: to_fire.append([t, fired_trans[t]]) while to_fire: n = np.random.randint(0, len(to_fire)) t = to_fire[n][0] to_fire[n][1] -= 1 if to_fire[n][1] == 0: to_fire.remove(to_fire[n]) tran = trans[t] incidence = incidence + tran.get_incidence() for p in range(dim): if pre[p] - (tran.get_incidence())[p] < (tran.get_pre())[p]: pre[p] = (tran.get_pre())[p] else: pre[p] = pre[p] - (tran.get_incidence())[p] for p in range(dim): if incidence[p] < 0: pre[p] = float("inf") if incidence[p] > 0: incidence[p] = float("inf") return OmegaTransition(pre, incidence)
def test_transitions(self): """ Testting basic properties of transitions """ # Checking transitoin creation exceptions(diff dim for pre and post, # C+Pre < 0 with self.assertRaises(Exception): OmegaTransition(np.array([1, 2, 3, 5, 6]), np.array([1, 4, 3, -1])) with self.assertRaises(Exception): OmegaTransition(np.array([1, 2, 3, 5]), np.array([1, 4, 3, -20])) # Loading test data tran1 = OmegaTransition(np.array([1, 2, 3, 5]), np.array([1, 4, 3, -5])) tran2 = OmegaTransition(np.array([1, float("inf"), 3, 5]), np.array([2, 3, 3, -5])) tran3 = OmegaTransition(np.array([1, float("inf"), 2, 5]), np.array([5, 5, float("inf"), -5])) # Checking oreder and equality self.assertNotEqual(tran1, tran2) self.assertEqual(tran1, tran1) self.assertGreaterEqual(tran3, tran2) self.assertFalse((tran1 >= tran2) | (tran1 <= tran2))
def add_transition(petri_net, places, rule): pos = rule.find('->') guards_str = rule[:pos] updates_str = rule[pos + 2:] guards = {} updates = {} # Parse guards for guard in guards_str.split(','): var, value = guard.split('>=') guards[var.strip()] = int(value) # Parse updates for update in updates_str.split(','): match = re.search('\s*(.*)\'\s*=\s*(.*)\s*(\+|-)\s*(.*)\s*', update) # xi' = xj {+,-} value if match is not None: var_in = match.group(1).strip() var_out = match.group(2).strip() value = int(match.group(3) + match.group(4)) if var_in != var_out: raise ValueError('x_i\' = x_j + c illegal with i != j') updates[var_in] = value # Add transition pre_vec = numpy.zeros(len(places)) incidence_vec = numpy.zeros(len(places)) for p in range(len(places)): guard = guards[places[p]] if places[p] in guards else 0 update = updates[places[p]] if places[p] in updates else 0 pre, incidence = guard, update # Add value to sparse matrix if necessary if pre != 0: pre_vec[p] = pre if incidence != 0: incidence_vec[p] = incidence petri_net.add_transition(OmegaTransition(pre_vec, incidence_vec))
def test_banana_land(self): petri = PetriNet(6) # Adding transitions: petri.add_transition( OmegaTransition(np.array([1, 0, 0, 0, 0, 0]), np.array([-1, 1, 1, 0, 0, 0]))) petri.add_transition( OmegaTransition(np.array([1, 0, 0, 0, 0, 0]), np.array([-1, 1, 0, 1, 0, 0]))) petri.add_transition( OmegaTransition(np.array([1, 0, 0, 0, 0, 0]), np.array([-1, 0, 1, 1, 0, 0]))) petri.add_transition( OmegaTransition(np.array([0, 1, 0, 0, 0, 0]), np.array([0, 0, 0, 0, 1, 0]))) petri.add_transition( OmegaTransition(np.array([0, 0, 0, 1, 0, 0]), np.array([0, 0, 0, -1, 0, 1]))) petri.add_transition( OmegaTransition(np.array([0, 0, 1, 0, 1, 0]), np.array([0, 0, 0, 0, -1, 1]))) # Marking the net: petri.mark_the_petri_net(OmegaMarking(np.array([1, 0, 0, 0, 0, 0]))) # Initializing the tree: cov_tree = CovTree(petri, petri.get_mark()) anti_chain = cov_tree.generate_cov_tree(True) self.assertEqual(len(anti_chain), 4) markings = [] for node in anti_chain: markings.append(node.get_mark()) self.assertTrue(OmegaMarking(np.array([1, 0, 0, 0, 0, 0])) in markings) self.assertTrue( OmegaMarking(np.array([0, 1, 1, 0, float("inf"), float("inf")])) in markings) self.assertTrue( OmegaMarking(np.array([0, 1, 0, 1, float("inf"), 0])) in markings) self.assertTrue(OmegaMarking(np.array([0, 0, 1, 1, 0, 0])) in markings) self.assertTrue(len(cov_tree._accelerations) == 2)
def test_Alain_2005(self): petri = PetriNet(7) # Adding transitoins: petri.add_transition( OmegaTransition(np.array([1, 0, 0, 0, 0, 0, 0]), np.array([-1, 1, 0, 0, 0, 0, 0]))) petri.add_transition( OmegaTransition(np.array([1, 0, 0, 0, 0, 0, 0]), np.array([-1, 0, 0, 0, 0, 0, 1]))) petri.add_transition( OmegaTransition(np.array([1, 0, 0, 0, 0, 0, 0]), np.array([-1, 0, 0, 0, 0, 1, 0]))) petri.add_transition( OmegaTransition(np.array([0, 0, 0, 0, 0, 1, 0]), np.array([0, 0, 0, 1, 2, -1, 0]))) petri.add_transition( OmegaTransition(np.array([0, 1, 0, 0, 0, 0, 0]), np.array([0, -1, 1, 0, 0, 0, 0]))) petri.add_transition( OmegaTransition(np.array([0, 0, 1, 0, 0, 0, 0]), np.array([0, 0, -1, 1, 0, 0, 0]))) petri.add_transition( OmegaTransition(np.array([0, 0, 0, 1, 0, 0, 0]), np.array([0, 0, 1, -1, 1, 0, 0]))) petri.add_transition( OmegaTransition(np.array([0, 0, 0, 0, 0, 0, 1]), np.array([0, 1, 0, 0, 1, 0, -1]))) # Marking the net: petri.mark_the_petri_net(OmegaMarking(np.array([1, 0, 0, 0, 0, 0, 0]))) # Initializing the tree: cov_tree = CovTree(petri, petri.get_mark()) anti_chain = cov_tree.generate_cov_tree() self.assertEqual(len(anti_chain), 6)
def add_transition(self, tran: OmegaTransition): assert (tran.get_dim() == self._dim) self._transitions.append(tran)