def load_vass_from_tts(tts_file, prop_file): vass = None header_read = False with open(tts_file) as input_file: for row in input_file: if "#" in row: row = row[:row.index("#")] data = row.strip() if len(data) == 0: continue if not header_read: num_states, num_loc = tuple(map(int, data.split())) states = {_name_state(i) for i in range(num_states)} vass = VASS(num_loc, states) header_read = True else: transition_type = None for symb in ["->", "+>"]: if symb in data: transition_type = symb break if transition_type is None: error = "Transition type unsupported in: {}".format(data) raise ValueError(error) init, target = data.split(symb) init = tuple(map(int, init.split())) target = tuple(map(int, target.split())) if transition_type == "->": _add_thread_transition(vass, init, target, num_loc) elif transition_type == "+>": _add_spawn_transition(vass, init, target, num_loc) init_state = _name_state(0) # On first state: self loop +1 on first counter vass.add_transition(init_state, Marking.one(num_loc, 0), init_state) # Init configuration init_config = VassConfig(init_state, Marking.one(num_loc, 0)) # Target configuration state_num, loc_nums = _load_config_from_prop(prop_file) init_vector = [0] * num_loc for i in loc_nums: init_vector[i] += 1 target_config = VassConfig(_name_state(state_num), Marking(init_vector)) return (vass, init_config, target_config)
def make_lossy(self, init=None): if init is None: init = (tuple(["="] * self.num_places()), Marking([0] * self.num_places())) target = (tuple([">="] * self.num_places()), Marking([0] * self.num_places())) self._embed_coverability(init, target)
def setUp(self): """ set up unit test environment """ file_path = os.path.join( os.path.dirname(__file__), 'test_resources/TestCase_Milestone_Condition.xml') self.DCRGraph = graph.DCRGraph(file_path) self.InitialMarking = Marking.get_initial_marking()
def remove_omegas(marking, value=0): marking_omegaless = [] for x in marking: if x == float("inf"): marking_omegaless.append(value) else: marking_omegaless.append(x) return Marking(marking_omegaless)
def successors(self, config): succ = set() for t in self._fwd_transitions.get(config.state(), set()): _, update, q = self._transitions[t] new_vector = config.vector() + update if new_vector >= Marking.zeros(len(update)): succ.add(VassConfig(q, new_vector)) return succ
def predecessors(self, config): pred = set() for t in self._bwd_transitions.get(config.state(), set()): p, update, _ = self._transitions[t] new_vector = config.vector() - update if new_vector >= Marking.zeros(len(update)): pred.add(VassConfig(p, new_vector)) return pred
def omega_marking(constrained_marking): comparisons, marking = constrained_marking new_marking = [] for i in range(len(marking)): if comparisons[i] == ">=": new_marking.append(float("inf")) else: new_marking.append(marking[i]) return Marking(new_marking)
def __init__(self, *entries): marking = [] for x in entries[1:]: if any(isinstance(x, t) for t in [list, tuple, Marking]): marking.extend(x) else: marking.append(x) self._state = entries[0] self._marking = Marking(marking)
def take_transition(self, config, transition): p, update, q = self._transitions[transition] if config.state() != p: return None else: new_vector = config.vector() + update if new_vector >= Marking.zeros(self.dim()): return VassConfig(q, new_vector) else: return None
def _add_spawn_transition(vass, init, target, num_loc): init_state, init_loc = init target_state, target_loc = target init_state = _name_state(init_state) target_state = _name_state(target_state) new_state = _name_state(vass.num_states()) vass.add_state(new_state) update = [0] * num_loc update[init_loc] = -1 vass.add_transition(init_state, Marking(update), new_state) if init_loc != target_loc: update[init_loc] = 1 update[target_loc] = 1 else: update[init_loc] = 2 vass.add_transition(new_state, Marking(update), target_state)
def predecessors_upward(self, config): pred = set() for t in self._bwd_transitions.get(config.state(), set()): p, update, _ = self._transitions[t] pre_vector = [] for i in range(len(update)): pre_vector.append(max(0, config.vector()[i] - update[i])) Upward.update(pred, VassConfig(p, Marking(pre_vector))) return pred
def predecessors_upward(self, marking): pred = set() for t in range(self.num_transitions()): pre_marking = [0] * self.num_places() for p in range(self.num_places()): pre, post = self.get_pre(p, t), self.get_post(p, t) pre_marking[p] = max(pre, marking[p] + pre - post) Upward.update(pred, Marking(pre_marking)) return pred
def test_exclude_relation(self): copied_marking = Marking.get_initial_marking() start_node = self.DCRGraph.get_node('Activity0') end_node = self.DCRGraph.get_node('Activity1') exclude_connection = DCRConnection.create_connection( start_node, end_node, ConnectionTypes.exclude) self.assertIsInstance(exclude_connection, Exclude) exclude_connection.perform_transition(copied_marking) self.assertTrue(end_node not in copied_marking.Included) self.assertTrue(end_node in self.InitialMarking.Included)
def _transition_effect(self, transition, reverse=False): trans = self._id_to_transition[transition] p, update, q = self._vass.transitions()[trans] if reverse: p, q = q, p p_place = self._state_to_id[p] q_place = self._state_to_id[q] left = [0] * self._vass.num_states() left[p_place] -= 1 left[q_place] += 1 return Marking(left + list(update))
def fire(self, marking, transition, reverse=False): pre_matrix, post_matrix = self._pre_matrix, self._post_matrix if reverse: pre_matrix, post_matrix = post_matrix, pre_matrix if self._repr_mode == Petri.DENSE: pre_col = pre_matrix[:,transition].getA1() post_col = post_matrix[:,transition].getA1() elif self._repr_mode == Petri.SPARSE: pre_col = pre_matrix.getcol(transition).toarray().flatten() post_col = post_matrix.getcol(transition).toarray().flatten() effect = (pre_col + post_col).tolist() return Marking([marking[i] + effect[i] for i in range(len(marking))])
def test_copy_of_marking(self): deepcopy_test = Marking.get_initial_marking() self.assertNotEqual(self.InitialMarking, deepcopy_test) deepcopy_test.Included.remove(self.DCRGraph.get_node('Activity0')) deepcopy_test.Included.remove(self.DCRGraph.get_node('Activity2')) deepcopy_test.Executed.append(self.DCRGraph.get_node('Activity0')) deepcopy_test.Executed.append(self.DCRGraph.get_node('Activity2')) # Check different lens self.assertEqual(4, len(self.DCRGraph.InitialIncluded)) self.assertEqual(2, len(deepcopy_test.Included)) self.assertEqual(2, len(deepcopy_test.Executed)) self.assertEqual(4, len(self.InitialMarking.Included)) self.assertEqual(0, len(self.InitialMarking.Executed)) self.assertEqual(deepcopy_test.PendingResponse[0], self.InitialMarking.PendingResponse[0])
def add_transition(self, p, update, q): if len(update) != self.dim(): raise ValueError("Expected dimension: {}".format(self.dim())) name = "t" + str(self.num_transitions()) self._transitions[name] = (p, Marking(update), q) succ = self._fwd_transitions.get(p, None) pred = self._bwd_transitions.get(q, None) if succ is not None: succ.add(name) else: self._fwd_transitions[p] = {name} if pred is not None: pred.add(name) else: self._bwd_transitions[q] = {name}
def perform_conformance_checking(trace, ca): """ The perform conformance checking method gets a trace as an input and then simulates the model with the constraints retrieved from the DCR graph. :param ca: The conformance analysis data object that is used for the overall conformance checking :param trace: the trace that is checked within this thread :return: """ marking = Marking.get_initial_marking() trace_conformance_data = TraceConformanceAnalysisData(trace) for event in trace.Events: node = dcr_graph.get_node_by_name(event.EventName) marking.perform_transition_node(node, event, trace_conformance_data) if len(marking.PendingResponse) != 0: for pending in marking.PendingResponse: if pending in marking.Included: trace_conformance_data.add_violating_pending( pending.ActivityName) if trace_conformance_data.HasViolations: ca.append_conformance_data(trace_conformance_data)
def fireable(self, marking, transition, reverse=False): effect = self._transition_effect(transition, reverse) return marking + effect >= Marking.zeros(self.num_places())
def __str__(self): return str(self._state) + Marking.__str__(self._marking)
def _to_constrained_marking(x): comp, marking = zip(*x) return (comp, Marking(marking))