コード例 #1
0
def _is_closed_to_transitions(nodes: [CovNode], trans: [OmegaTransition],
                              set_of_node: {tuple}):
    """
    Recives a set of makrkings(in node format N) and transitions(T) and checks if ↑N =  ↑{N+t: t\in T}
    """
    new_front = []
    for node1 in nodes:
        for tran in trans:
            if tran.is_fireable_from(node1.marking):
                new_mark = tran.apply_on_marking(deepcopy(node1.marking))
                covered = False
                if tuple(new_mark) in set_of_node:
                    covered = True
                else:
                    for node2 in nodes:
                        if all(new_mark <= node2.marking):
                            covered = True
                            continue
                if not covered:
                    new_node = CovNode(new_mark, node1._dim, node1._depth + 1,
                                       node1)
                    new_node.add_transition(tran)
                    new_node.trans_to_fire = len(trans) - 1
                    new_front.append(new_node)
                    # new_front.append([2])

    return new_front
コード例 #2
0
 def _check_ancestors(self, current_node: CovNode):
     accelerated = False
     ance_node = self._accelerate(current_node)
     while ance_node is not None:
         accelerated = True
         current_node.change_parent(ance_node.get_parent())
         if (current_node._depth -
                 ance_node._depth) > self.max_depth_of_acc:
             self.max_depth_of_acc = current_node._depth - ance_node._depth
         current_node._depth = ance_node._depth
         self.delete_node(ance_node)
         ance_node = self._accelerate(current_node)
     return accelerated
コード例 #3
0
ファイル: tree_old.py プロジェクト: IgorKhm/MinCov
    def delete_node(self, node: CovNode, delete_from_verSet=True):
        """
        Deletes a node.
        delete_from_verSet: sometimes we don't need to delete from verSet.
        """
        self.number_of_deleted_nodes += 1
        self._delete_descendants(node)

        if node.get_parent() is not None:
            node.get_parent().delete_child(node)
        self._vertices.remove(node)
        if delete_from_verSet:
            self._verSet.remove(tuple(node.marking))
        if node in self._front:
            self.deleteFromFront(node)
コード例 #4
0
    def reset_vertices(self, root_mark: np.array):
        self._root = CovNode(root_mark, self._dim, 0, None)
        self._vertices = [self._root]
        self._front = [self._root]
        self._verSet = {tuple(self._root.marking)}

        self.max_size = 1
        self.max_size_of_acc = 0
        self.use_of_acc = 0
コード例 #5
0
 def _use_accelerations(self, current_node: CovNode):
     i = len(self._accelerations) - 1
     while i > 0:
         # for i in range(len(self._accelerations)):
         acc = self._accelerations[i]
         # self.num_of_comparisons += 1
         self.num_of_accelaration_tried += 1
         if acc.is_fireable_from(current_node.marking):
             pre_marking = current_node.marking
             current_node.marking = acc.apply_on_marking(
                 current_node.marking)
             if any(pre_marking != current_node.marking):
                 # self._verSet.remove(tuple(pre_marking))
                 # self._verSet.add(tuple(current_node.marking))
                 i = len(self._accelerations) - 1
                 current_node.applyed_acc = True
                 self.use_of_acc += 1
         i -= 1
コード例 #6
0
 def _explore_successor(self, current_node: CovNode):
     new_nodes = current_node.successors_no_duplicates(
         self._petriNet.get_transitions())
     num_children = len(new_nodes)
     self.average_num_of_successors = (self.average_num_of_successors *
                                       (self.count - 1) +
                                       num_children) / self.count
     for i in range(num_children):
         child = new_nodes[num_children - i - 1]
         # We don't want to add vertices with the same marking to verSet.
         # Moreover, it pays off to check if we already discovered some of these marking:
         if tuple(child.marking) in self._verSet:
             current_node.delete_child(child)
             continue
         else:
             self._vertices.append(child)
             self._front.append(child)
             self._verSet.add(tuple(child.marking))
コード例 #7
0
    def _compute_pre_and_incidence_acceleration(self, current_node: CovNode,
                                                ance_node: CovNode):
        """
        Given a node(current_node) and one of its ancestors(ance_node) which is has a smaller marking.
        Finds the the pre and incidence of the acceleration between them.
        :return:
        """
        pre = np.zeros(self._dim)
        incidence = np.zeros(self._dim)

        while current_node != ance_node:
            # Begin - Code for performance tracing #
            # self.num_of_comparisons += 1  # notsure
            # END - Code for performance tracing #

            trans = current_node.get_transitions()
            for i in range(len(trans)):
                tran = trans[len(trans) - i - 1]
                incidence = incidence + tran.get_incidence()

                for p in range(self._dim):
                    if (pre[p] == float("inf")) & (
                        (tran.get_incidence())[p] == float("inf")):
                        pre[p] = 0
                        continue
                    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]

            current_node = current_node.get_parent()

        for p in range(self._dim):
            if incidence[p] < 0:
                pre[p] = float("inf")

        for p in range(self._dim):
            if incidence[p] != 0:
                incidence[p] = float("inf")

        return pre, incidence
コード例 #8
0
ファイル: tree_old.py プロジェクト: IgorKhm/MinCov
    def __init__(self, petri_net: PetriNet, mark: np.array):
        """
        Constructor
        """
        assert (isinstance(petri_net, PetriNet)), "Has to be a Petri Net"

        self._petriNet = petri_net
        self._dim = petri_net.get_dim()
        self._accelerations = np.array([])

        self._root = CovNode(mark, self._dim, 0, None)
        self._vertices = [self._root]  # a list of all the vertices
        self._front = [
            self._root
        ]  # a list of the vertices which still weren't processed
        self._verSet = {
            tuple(self._root.marking)
        }  # A set of all the marks, used to increase speed(hash)

        # Options for the run of generate_cov_tree():
        self.timeout = float("inf")  # The time out for generate_cov_tree()

        self.keep_accelerations = True  # Remember and reuse previous accelerations

        self.use_z3_to_guess_accelerations = False  # Use z3 to try to guess some accelerations before starting for
        self.z3_timeout = 10  # z3_timeout time

        self.check_for_correctness = True  # in the end of generate_cov_tree() preform a few checks for correctness

        # setting the graph traversal:
        self._type_of_graph_traversal = 1
        self.pushFront = self.push_into_front_function()
        self.popFront = self.pop_next_vertex_func()
        self.deleteFromFront = self.remove_from_front_function()

        # Variables for performance:
        self.verbose = False
        self.max_size = 1
        self.max_size_of_acc = 0
        self.use_of_acc = 0
        self.count = 0
        self.max_depth = 0
        self.number_of_deleted_nodes = 0
        self.number_of_deleted_decedents = 0
        self.max_depth_of_acc = 0
        self.average_num_of_successors = 0
        self.num_of_comparisons = 0
        self.average_vertics_size = 1
        self.num_of_accelaration_tried = 0
        self.num_of_rechecks = 0
コード例 #9
0
    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
コード例 #10
0
ファイル: tree_old.py プロジェクト: IgorKhm/MinCov
    def _delete_descendants(self, node: CovNode):
        """
        Deletes all the descendants of a specific node
        Python has a limitation on the depth of recursion.
        Hence we do it with a loop instead of raising the
        limit recursion.
        """
        new_children = node.get_children()
        while len(new_children) != 0:

            child = new_children.pop()
            new_children.extend(child.get_children())

            # Begin - Code for performance #
            self.number_of_deleted_decedents += 1
            self.number_of_deleted_nodes += 1
            # END - Code for performance #
            self._vertices.remove(child)
            self._verSet.remove(tuple(child.marking))
            if child in self._front:
                self.deleteFromFront(child)
コード例 #11
0
    def test_cov_tree_accelerate(self):
        petri = PetriNet(4)
        mark1 = OmegaMarking(np.array([1, 3, 6, float("inf")]))
        node1 = CovNode(mark1, mark1.get_dim())
        mark2 = OmegaMarking(np.array([1, 3, 5, float("inf")]))
        node2 = CovNode(mark2, mark2.get_dim(), node1._depth, node1)

        tr = CovTree(petri, mark1)
        mark0 = OmegaMarking(np.array([0, 2, 5, 0]))
        node0 = CovNode(mark0, mark0.get_dim(), tr.get_root())
        node1.change_parent(node0)
        tr.add_node(node0)
        tr.add_node(node1)
        tr.add_node(node2)
        tr._accelerate(node2, True)
        self.assertTrue(len(tr._accelerations) == 1)
コード例 #12
0
    def test_cov_tree_create_insert_delete(self):
        petri = PetriNet(4)
        mark1 = OmegaMarking(np.array([1, 3, 6, float("inf")]))
        node1 = CovNode(mark1, mark1.get_dim())
        mark2 = OmegaMarking(np.array([1, 3, 5, float("inf")]))
        node2 = CovNode(mark2, mark2.get_dim(), node1._depth, node1)

        tr = CovTree(petri, mark1)
        mark0 = OmegaMarking(np.array([0, 2, 5, 0]))
        node0 = CovNode(mark0, mark0.get_dim(), tr.get_root())
        node1.change_parent(node0)
        tr.add_node(node0)
        tr.add_node(node1)
        tr.add_node(node2)
        #         print(node2.GetMark()._marking)
        self.assertEqual(len(tr.get_vertices()), 4)
        tr.delete_node(node2)
        self.assertEqual(len(tr.get_vertices()), 3)
        tr.delete_node(node0)
        self.assertEqual(len(tr.get_vertices()), 1)
コード例 #13
0
    def check_for_cover(self, target: np.array, root_mark=None):
        if root_mark is not None:
            self.reset_vertices(root_mark)

        start_time = time.time()
        if self.use_z3_to_guess_accelerations:
            self._accelerations = get_accelerations_from_z3(
                self._petriNet.get_transitions(), self._root.marking,
                self.z3_timeout)

        if self._type_of_graph_traversal == GRAPH_TRAVERSALS.get(
                "MOST_TOKEN_FIRST"):
            self._front = []
            heappush(self._front, self._root)

        trans = np.array(self._petriNet.get_transitions())
        num_trans = len(trans)
        self._root.trans_to_fire = num_trans - 1
        while len(self._front) != 0:
            if time.time() - start_time > self.timeout:
                return None
            self.count += 1
            current_node = None
            current_parent_node = self.popFront()

            while 1:
                tran = trans[current_parent_node.trans_to_fire]
                current_parent_node.trans_to_fire -= 1
                # self.num_of_comparisons += 1
                if tran.is_fireable_from(current_parent_node.marking):
                    new_marking = tran.apply_on_marking(
                        current_parent_node.marking)
                    if tuple(new_marking) not in self._verSet:
                        current_node = CovNode(new_marking,
                                               current_parent_node._dim,
                                               current_parent_node._depth + 1,
                                               current_parent_node)
                        current_node.add_transition(tran)
                        current_node.trans_to_fire = num_trans - 1
                        break

                if current_parent_node.trans_to_fire < 0:
                    if len(self._front) != 0:
                        current_parent_node = self.popFront()
                    else:
                        break

            if current_parent_node.trans_to_fire >= 0:
                self.pushFront(current_parent_node)
            if not current_node:
                continue

            if self.keep_accelerations:
                self._use_accelerations(current_node)
            if tuple(current_node.marking) in self._verSet:
                current_parent_node.delete_child(current_node)
                continue

            nodes_to_delete = self._check_if_there_exists_bigger_marking(
                current_node)
            if nodes_to_delete is None:
                current_parent_node.delete_child(current_node)
                continue

            self._vertices.append(current_node)
            self._verSet.add(tuple(current_node.marking))
            self.pushFront(current_node)

            accelarated = self._check_ancestors(current_node)

            self._find_and_delete_smaller(current_node, nodes_to_delete,
                                          accelarated)

            if all(current_node.marking >= target):
                print("------Covered-----------")
                print("V: %d" % len(self._vertices))
                print("time: %f" % (time.time() - start_time))
                print("count: %d" % self.count)
                print("---------------------")
                return True

        print("------Not covered-----------")
        print("V: %d" % len(self._vertices))
        print("time: %f" % (time.time() - start_time))
        print("count: %d" % self.count)
        print("---------------------")

        return False
コード例 #14
0
    def generate_cov_tree(self, root_mark=None):
        if root_mark is not None:
            self.reset_vertices(root_mark)

        if self._type_of_graph_traversal == GRAPH_TRAVERSALS.get(
                "MOST_TOKEN_FIRST"):
            self._front = []
            heappush(self._front, self._root)

        start_time = time.time()
        if self.use_z3_to_guess_accelerations:
            self._accelerations = get_accelerations_from_z3(
                self._petriNet.get_transitions(), self._root.marking,
                self.z3_timeout)

        trans = np.array(self._petriNet.get_transitions())
        num_trans = len(trans)
        self._root.trans_to_fire = num_trans - 1
        clover_is_not_ready = True

        while clover_is_not_ready:

            while len(self._front) != 0:
                if self.timeout < time.time() - start_time:
                    return None
                current_node = None
                current_parent_node = self.popFront()
                while 1:
                    if current_parent_node.trans_to_fire == 0:
                        if len(self._front) != 0:
                            current_parent_node = self.popFront()
                        else:
                            break

                    tran = trans[current_parent_node.trans_to_fire - 1]
                    current_parent_node.trans_to_fire -= 1

                    # Begin - Code for performance tracing #
                    # self.num_of_comparisons += 1
                    # END - Code for performance tracing #

                    if tran.is_fireable_from(current_parent_node.marking):
                        new_marking = tran.apply_on_marking(
                            current_parent_node.marking)
                        if tuple(new_marking) not in self._verSet:
                            current_node = CovNode(
                                new_marking, current_parent_node._dim,
                                current_parent_node._depth + 1,
                                current_parent_node, self.count + 1)
                            current_node.add_transition(tran)
                            current_node.trans_to_fire = num_trans
                            break

                if current_parent_node.trans_to_fire > 0:
                    self.pushFront(current_parent_node)
                if not current_node:
                    continue

                # Begin - Code for performance #
                if (self.count % 1000 == 0) & (self.count != 0):
                    if self.verbose:
                        print("---------------------")
                        print("V: %d" % len(self._vertices))
                        print("Front: %d" % len(self._front))
                        print("acc: %d" % len(self._accelerations))
                        print("acc used: %d" % self.use_of_acc)
                        print("max depth of acc: %d" % self.max_depth_of_acc)
                        print("current depth: %d" % current_node._depth)
                        print("max depth: %d" % self.max_depth)
                        print("num of deleted nodes(not during creation): %d" %
                              self.number_of_deleted_nodes)
                        print("num of deleted decedents: %d" %
                              self.number_of_deleted_decedents)
                        print("average num of successors: %f" %
                              self.average_num_of_successors)
                        print("time: %f" % (time.time() - start_time))
                        print("count: %d" % self.count)
                        print("---------------------")
                    self.count += 1
                else:
                    self.count += 1
                    self.average_vertics_size = (
                        self.average_vertics_size *
                        (self.count - 1) + len(self._vertices)) / self.count
                # End - Code for performance #

                if self.keep_accelerations:
                    self._use_accelerations(current_node)
                if tuple(current_node.marking) in self._verSet:
                    current_parent_node.delete_child(current_node)
                    continue

                nodes_to_delete = self._check_if_there_exists_bigger_marking(
                    current_node)
                if nodes_to_delete is None:
                    current_parent_node.delete_child(current_node)
                    continue

                self._vertices.append(current_node)
                self._verSet.add(tuple(current_node.marking))
                self.pushFront(current_node)

                accelarated = self._check_ancestors(current_node)

                self._find_and_delete_smaller(current_node, nodes_to_delete,
                                              accelarated)

                # Begin - Code for performance #
                if self.max_size < len(self._vertices):
                    self.max_size = len(self._vertices)
                if self.max_size_of_acc < len(self._accelerations):
                    self.max_size_of_acc = len(self._accelerations)
                self.max_depth = max(current_node._depth, self.max_depth)
                # End - Code for performance #

            if self.keep_accelerations:
                clover_is_not_ready = False
            else:
                print(time.time())
                new_front = _is_closed_to_transitions(
                    self._vertices, self._petriNet.get_transitions(),
                    self._verSet)
                print(time.time())
                if len(new_front) == 0:
                    clover_is_not_ready = False
                else:
                    for node in new_front:
                        self.num_of_rechecks += 1
                        self._vertices.append(node)
                        self._verSet.add(tuple(node.marking))
                        self.push_next_vertex(node)

        # Begin - Code for performance #
        if self.max_size > 0:
            print("MAX size of V:  %d" % self.max_size)
            print("MAX size of Acc: %d" % self.max_size_of_acc)
            print("size of V: %d" % len(self._vertices))
            print("size of VerSet: %d" % len(self._verSet))
            print("size of Acc: %d" % len(self._accelerations))
            print("Num of acc used: %d" % self.use_of_acc)
            print("Total time(rounded): %f" % (time.time() - start_time))
            print("max depth: %d" % self.max_depth)
            print("num of deleted nodes(not during creation): %d" %
                  self.number_of_deleted_nodes)
            print("num of deleted decedents: %d" %
                  self.number_of_deleted_decedents)
            print("max depth of acc: %d" % self.max_depth_of_acc)
            print("count: %d" % self.count)
            print("num of comperesions: %d" % self.num_of_comparisons)
            print("average vertices size: %f" % self.average_vertics_size)
            print("num of rechecks : %d" % self.num_of_rechecks)

        # End - Code for performance #

        if self.check_for_correctness:
            self._check_for_correctness()

        return self._vertices
コード例 #15
0
    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)
コード例 #16
0
ファイル: tree_old.py プロジェクト: IgorKhm/MinCov
    def check_for_cover(self, target: np.array, petri_file="", root_mark=None):

        qc_petrinet, qc_init, qc_targets = load_petrinet(petri_file)
        start_time = time.time()
        print("loaded petri")
        solver, variables = build_cpn_solver(qc_petrinet,
                                             None,
                                             qc_targets,
                                             domain='N')
        print("loaded z3 in %f seconds" % (time.time() - start_time))
        _, initial_vars, target_vars = variables
        solver.set("timeout", 100000)

        def coverable(markings):
            return igor_check_cpn_coverability_z3(solver, initial_vars,
                                                  markings)

        if root_mark is not None:
            self.reset_vertices(root_mark)

        # start_time = time.time()
        if self.use_z3_to_guess_accelerations:
            self._accelerations = get_accelerations_from_z3(
                self._petriNet.get_transitions(), self._root.marking,
                self.z3_timeout)

        if self._type_of_graph_traversal == GRAPH_TRAVERSALS.get(
                "MOST_TOKEN_FIRST"):
            self._front = []
            heappush(self._front, self._root)

        trans = np.array(self._petriNet.get_transitions())
        num_trans = len(trans)
        self._root.trans_to_fire = num_trans - 1
        if not coverable([self._root.marking]):
            self.deleteFromFront(self._root)

        while len(self._front) != 0:
            if time.time() - start_time > self.timeout:
                return None
            self.count += 1
            current_node = None
            current_parent_node = self.popFront()

            while 1:
                tran = trans[current_parent_node.trans_to_fire]
                current_parent_node.trans_to_fire -= 1
                if tran.is_fireable_from(current_parent_node.marking):
                    new_marking = tran.apply_on_marking(
                        current_parent_node.marking)
                    if tuple(new_marking) not in self._verSet:
                        current_node = CovNode(new_marking,
                                               current_parent_node._dim,
                                               current_parent_node._depth + 1,
                                               current_parent_node)
                        current_node.add_transition(tran)
                        current_node.trans_to_fire = num_trans - 1
                        break

                if current_parent_node.trans_to_fire < 0:
                    if len(self._front) != 0:
                        current_parent_node = self.popFront()
                    else:
                        break

            if current_parent_node.trans_to_fire >= 0:
                self.pushFront(current_parent_node)
            if not current_node:
                continue

            if self.keep_accelerations:
                self._use_accelerations(current_node)
            if tuple(current_node.marking) in self._verSet:
                current_parent_node.delete_child(current_node)
                continue

            nodes_to_delete = self._check_if_there_exists_bigger_marking(
                current_node)
            if nodes_to_delete is None:
                current_parent_node.delete_child(current_node)
                continue

            self._vertices.append(current_node)
            self._verSet.add(tuple(current_node.marking))
            self.pushFront(current_node)

            accelarated = self._check_ancestors(current_node)

            self._find_and_delete_smaller(current_node, nodes_to_delete,
                                          accelarated)

            if self.count % 100 == 0:
                if not coverable([current_node.marking]):
                    self.deleteFromFront(current_node)

            if all(current_node.marking >= target):
                print("------Covered-----------")
                print("V: %d" % len(self._vertices))
                print("time: %f" % (time.time() - start_time))
                print("count: %d" % self.count)
                print("---------------------")
                return True

        print("------Not covered-----------")
        print("V: %d" % len(self._vertices))
        print("time: %f" % (time.time() - start_time))
        print("count: %d" % self.count)
        print("---------------------")

        return False