def __init__(self, star, mode, transition_index):
        assert isinstance(mode, LinearAutomatonMode)

        self.settings = star.settings
        self.mode = mode
        self.inputs = star.inputs

        self.star = star
        self.transition = mode.transitions[transition_index]
        self.num_output_vars = self.transition.guard_matrix_csr.shape[1]

        self.key_dir_offset = 0

        if self.settings.plot.plot_mode != PlotSettings.PLOT_NONE:
            if self.settings.plot.xdim_dir is not None:
                self.key_dir_offset += 1

            if self.settings.plot.ydim_dir is not None:
                self.key_dir_offset += 1

        self.lpi = LpInstance(self.num_output_vars, star.num_init_vars,
                              self.inputs)

        self.lpi.set_init_constraints(star.init_mat, star.init_rhs)
        self.lpi.set_output_constraints(self.transition.guard_matrix_csr,
                                        self.transition.guard_rhs)

        if star.inputs > 0:
            self.lpi.set_input_constraints_csc(
                csc_matrix(star.mode.u_constraints_csr),
                star.mode.u_constraints_rhs)

        self.optimized_lp_solution = None

        self.freeze_attrs()
Beispiel #2
0
    def test_damping(self):
        'test based on damping dynamics'

        lp = LpInstance(1, 1)
        basis = np.array([[0.5]], dtype=float)
        lp.update_basis_matrix(basis)

        lp.add_basis_constraint(np.array([1.0], dtype=float), 1.0)
        lp.add_basis_constraint(np.array([-1.0], dtype=float), -1.0)

        res = np.zeros(2)
        lp.minimize(np.array([0], dtype=float), res)

        self.assertLess(res[0], 1.0)
Beispiel #3
0
    def test_underconstrained(self):
        'test an underconstrained case (fails for cvxopt)'

        a_ub = [[1.0, 0.0], [-1.0, 0.0]]
        b_ub = [1.0, 1.0]
        c = [1.0, 0.0]

        num_vars = 2

        lp = LpInstance(num_vars, num_vars)

        orthonormal_basis = [[
            1.0 if d == index else 0.0 for d in xrange(num_vars)
        ] for index in xrange(num_vars)]
        lp.update_basis_matrix(np.array(orthonormal_basis, dtype=float))

        # add each constraint
        for row in xrange(len(b_ub)):
            vec = np.matrix(a_ub[row], dtype=float)
            val = b_ub[row]

            lp.add_basis_constraint(vec, val)

        res_glpk = np.zeros(num_vars)
        lp.minimize(np.array(c, dtype=float), res_glpk)

        self.assertAlmostEqual(res_glpk[0], -1)
Beispiel #4
0
    def create_lpi(self, ce_object):
        longest_ce_lpi = LpInstance(self.num_dims, self.num_dims)
        longest_ce_lpi.update_basis_matrix(self.init_star.basis_matrix)
        prev_node_state = ce_object.patch[ce_object.start_index].state
        basis_centers = []
        while True:
            if isinstance(prev_node_state.parent, InitParent) or isinstance(
                    prev_node_state.parent.star.parent, InitParent):
                break
            elif isinstance(prev_node_state.parent.star.parent,
                            DiscretePostParent):
                basis_centers.append(
                    prev_node_state.parent.star.parent.prestar_basis_center)
                prev_node_state = prev_node_state.parent.star.parent.prestar

        for idx in range(ce_object.start_index, ce_object.end_index + 1, 1):
            node = ce_object.patch[idx]
            if node.state.mode.name != prev_node_state.mode.name:
                basis_centers.append(
                    node.state.parent.star.parent.prestar_basis_center)
                prev_node_state = node.state
            usafe_basis_preds = self.compute_usafe_set_pred_in_star_basis(
                node.state)
            for pred in usafe_basis_preds:
                for basis_center in basis_centers[::-1]:
                    pred = self.convert_usafe_basis_pred_in_basis_center(
                        pred, basis_center)
                longest_ce_lpi.add_basis_constraint(pred.vector, pred.value)

        for pred in self.init_star.constraint_list:
            longest_ce_lpi.add_basis_constraint(pred.vector, pred.value)

        return longest_ce_lpi
Beispiel #5
0
        def anim_iterator():
            'generator for the computation iterator'
            Timers.tic("total")

            # do the computation until its done
            while not is_finished_func():
                yield False

            # redraw one more (will clear cur_state)
            # yield False

            Timers.toc("total")

            LpInstance.print_stats()
            Timers.print_stats()
Beispiel #6
0
    def run_to_completion(self):
        'run the computation until it finishes (without plotting)'

        Timers.tic("total")

        while not self.is_finished():
            self.do_step()

        Timers.toc("total")

        if self.settings.print_output:
            LpInstance.print_stats()
            Timers.print_stats()

        self.result.time = Timers.timers["total"].total_secs
Beispiel #7
0
    def test_boundaries_optimized(self):
        'test finding the boundaries in an optimized fashion'

        Star.init_plot_vecs(2, TestStar.plot_settings)

        hr = HyperRectangle([
            (0, 1),
            (0, 1),
        ])
        star = init_hr_to_star(make_settings(), hr, TestStar.loc)

        start_op = LpInstance.total_optimizations()

        verts = star.verts()

        num_op = LpInstance.total_optimizations() - start_op

        self.assertEqual(len(verts), 5)
        self.assertLess(num_op, 100)
Beispiel #8
0
    def compare_opt(self, a_ub, b_ub, c):
        'compare cvx opt versus our glpk interface'

        # make sure we're using floats not ints
        a_ub = [[float(x) for x in row] for row in a_ub]
        b_ub = [float(x) for x in b_ub]
        c = [float(x) for x in c]

        num_vars = len(a_ub[0])

        # solve it with cvxopt
        options = {'show_progress': False}
        sol = cvxopt.solvers.lp(cvxopt.matrix(c),
                                cvxopt.matrix(a_ub).T,
                                cvxopt.matrix(b_ub),
                                options=options)

        #if sol['status'] == 'primal infeasible':
        #    res_cvxopt = None

        if sol['status'] != 'optimal':
            raise RuntimeError("cvxopt LP failed: {}".format(sol['status']))

        res_cvxopt = [float(n) for n in sol['x']]

        #print "cvxopt value = {}, result = {}".format(np.dot(res_cvxopt, c), repr(res_cvxopt))

        # solve it with the glpk <-> hylaa interface
        lp = LpInstance(num_vars, num_vars)

        orthonormal_basis = [[
            1.0 if d == index else 0.0 for d in xrange(num_vars)
        ] for index in xrange(num_vars)]
        lp.update_basis_matrix(np.array(orthonormal_basis, dtype=float))

        # add each constraint
        for row in xrange(len(b_ub)):
            vec = np.matrix(a_ub[row], dtype=float)
            val = b_ub[row]

            lp.add_basis_constraint(vec, val)

        res_glpk = np.zeros(num_vars)
        lp.minimize(np.array(c, dtype=float), res_glpk)

        #print "glpk interface value = {}, result = {}".format(np.dot(res_glpk, c), repr(res_glpk))

        self.assertEqual(num_vars, len(res_cvxopt))
        self.assertAlmostEqual(np.dot(res_glpk, c),
                               np.dot(res_cvxopt, c),
                               places=5)
Beispiel #9
0
    def make_combined_lpi(self, automaton_transition=None, skip_inputs=False):
        'create one lpi per guard, which will have both the star and input effects, as well as the guard condition'

        lpi = LpInstance(self.star.num_dims, self.star.num_dims)
        lpi.update_basis_matrix(self.star.basis_matrix)

        for lc in self.star.constraint_list:
            lpi.add_basis_constraint(lc.vector, lc.value)

        # add standard basis guard constraints
        if automaton_transition is not None:
            for lc in automaton_transition.condition_list:
                lpi.add_standard_constraint(lc.vector, lc.value)

        # add any input star constraints
        mode = self.star.mode

        if not skip_inputs and self.star.input_stars is not None:
            for input_star in self.star.input_stars:
                lpi.add_input_star(mode.u_constraints_a_t,
                                   mode.u_constraints_b,
                                   input_star.input_basis_matrix)

        return lpi
Beispiel #10
0
    def test_cpp(self):
        'runs the c++ test() function for the glpk interface'

        start_op = LpInstance.total_optimizations()
        start_it = LpInstance.total_iterations()

        LpInstance.test()
        self.assertGreater(LpInstance.total_iterations() - start_it,
                           5)  # the test ran a few iterations of lp
        self.assertGreater(LpInstance.total_optimizations() - start_op,
                           1)  # the test ran a few lp
Beispiel #11
0
    def get_lpi(self):
        'get (maybe create) the LpInstance object for this star + inputs, and return it'

        rv = self._star_lpi

        if rv is None:
            rv = LpInstance(self.num_dims, self.num_dims)
            rv.update_basis_matrix(self.basis_matrix)

            for lc in self.constraint_list:
                rv.add_basis_constraint(lc.vector, lc.value)

            # add the influence of the inputs
            if self.input_stars is not None:
                for input_star in self.input_stars:
                    rv.add_input_star(input_star.a_matrix_t, input_star.b_vector, input_star.input_basis_matrix)

            self._star_lpi = rv

        return rv
Beispiel #12
0
    def make_no_input_lpi(self, basis_matrix=None):
        '''make the lpi object for the input-free star, using the current star's basis matrix'''

        if basis_matrix is None:
            basis_matrix = np.zeros((self.star.num_dims, self.star.num_dims))

        rv = LpInstance(self.star.num_dims, self.star.num_dims)
        rv.update_basis_matrix(basis_matrix)

        for lc in self.star.constraint_list:
            rv.add_basis_constraint(lc.vector, lc.value)

        return rv
Beispiel #13
0
    def make_input_lpi(self, basis_matrix=None):
        'make the lpi object for the input star'

        rv = None

        if self.star.mode.num_inputs > 0:
            rv = LpInstance(self.star.num_dims, self.star.mode.num_inputs)

            if basis_matrix is None:
                basis_matrix = np.zeros(
                    (self.star.mode.num_inputs, self.star.num_dims))

            rv.update_basis_matrix(basis_matrix)

            for i in range(self.star.mode.u_constraints_b.shape[0]):
                rv.add_basis_constraint(self.star.mode.u_constraints_a[i, :],
                                        self.star.mode.u_constraints_b[i])

        return rv
Beispiel #14
0
    def test_ha(self):
        'test based on harmonic oscillator dynamics'

        lp = LpInstance(2, 2)
        basis = np.array([[0, -1], [1, 0]], dtype=float)
        lp.update_basis_matrix(basis)

        # x == 1
        lp.add_basis_constraint(np.array([1, 0], dtype=float), 1.0)
        lp.add_basis_constraint(np.array([-1, 0], dtype=float), -1.0)

        # y == 0
        lp.add_basis_constraint(np.array([0, 1], dtype=float), 0)
        lp.add_basis_constraint(np.array([0, -1], dtype=float), -0)

        res = -np.ones(4)
        lp.minimize(np.array([0, 0], dtype=float), res)

        # result should be [0, -1] (standard basis) and [1, 0] (star basis)
        self.assertAlmostEqual(res[0], 0.0)
        self.assertAlmostEqual(res[1], -1.0)

        # star constraints
        self.assertAlmostEqual(res[2], 1.0)
        self.assertAlmostEqual(res[3], 0.0)
    def compute_sequence_in_a_mode_wrt_init_mode(self, error_star_list, direction, compute_intersection):

        basis_center = error_star_list[0].parent.star.parent.prestar_basis_center

        usafe_basis_preds_list = self.compute_usafe_basis_pred_in_star_basis_in_star_list(error_star_list,
                                                                                          compute_intersection)
        valid_ids_for_all_indices = []
        feasible_points = []
        basis_matrix = error_star_list[0].parent.star.parent.prestar.parent.star.basis_matrix
        for idx_i in range(len(error_star_list)):
            valid_ids_for_current_index = []
            ## Create an LP instance
            usafe_lpi = LpInstance(self.num_dims, self.num_dims)
            usafe_lpi.update_basis_matrix(basis_matrix)

            #if idx_i == 0:
            #    with open("constraints_before", 'w+') as f:
            #        f.write('uasfe_basis_preds\n')
            #        for pred in usafe_basis_preds_list[idx_i]:
            #            f.write('{},{};\n'.format(pred.vector, pred.value))
            #        f.write('parent.star.constraint_list\n')
            #        for pred in error_star_list[0].parent.star.constraint_list:
            #            f.write('{},{};\n'.format(pred.vector, pred.value))
            #        f.write('Initial mode predicates\n')
            #        for pred in error_star_list[0].parent.star.parent.prestar.parent.star.constraint_list:
            #            f.write('{},{};\n'.format(pred.vector, pred.value))

            all_preds = []
            for pred in usafe_basis_preds_list[idx_i]:
                all_preds.append(self.convert_usafe_basis_pred_in_basis_center(pred, basis_center))
            for pred in error_star_list[0].parent.star.constraint_list:
                all_preds.append(self.convert_usafe_basis_pred_in_basis_center(pred, basis_center))

            ## adding constraints from the previous mode initial star (P)
            for pred in error_star_list[0].parent.star.parent.prestar.parent.star.constraint_list:
                all_preds.append(pred.clone())

            for pred in all_preds:
                usafe_lpi.add_basis_constraint(pred.vector, pred.value)

            #if idx_i == 0:
            #    with open("constraints_after", 'w+') as f:
            #        for pred in all_preds:
            #            f.write('{},{};\n'.format(pred.vector, pred.value))

            result = np.zeros(self.num_dims)
            usafe_lpi.minimize(direction, result, error_if_infeasible=False)
            feasible_point = np.dot(basis_matrix, result)
            valid_ids_for_current_index.append(idx_i)
            for idx_j in range(idx_i - 1, -1, -1):
                for pred in usafe_basis_preds_list[idx_j]:
                    new_pred = self.convert_usafe_basis_pred_in_basis_center(pred, basis_center)
                    usafe_lpi.add_basis_constraint(new_pred.vector, new_pred.value)

                result = np.zeros(self.num_dims)

                is_feasible = usafe_lpi.minimize(direction, result, error_if_infeasible=False)

                if not is_feasible:
                    break
                valid_ids_for_current_index.append(idx_j)
                feasible_point = np.dot(basis_matrix, result)
            valid_ids_for_all_indices.append(valid_ids_for_current_index)
            feasible_points.append(feasible_point)
        #print "valid ids for current mode: '{}'".format(valid_ids_for_all_indices)
        #print "feasible points: '{}'".format(feasible_points)
        return valid_ids_for_all_indices, feasible_points
Beispiel #16
0
    def check_path_feasibility(self, node, direction, basis_centers,
                               constraints_list):
        current_constraints_list = []
        current_basis_centers = []
        for constraint in constraints_list:
            current_constraints_list.append(constraint)
        for basis_center in basis_centers:
            current_basis_centers.append(basis_center)
        if node.error is False:
            print("Non-error node at '{}' in location '{}'".format(
                node.state.total_steps, node.state.mode.name))
            if node.cont_transition is not None:
                print(
                    " -- has a continuous transition at '{}' to location '{}'".
                    format(node.cont_transition.succ_node.state.total_steps,
                           node.cont_transition.succ_node.state.mode.name))
                self.check_path_feasibility(node.cont_transition.succ_node,
                                            direction, current_basis_centers,
                                            current_constraints_list)
            if len(node.disc_transitions) > 0 and node.disc_transitions[
                    0].succ_node.cont_transition is not None:
                print(" -- has a discrete transition at '{}' to location '{}'".
                      format(
                          node.disc_transitions[0].succ_node.state.total_steps,
                          node.disc_transitions[0].succ_node.state.mode.name))
                basis_centers.append(node.state.center)
                self.check_path_feasibility(node.disc_transitions[0].succ_node,
                                            direction, current_basis_centers,
                                            current_constraints_list)
            if node.cont_transition is None and len(
                    node.disc_transitions) == 0:
                print(" -- has no transition. Returning to previous node")
        else:
            print("Error node at '{}' in location '{}'".format(
                node.state.total_steps, node.state.mode.name))
            # print "basis centers '{}'".format(basis_centers)
            usafe_lpi = LpInstance(self.num_dims, self.num_dims)
            usafe_lpi.update_basis_matrix(self.init_star.basis_matrix)
            for constraint in current_constraints_list:
                usafe_lpi.add_basis_constraint(constraint.vector,
                                               constraint.value)

            usafe_basis_preds = self.compute_usafe_set_pred_in_star_basis(
                node.state)
            for pred in usafe_basis_preds:
                for basis_center in current_basis_centers[::-1]:
                    pred = self.convert_usafe_basis_pred_in_basis_center(
                        pred, basis_center)
                usafe_lpi.add_basis_constraint(pred.vector, pred.value)
                current_constraints_list.append(pred)

            if isinstance(node.state.parent.star.parent, DiscretePostParent):
                for pred in node.state.parent.star.constraint_list:
                    for basis_center in current_basis_centers[::-1]:
                        pred = self.convert_usafe_basis_pred_in_basis_center(
                            pred, basis_center)
                    usafe_lpi.add_basis_constraint(pred.vector, pred.value)
                    current_constraints_list.append(pred)

            result = np.zeros(self.num_dims)
            is_feasible = usafe_lpi.minimize(direction,
                                             result,
                                             error_if_infeasible=False)

            if is_feasible:
                feasible_point = np.dot(self.init_star.basis_matrix, result)
                print("feasible point is '{}' at the time step '{}'".format(
                    feasible_point, node.state.total_steps))

            if node.cont_transition is None and len(
                    node.disc_transitions) is 0:
                print("-- has no transition. Returning to previous node")

            if node.cont_transition is not None:
                print(
                    " -- has a continuous transition at '{}' to location '{}'".
                    format(node.cont_transition.succ_node.state.total_steps,
                           node.cont_transition.succ_node.state.mode.name))
                self.check_path_feasibility(node.cont_transition.succ_node,
                                            direction, current_basis_centers,
                                            current_constraints_list)
            if len(node.disc_transitions) > 0 and node.disc_transitions[
                    0].succ_node.cont_transition is not None:
                print(
                    " -- '{}' in location '{}' has a discrete transition at '{}' to location '{}'"
                    .format(
                        node.state.total_steps, node.state.mode.name,
                        node.disc_transitions[0].succ_node.state.total_steps,
                        node.disc_transitions[0].succ_node.state.mode.name))
                current_basis_centers.append(
                    node.disc_transitions[0].succ_node.state.parent.
                    prestar_basis_center)
                self.check_path_feasibility(
                    node.disc_transitions[0].succ_node.cont_transition.
                    succ_node, direction, current_basis_centers,
                    current_constraints_list)
    def compute_sequence_in_a_mode(self, error_star_list, direction, compute_intersection):

        usafe_basis_preds_list = self.compute_usafe_basis_pred_in_star_basis_in_star_list(error_star_list, compute_intersection)
        valid_ids_for_all_indices = []
        feasible_points = []

        for idx_i in range(len(error_star_list)):
            valid_ids_for_current_index = []
            ## Create an LP instance
            usafe_lpi = LpInstance(self.num_dims, self.num_dims)
            usafe_lpi.update_basis_matrix(error_star_list[0].parent.star.basis_matrix)

            all_preds = []
            for pred in usafe_basis_preds_list[idx_i]:
                all_preds.append(pred.clone())
            for pred in error_star_list[0].parent.star.constraint_list:
                all_preds.append(pred.clone())

            for pred in all_preds:
                usafe_lpi.add_basis_constraint(pred.vector, pred.value)

            result = np.zeros(self.num_dims)
            usafe_lpi.minimize(direction, result, error_if_infeasible=False)
            feasible_point = np.dot(error_star_list[0].parent.star.basis_matrix, result)
            valid_ids_for_current_index.append(idx_i)
            for idx_j in range(idx_i-1, -1, -1):
                for pred in usafe_basis_preds_list[idx_j]:
                    usafe_lpi.add_basis_constraint(pred.vector, pred.value)

                result = np.zeros(self.num_dims)

                is_feasible = usafe_lpi.minimize(direction, result, error_if_infeasible=False)

                if not is_feasible:
                    break
                valid_ids_for_current_index.append(idx_j)
                feasible_point = np.dot(self.init_star.basis_matrix, result)
            valid_ids_for_all_indices.append(valid_ids_for_current_index)
            feasible_points.append(feasible_point)
        return valid_ids_for_all_indices, feasible_points
Beispiel #18
0
    def compute_robust_ce_old(self):
        Timers.tic('Robust counter-example generation time')
        ce_object = self.compute_longest_ce()
        robust_points_in_initial_star = []
        patch = ce_object.patch[1:len(ce_object.patch) - 1]
        for node in patch:
            usafe_lpi = LpInstance(self.num_dims, self.num_dims)
            usafe_lpi.update_basis_matrix(node.state.basis_matrix)
            error_std_preds = self.convert_star_pred_in_standard_pred(
                node.state)
            for pred in error_std_preds:
                usafe_lpi.add_standard_constraint(pred.vector, pred.value)
            for pred in self.usafe_set_constraint_list:
                usafe_lpi.add_standard_constraint(pred.vector, pred.value)

            directions = np.identity(self.num_dims, dtype=float)
            avg_points = []
            for index in range(self.num_dims):
                direction = directions[index]
                result = np.ones(self.num_dims)
                is_feasible = usafe_lpi.minimize(direction,
                                                 result,
                                                 error_if_infeasible=False)
                if is_feasible:
                    basis_matrix = np.identity(self.num_dims, dtype=float)
                    point1 = np.dot(basis_matrix, result)
                result = np.ones(self.num_dims)
                is_feasible = usafe_lpi.minimize(-1 * direction,
                                                 result,
                                                 error_if_infeasible=False)
                if is_feasible:
                    basis_matrix = np.identity(self.num_dims, dtype=float)
                    point2 = np.dot(basis_matrix, result)
                avg_point = (point1 + point2) / 2
                avg_points.append(avg_point)
            robust_point_in_star = np.zeros(self.num_dims, dtype=float)
            for point in avg_points:
                robust_point_in_star += point
            robust_point_in_star = robust_point_in_star / len(avg_points)
            # print "robust point in star {}".format(robust_point_in_star)
            basis_centers = []
            prev_node_state = node.state
            while True:
                if isinstance(
                        prev_node_state.parent, InitParent) or isinstance(
                            prev_node_state.parent.star.parent, InitParent):
                    break
                elif isinstance(prev_node_state.parent.star.parent,
                                DiscretePostParent):
                    basis_centers.append(prev_node_state.parent.star.parent.
                                         prestar_basis_center)
                    prev_node_state = prev_node_state.parent.star.parent.prestar
            error_star_state = node.state.point_to_star_basis(
                robust_point_in_star)
            for basis_center in basis_centers[::-1]:
                error_star_state = error_star_state - basis_center
            robust_points_in_initial_star.append(
                np.dot(self.init_star.basis_matrix.T, error_star_state))

        robust_point = 0.0
        for point in robust_points_in_initial_star:
            robust_point += point
        robust_point = robust_point / len(robust_points_in_initial_star)
        print("Robust point: '{}'".format(robust_point))
        Timers.toc('Robust counter-example generation time')
        return robust_point
Beispiel #19
0
    def compute_deepest_ce(self, direction):
        start_node = self.reach_tree.nodes[0]
        node_queue = [start_node]
        depth = None
        deepest_node = None
        deepest_point = None
        Timers.tic("Deepest counter-example generation time")
        while len(node_queue) is not 0:

            node = node_queue[0]
            node_queue = node_queue[1:]

            if node.error is True:
                usafe_lpi = LpInstance(self.num_dims, self.num_dims)
                # usafe_lpi.update_basis_matrix(np.identity(self.num_dims))
                usafe_lpi.update_basis_matrix(node.state.basis_matrix)
                error_std_preds = self.convert_star_pred_in_standard_pred(
                    node.state)
                for pred in error_std_preds:
                    usafe_lpi.add_standard_constraint(pred.vector, pred.value)
                for pred in self.usafe_set_constraint_list:
                    usafe_lpi.add_standard_constraint(pred.vector, pred.value)
                # usafe_basis_preds = self.compute_usafe_set_pred_in_star_basis(node.state)
                # for pred in node.state.constraint_list:
                #    usafe_lpi.add_basis_constraint(pred.vector, pred.value)
                # for pred in usafe_basis_preds:
                #    usafe_lpi.add_basis_constraint(pred.vector, pred.value)

                result = np.ones(self.num_dims)
                is_feasible = usafe_lpi.minimize(-1 * direction,
                                                 result,
                                                 error_if_infeasible=False)
                if is_feasible:
                    # basis_matrix = node.state.basis_matrix
                    basis_matrix = np.identity(self.num_dims, dtype=float)
                    point = np.dot(basis_matrix, result)
                    current_depth = np.dot(direction, point)
                    # print("Current depth {}".format(current_depth))
                    # print ("depth for the point {} at time {} in loc {} is : {}".format(point, node.state.total_steps,
                    # node.state.mode.name, current_depth))
                    if depth is None or current_depth >= depth:
                        depth = current_depth
                        deepest_node = node
                        deepest_point = point

            if node.cont_transition is not None:
                node_queue.append(node.cont_transition.succ_node)
            if len(node.disc_transitions) > 0 and node.disc_transitions[
                    0].succ_node.cont_transition is not None:
                node_queue.append(node.disc_transitions[0].succ_node.
                                  cont_transition.succ_node)

        print("deepest point is '{}' in location '{}' with depth '{}'".format(
            deepest_point, deepest_node.state.mode.name,
            np.dot(abs(direction), deepest_point)))
        basis_centers = []
        # basis_matrices = []
        prev_node_state = deepest_node.state
        while True:
            if isinstance(prev_node_state.parent, InitParent) or isinstance(
                    prev_node_state.parent.star.parent, InitParent):
                break
            elif isinstance(prev_node_state.parent.star.parent,
                            DiscretePostParent):
                basis_centers.append(
                    prev_node_state.parent.star.parent.prestar_basis_center)
                # basis_matrices.append(prev_node_state.parent.star.parent.prestar.basis_matrix)
                prev_node_state = prev_node_state.parent.star.parent.prestar

        print("Basis centers: {}".format(basis_centers))
        # usafe_lpi = LpInstance(self.num_dims, self.num_dims)
        # usafe_lpi.update_basis_matrix(self.init_star.basis_matrix)
        # error_star_state = self.convert_std_state_in_star_state(deepest_point, deepest_node.state)
        error_star_state = deepest_node.state.point_to_star_basis(
            deepest_point)
        # for index in range(len(basis_centers)-1, -1, -1):
        #    print "Index is {}".format(index)
        #    basis_center = basis_centers[index]
        #    basis_matrix = basis_matrices[index]
        #    basis_center_coeffs = np.dot(inv(basis_matrix.T),basis_center)
        #    error_star_state = error_star_state - basis_center_coeffs
        for basis_center in basis_centers[::-1]:
            error_star_state = error_star_state - basis_center
        deepest_ce = np.dot(self.init_star.basis_matrix.T, error_star_state)
        ce_depth = float(np.dot(abs(direction), deepest_point))
        ce_object = CeObject(ce=deepest_ce, ce_depth=ce_depth)
        print("The deepest ce is '{}' with depth '{}'".format(
            deepest_ce, ce_depth))
        Timers.toc("Deepest counter-example generation time")
        return ce_object
Beispiel #20
0
    def compute_longest_ce_in_a_path(self, path):
        # longest_ce_lpi = None
        direction = np.ones(self.num_dims)
        prev_time_step = path[0].state.total_steps - 1
        continuous_patches = []
        current_patch = []
        for node in path:
            if node.state.total_steps == prev_time_step + 1:
                current_patch.append(node)
                # print(node.state.mode.name, node.state.total_steps)
            else:
                continuous_patches.append(current_patch)
                current_patch = [node]
            prev_time_step = node.state.total_steps
            # print('Loc {} time step {}\n'.format(node.state.mode.name, node.state.total_steps))

        if len(current_patch) is not 0:
            continuous_patches.append(current_patch)

        # ce_length = 0
        # ce = None
        ce_object = None
        for patch in continuous_patches:
            # current_ce_length = 0
            # ce = None
            for idx_i in range(len(patch)):
                usafe_lpi = LpInstance(self.num_dims, self.num_dims)
                usafe_lpi.update_basis_matrix(self.init_star.basis_matrix)
                prev_node_state = patch[idx_i].state
                basis_centers = []
                current_ce_length = 0

                while True:
                    if isinstance(prev_node_state.parent,
                                  InitParent) or isinstance(
                                      prev_node_state.parent.star.parent,
                                      InitParent):
                        break
                    elif isinstance(prev_node_state.parent.star.parent,
                                    DiscretePostParent):
                        basis_centers.append(prev_node_state.parent.star.
                                             parent.prestar_basis_center)
                        prev_node_state = prev_node_state.parent.star.parent.prestar

                # TO CHECK Reverse the basis_centers list here?

                prev_node_state = patch[idx_i].state

                for idx_j in range(idx_i, len(patch), 1):
                    node = patch[idx_j]
                    if node.state.mode.name != prev_node_state.mode.name:
                        basis_centers.append(
                            node.state.parent.star.parent.prestar_basis_center)
                        prev_node_state = node.state
                    usafe_basis_preds = self.compute_usafe_set_pred_in_star_basis(
                        node.state)
                    for pred in usafe_basis_preds:
                        for basis_center in basis_centers[::-1]:
                            pred = self.convert_usafe_basis_pred_in_basis_center(
                                pred, basis_center)
                        usafe_lpi.add_basis_constraint(pred.vector, pred.value)

                    for pred in self.init_star.constraint_list:
                        usafe_lpi.add_basis_constraint(pred.vector, pred.value)

                    # TO CHECK is this a redundant step?
                    # if isinstance(node.state.parent.star.parent, DiscretePostParent):
                    #    for pred in node.state.parent.star.constraint_list:
                    #        for basis_center in basis_centers[::-1]:
                    #            pred = self.convert_usafe_basis_pred_in_basis_center(pred, basis_center)
                    #        usafe_lpi.add_basis_constraint(pred.vector, pred.value)

                    result = np.zeros(self.num_dims)
                    is_feasible = usafe_lpi.minimize(direction,
                                                     result,
                                                     error_if_infeasible=False)

                    if is_feasible:
                        feasible_point = np.dot(self.init_star.basis_matrix,
                                                result)
                        current_ce_length = current_ce_length + 1
                        current_ce = feasible_point
                        # print "Counterexample is '{}' of length '{}' for node '{}' at time '{}'".format(current_ce,
                        #                            current_ce_length, node.state.mode.name, node.state.total_steps)
                    else:
                        # print "Node '{}' at time '{}' is not feasible with existing states".format(
                        # node.state.mode.name, node.state.total_steps)
                        break

                    if ce_object is None or current_ce_length >= ce_object.ce_length:
                        ce_object = CeObject(current_ce, current_ce_length,
                                             usafe_lpi, 0, patch,
                                             patch[idx_i].state.total_steps,
                                             patch[idx_j].state.total_steps)
                        # longest_ce_lpi = usafe_lpi
                        # print "This counterexample starts from index '{}' in location '{}'".format(
                        # patch[idx_i].state.total_steps, patch[idx_i].state.mode.name)
                        # print "This counterexample ends at index '{}' in location '{}'".format(
                        # node.state.total_steps, node.state.mode.name)

        return ce_object
    def compute_sequences_in_two_modes(self, error_star_list_per_mode, direction, compute_intersection=False):
        error_star_list_second_mode = error_star_list_per_mode[1]
        error_star_list_first_mode = []
        for index in range(len(error_star_list_per_mode[0])):
            if (error_star_list_per_mode[0][index].total_steps < error_star_list_second_mode[0].total_steps):
                error_star_list_first_mode.append(error_star_list_per_mode[0][index].clone())
            else:
                break

        usafe_basis_preds_list_first_mode = self.compute_usafe_basis_pred_in_star_basis_in_star_list(error_star_list_first_mode, compute_intersection)
        usafe_basis_preds_list_second_mode = self.compute_usafe_basis_pred_in_star_basis_in_star_list(error_star_list_second_mode, compute_intersection)

        ## compute_sequence_in_a_mode() returns the indices of the feasible stars for each star scanning from left to right
        sequences_in_second_mode, feasible_pts_in_second_mode = self.compute_sequence_in_a_mode_wrt_init_mode(error_star_list_second_mode, direction, compute_intersection)
        sequences_in_first_mode, feasible_pts_in_first_mode = self.compute_sequence_in_a_mode(error_star_list_first_mode, direction, compute_intersection)
        len_of_longest_seq_in_first_mode = 0
        longest_ce_in_first_mode = None
        longest_seq_in_first_mode = [0, 0]
        ce_length_in_first_mode = 0
        for index in range(len(sequences_in_first_mode)):
            valid_ids = sequences_in_first_mode[index]
            cur_seq_len = (valid_ids[0]-valid_ids[len(valid_ids)-1])
            if len_of_longest_seq_in_first_mode < cur_seq_len:
                len_of_longest_seq_in_first_mode = cur_seq_len
                longest_seq_in_first_mode[1] = valid_ids[0]
                longest_seq_in_first_mode[0] = valid_ids[len(valid_ids)-1]
                ce_length_in_first_mode = longest_seq_in_first_mode[1] - longest_seq_in_first_mode[0] + 1
                longest_ce_in_first_mode = feasible_pts_in_first_mode[index]

        len_of_longest_seq_in_second_mode = 0
        longest_seq_in_second_mode = [0, 0]
        longest_ce_in_second_mode = None
        ce_length_in_second_mode = 0
        for index in range(len(sequences_in_second_mode)):
            valid_ids = sequences_in_second_mode[index]
            cur_seq_len = (valid_ids[0] - valid_ids[len(valid_ids)-1])
            if len_of_longest_seq_in_second_mode < cur_seq_len:
                len_of_longest_seq_in_second_mode = cur_seq_len
                longest_seq_in_second_mode[1] = valid_ids[0]
                longest_seq_in_second_mode[0] = valid_ids[len(valid_ids) - 1]
                ce_length_in_second_mode = longest_seq_in_second_mode[1] - longest_seq_in_second_mode[0] + 1
                longest_ce_in_second_mode = feasible_pts_in_second_mode[index]

        ## Compute indices - Compute longest sequence in first mode for each star in the next mode
        ## The sequence is represented as start and end index. If there is none, both start and end indices are -1
        first_mode_seq_for_each_second_mode_stars = []
        #usafe_basis_preds_list_in_first_mode = self.compute_usafe_basis_pred_in_star_basis_in_star_list(
        #            error_star_list_per_mode[0], compute_intersection)
        for index in range(len(error_star_list_second_mode)):

            usafe_basis_preds_for_current_star_in_current_mode = self.compute_usafe_basis_pred_in_star_basis(
                        error_star_list_second_mode[index], compute_intersection)

            basis_center = error_star_list_second_mode[0].parent.star.parent.prestar_basis_center

            new_usafe_basis_preds = []
            for pred in usafe_basis_preds_for_current_star_in_current_mode:
                        new_usafe_basis_preds.append(self.convert_usafe_basis_pred_in_basis_center(pred, basis_center))
            indices = self.compute_indices(new_usafe_basis_preds, usafe_basis_preds_list_first_mode, 0,
                                                   len(usafe_basis_preds_list_first_mode) - 1, direction)
            first_mode_seq_for_each_second_mode_stars.append(self.perform_pruning(indices))

        final_seqs_for_first_mode = []
        final_seqs_for_second_mode = []
        feasible_ces = []
        basis_center = error_star_list_second_mode[0].parent.star.parent.prestar_basis_center
        for valid_ids_for_current_index in sequences_in_second_mode:
            start = 0
            end = len(valid_ids_for_current_index) - 1
            feasible_point = None
            while True:

                ## Create an LP instance
                usafe_lpi = LpInstance(self.num_dims, self.num_dims)
                usafe_lpi.update_basis_matrix(self.init_star.basis_matrix)
                for pred in self.init_star.constraint_list:
                    usafe_lpi.add_basis_constraint(pred.vector, pred.value)

                sequence_1 = first_mode_seq_for_each_second_mode_stars[valid_ids_for_current_index[start]] ## Merging it with same sequence gives the same seq
                for idx in range(start, end, 1 ):
                    sequence_1 = self.compute_sequences_intersection(sequence_1, first_mode_seq_for_each_second_mode_stars[valid_ids_for_current_index[idx]])
                    if sequence_1[1] != -1:
                        for pred in usafe_basis_preds_list_second_mode[valid_ids_for_current_index[idx]]:
                            lc = self.convert_usafe_basis_pred_in_basis_center(pred, basis_center)
                            usafe_lpi.add_basis_constraint(lc.vector, lc.value)
                    #sequence_1 = self.compute_sequences_intersection(sequence_1, first_mode_seq_for_each_second_mode_stars[valid_ids_for_current_index[idx]])
                if sequence_1[1] == -1:
                    break
                for idx in range(len(sequence_1)):
                    for pred in usafe_basis_preds_list_first_mode[idx]:
                        usafe_lpi.add_basis_constraint(pred.vector, pred.value)

                result = np.zeros(self.num_dims)

                is_feasible = usafe_lpi.minimize(direction, result, error_if_infeasible=False)
                feasible_point = np.dot(self.init_star.basis_matrix, result)
                if is_feasible:
                    break
                else:
                    end = end - 1

            valid_ids = valid_ids_for_current_index[start:end+1] #end+1 for including the last value
            sequence_2 = [-1,-1]
            sequence_2[1] = valid_ids[0]
            sequence_2[0] = valid_ids[len(valid_ids) - 1]
            if sequence_1[1] != -1:
                final_seqs_for_second_mode.append(sequence_2)
                final_seqs_for_first_mode.append(sequence_1)
                feasible_ces.append(feasible_point)

        combined_max_ce_length = 0
        start_idx_first_mode = -1
        start_idx_sec_mode = -1
        end_idx_first_mode = -1
        end_idx_sec_mode = -1
        longest_ce = None
        for index in range(len(final_seqs_for_second_mode)):
            current_ce_length = final_seqs_for_first_mode[index][1] - final_seqs_for_first_mode[index][0] + 1
            current_ce_length = current_ce_length + (final_seqs_for_second_mode[index][1] - final_seqs_for_second_mode[index][0] + 1)
            if current_ce_length > combined_max_ce_length:
                start_idx_first_mode = final_seqs_for_first_mode[index][0]
                end_idx_first_mode = final_seqs_for_first_mode[index][1]
                start_idx_sec_mode = final_seqs_for_second_mode[index][0]
                end_idx_sec_mode = final_seqs_for_second_mode[index][1]
                combined_max_ce_length = current_ce_length
                longest_ce = feasible_ces[index]

        if combined_max_ce_length < ce_length_in_first_mode:
            combined_max_ce_length = ce_length_in_first_mode
            longest_ce = longest_ce_in_first_mode
            start_idx_first_mode = longest_ce_in_first_mode[0]
            end_idx_first_mode = longest_ce_in_first_mode[1]
            start_idx_sec_mode = end_idx_sec_mode = -1
        if combined_max_ce_length < ce_length_in_second_mode:
            combined_max_ce_length = ce_length_in_second_mode
            longest_ce = longest_ce_in_second_mode
            start_idx_sec_mode = longest_seq_in_second_mode[0]
            end_idx_sec_mode = longest_seq_in_second_mode[1]
            start_idx_first_mode = end_idx_first_mode = -1

        final_indices = []
        final_indices.append(combined_max_ce_length)
        final_indices.append(start_idx_first_mode)
        final_indices.append(end_idx_first_mode)
        final_indices.append(start_idx_sec_mode)
        final_indices.append(end_idx_sec_mode)

        return final_indices, longest_ce
class GuardOptData(Freezable):
    'Guard optimization data'

    def __init__(self, star, mode, transition_index):
        assert isinstance(mode, LinearAutomatonMode)

        self.settings = star.settings
        self.mode = mode
        self.inputs = star.inputs

        self.star = star
        self.transition = mode.transitions[transition_index]
        self.num_output_vars = self.transition.guard_matrix_csr.shape[1]

        self.key_dir_offset = 0

        if self.settings.plot.plot_mode != PlotSettings.PLOT_NONE:
            if self.settings.plot.xdim_dir is not None:
                self.key_dir_offset += 1

            if self.settings.plot.ydim_dir is not None:
                self.key_dir_offset += 1

        self.lpi = LpInstance(self.num_output_vars, star.num_init_vars,
                              self.inputs)

        self.lpi.set_init_constraints(star.init_mat, star.init_rhs)
        self.lpi.set_output_constraints(self.transition.guard_matrix_csr,
                                        self.transition.guard_rhs)

        if star.inputs > 0:
            self.lpi.set_input_constraints_csc(
                csc_matrix(star.mode.u_constraints_csr),
                star.mode.u_constraints_rhs)

        self.optimized_lp_solution = None

        self.freeze_attrs()

    def update_full_lp(self):
        '''update the LP solution and, if it's feasible, get its solution, for GUARD_FULL_LP'''

        cur_basis_mat = self.star.time_elapse.cur_basis_mat

        # start and end rows of key-dir matrices
        start = self.key_dir_offset
        end = self.key_dir_offset + self.num_output_vars

        self.lpi.update_basis_matrix(cur_basis_mat[start:end])

        # add input effects for the current step (if it exists)
        if self.star.time_elapse.cur_input_effects_matrix is not None:
            input_effects_mat = self.star.time_elapse.cur_input_effects_matrix
            self.lpi.add_input_effects_matrix(input_effects_mat[start:end])

        result_len = self.num_output_vars + self.star.num_init_vars
        result_len += self.num_output_vars  # total input effect
        result_len += self.inputs * (self.star.time_elapse.next_step - 1
                                     )  # inputs at each step

        result = np.zeros((result_len), dtype=float)
        direction = np.zeros((self.num_output_vars, ), dtype=float)

        is_feasible = self.lpi.minimize(direction,
                                        result,
                                        error_if_infeasible=False)

        return result if is_feasible else None

    def get_guard_lpi(self):
        '''get the current full lp instance for this guard'''

        return self.lpi

    def get_optimized_lp_solution(self):
        '''gets the lp solution without calling an lp solver
        this is only possible if the initial set has only range conditions for each initial dimension,
        and the output-space has only a single condition

        This returns either an lp solution (np.ndarray) or None if infeasible
        '''

        Timers.tic('get_optimized_lp_solution')

        init_ranges = self.star.init_range_tuples
        basis_mat = self.star.time_elapse.cur_basis_mat
        input_effects_mat = self.star.time_elapse.cur_input_effects_matrix

        assert len(init_ranges) == basis_mat.shape[1]
        assert len(self.transition.guard_rhs) == 1
        assert self.num_output_vars == 1
        assert self.transition.guard_matrix_csr.shape == (1, 1)

        guard_multiplier = self.transition.guard_matrix_csr[0, 0]

        if self.optimized_lp_solution is None:
            # +1 for output +1 for total input effects
            self.optimized_lp_solution = [0.0] * (len(init_ranges) + 1 + 1)

        result = self.optimized_lp_solution
        total_output_index = len(init_ranges)
        total_input_index = len(init_ranges) + 1

        guard_threshold = self.transition.guard_rhs[0]
        noinput_effect = 0

        Timers.tic("noinput_effects")
        for init_index in xrange(len(init_ranges)):
            basis_val = basis_mat[0, init_index]
            min_init = init_ranges[init_index][0]
            max_init = init_ranges[init_index][1]

            mult = basis_val * guard_multiplier
            val1 = min_init * mult
            val2 = max_init * mult

            # take the minimum of val1 and val2, since guard is CONDITION <= RHS
            if val1 < val2:
                noinput_effect += val1
                result[init_index] = min_init
            else:
                noinput_effect += val2
                result[init_index] = max_init
        Timers.toc("noinput_effects")

        # add input effects if they exist
        if input_effects_mat is not None:
            Timers.tic("input_effects")
            input_ranges = self.star.mode.u_range_tuples

            for input_index in xrange(len(input_ranges)):
                basis_val = input_effects_mat[0][input_index]
                min_input = input_ranges[input_index][0]
                max_input = input_ranges[input_index][1]

                val1 = min_input * basis_val * guard_multiplier
                val2 = max_input * basis_val * guard_multiplier

                # take the minimum of val1 and val2, since guard is CONDITION <= RHS
                if val1 < val2:
                    result[total_input_index] += val1
                    result.append(min_input)
                else:
                    result[total_input_index] += val2
                    result.append(max_input)

            Timers.toc("input_effects")

        result[total_output_index] = noinput_effect + result[total_input_index]

        rv = np.array(
            result, dtype=float
        ) if result[total_output_index] <= guard_threshold else None

        Timers.toc('get_optimized_lp_solution')

        return rv

    def get_updated_lp_solution(self):
        '''update the LP solution and, if it's feasible, get its solution'''

        if self.star.settings.interval_guard_optimization and self.star.init_range_tuples is not None and \
            (self.star.inputs == 0 or self.star.mode.u_range_tuples is not None) and self.num_output_vars == 1:
            # LP can be decomposed column-by-column (optimization)
            rv = self.get_optimized_lp_solution()
        else:
            rv = self.update_full_lp()

        return rv
    def compute_counter_examples(self, direction):

        ## Populate error stars info
        error_star_steps = []
        error_star_modes = []

        for error_star in self.error_stars:
            error_star_steps.append(error_star.total_steps)
            error_star_modes.append(error_star.mode)

        # List of feasible solutions/initial points
        initial_points = []
        usafe_basis_predicates_list = []

        ## Iterate over the stars which intersect with the unsafe set
        ## Eventually there is going to be just one star at a particular
        ## time step that user is interested in.
        for index in range(len(self.error_stars)):

            #basis_matrix = error_star_basis_matrices[index]
            #basis_center = error_star_centers[index]
            error_star = self.error_stars[index]
            usafe_basis_predicates = self.compute_usafe_basis_pred_in_star_basis(error_star)

            ## List of predicates for each time step where our standard star intersects with the unsafe set
            ## To be used while computing the longest subsequence.
            usafe_basis_predicates_list.append(usafe_basis_predicates)

            ## Create an LP instance
            usafe_lpi = LpInstance(self.num_dims, self.num_dims)

            ## Update the basis matrix
            usafe_lpi.update_basis_matrix(self.init_star.basis_matrix)

            for predicate in usafe_basis_predicates:
                usafe_lpi.add_basis_constraint(predicate.vector, predicate.value)

            ## Add init star basis constraints to the usafe linear constraints list
            for lc in self.init_star.constraint_list:
                usafe_lpi.add_basis_constraint(lc.vector, lc.value)

            result = np.zeros(self.num_dims)

            is_feasible = usafe_lpi.minimize(direction, result, error_if_infeasible=False)

            ## This gives us a point, if any, in the initial set which leads to an unsafe point at a given time step.
            if is_feasible:
                initial_points.append(np.dot(self.init_star.basis_matrix, result))

        counterExamples = []
        unique_initial_points = []
        for index_i in range(len(initial_points)):
            not_unique = False
            for index_u in range(len(unique_initial_points)):
                out = np.zeros(self.num_dims)
                if (np.subtract(unique_initial_points[index_u], initial_points[index_i]) == out).all():
                    not_unique = True
                    break
            if not not_unique:
                counterExample = CounterExample(initial_points[index_i], usafe_basis_predicates_list, error_star_steps,
                                                error_star_modes, self.num_dims)
                counterExamples.append(counterExample)
                unique_initial_points.append(initial_points[index_i])
        return counterExamples
    def check_if_feasible(self, usafe_basis_preds, usafe_basis_preds_list_in_first_mode, start_index, end_index, direction):

        ## Create an LP instance
        usafe_lpi = LpInstance(self.num_dims, self.num_dims)
        usafe_lpi.update_basis_matrix(self.init_star.basis_matrix)

        for pred in usafe_basis_preds:
            usafe_lpi.add_basis_constraint(pred.vector, pred.value)

        for idx in range(len(usafe_basis_preds_list_in_first_mode)):

            if idx >= start_index and idx <= end_index:
                for pred in usafe_basis_preds_list_in_first_mode[idx]:
                    usafe_lpi.add_basis_constraint(pred.vector, pred.value)

        for pred in self.init_star.constraint_list:
            usafe_lpi.add_basis_constraint(pred.vector, pred.value)

        result = np.zeros(self.num_dims)

        is_feasible = usafe_lpi.minimize(direction, result, error_if_infeasible=False)

        return is_feasible
Beispiel #25
0
    def compute_ce_vector(self,
                          simulation,
                          usafe_set_constraint_list,
                          direction=None,
                          sim_start_time=0,
                          current_mode_idx=0):
        usafe_points = []
        ce_vector = []
        for time in self.error_time_steps[current_mode_idx]:
            point = simulation[int(time) - sim_start_time]
            usafe_lpi = LpInstance(self.num_dims, self.num_dims)
            identity_matrix = np.identity(self.num_dims)
            usafe_lpi.update_basis_matrix(np.identity(self.num_dims))
            for dim in range(identity_matrix.ndim):
                lc = LinearConstraint(identity_matrix[dim], point[dim])
                usafe_lpi.add_basis_constraint(lc.vector, lc.value)
                lc = LinearConstraint(-1 * identity_matrix[dim], -point[dim])
                usafe_lpi.add_basis_constraint(lc.vector, lc.value)
            for constraints in usafe_set_constraint_list:
                usafe_lpi.add_basis_constraint(constraints.vector,
                                               constraints.value)

            direction = np.zeros(self.num_dims)
            usafe_point = np.zeros(self.num_dims)
            is_feasible = usafe_lpi.minimize(direction,
                                             usafe_point,
                                             error_if_infeasible=False)
            usafe_points.append(usafe_point)
            if is_feasible:
                ce_vector.append(1)
            else:
                ce_vector.append(0)
        return ce_vector
Beispiel #26
0
    def compute_longest_sequence(self,
                                 ce_vector,
                                 init_star,
                                 direction,
                                 current_mode_idx=0):

        usafe_lpi = LpInstance(init_star.num_dims, init_star.num_dims)
        length = 0

        # First value is the length of the subsequence
        # Second and third values are the indices of the subsequence in the ce_vector
        time_step_indices = [0, 0, 0]
        start_index = 0
        end_index = 0
        index = [0, 0]
        max_len = 0
        current_index = 0
        while (current_index < len(ce_vector)):
            if ce_vector[current_index] == 1:
                if length == 0:
                    usafe_lpi = LpInstance(init_star.num_dims,
                                           init_star.num_dims)
                    usafe_lpi.update_basis_matrix(init_star.basis_matrix)
                    for lc in init_star.constraint_list:
                        usafe_lpi.add_basis_constraint(lc.vector, lc.value)
                    start_index = current_index

                usafe_basis_predicates = self.usafe_basis_predicates[
                    current_mode_idx][current_index]
                result = np.zeros(init_star.num_dims)
                for usafe_basis_predicate in usafe_basis_predicates:
                    usafe_lpi.add_basis_constraint(
                        usafe_basis_predicate.vector,
                        usafe_basis_predicate.value)

                is_feasible = usafe_lpi.minimize(direction,
                                                 result,
                                                 error_if_infeasible=False)
                if is_feasible:
                    length = length + 1
                    end_index = current_index
                else:
                    current_index = start_index + 1
                    length = 0

                if max_len < length:
                    max_len = length
                    index[0] = start_index
                    index[1] = end_index
            else:
                length = 0
            current_index = current_index + 1

        time_step_indices[1] = self.error_time_steps[current_mode_idx][
            index[0]]
        time_step_indices[2] = self.error_time_steps[current_mode_idx][
            index[1]]
        time_step_indices[0] = time_step_indices[2] - time_step_indices[1] + 1
        return time_step_indices
    def compute_deepest_ce(self, depth_direction):

        compute_intersection = True
        Timers.tic('Deepest counter-example')
        points = []
        for error_star in self.error_stars:
            usafe_lpi = LpInstance(self.num_dims, self.num_dims)
            usafe_lpi.update_basis_matrix(error_star.basis_matrix)
            for pred in self.usafe_set_constraint_list:
                usafe_lpi.add_standard_constraint(pred.vector, pred.value)
            for pred in error_star.constraint_list:
                usafe_lpi.add_basis_constraint(pred.vector, pred.value)
            result = np.zeros(self.num_dims)
            is_feasible = usafe_lpi.minimize(-1 * depth_direction, result, error_if_infeasible=False)
            if is_feasible:
                usafe_set_basis_matrix = np.identity(self.num_dims, dtype=float)
                points.append(np.dot(usafe_set_basis_matrix, result))

        if len(points) is 0:
            print("Result (Deepest counter-example): No solution exists in this direction.")
            Timers.toc('Deepest counter-example')
            return

        # Find the index of the error_star corresponding to the max_depth
        max_depth = np.dot(depth_direction, points[0])
        max_depth_error_star = self.error_stars[0].clone()
        max_point = points[0]
        for index in range(len(points)):
            point = points[index]
            depth = np.dot(depth_direction, point)
            if depth > max_depth:
               max_depth = depth
               max_depth_error_star = self.error_stars[index].clone()
               max_point = point

        print("The deepest point is: '{}' with max_depth '{}'".format(max_point, max_depth))
        #print "Max error star: '{}'".format(max_depth_error_star)
        #max_depth_error_star = self.error_stars[max_depth_index].clone()

        feasible_point = None
        if max_depth_error_star.mode.name == self.init_star.mode.name:
            basis_matrix = max_depth_error_star.parent.star.basis_matrix
            usafe_lpi = LpInstance(self.num_dims, self.num_dims)
            usafe_lpi.update_basis_matrix(basis_matrix)
            usafe_basis_preds = self.compute_point_as_star_basis(max_point, max_depth_error_star)
            #usafe_basis_preds = self.compute_usafe_basis_pred_in_star_basis(max_depth_error_star, False)
            for pred in usafe_basis_preds:
                usafe_lpi.add_basis_constraint(pred.vector, pred.value)
            for pred in max_depth_error_star.parent.star.constraint_list:
                usafe_lpi.add_basis_constraint(pred.vector, pred.value)

            result = np.zeros(self.num_dims)
            is_feasible = usafe_lpi.minimize(-1 * depth_direction, result, error_if_infeasible=False)
            if is_feasible:
                feasible_point = np.dot(basis_matrix, result)
                print("CounterExample: '{}' with depth '{}' in the given direction".format(feasible_point, max_depth))
            Timers.toc('Deepest counter-example')

        else:
            basis_center = max_depth_error_star.parent.star.parent.prestar_basis_center

            usafe_basis_preds = self.compute_usafe_basis_pred_in_star_basis(max_depth_error_star, compute_intersection)
            #print "Usafe Basis predicates: {}".format(usafe_basis_preds)
            #usafe_basis_preds = self.compute_point_as_star_basis(max_point, max_depth_error_star)
            basis_matrix = max_depth_error_star.parent.star.parent.prestar.parent.star.basis_matrix

            usafe_lpi = LpInstance(self.num_dims, self.num_dims)
            usafe_lpi.update_basis_matrix(basis_matrix)

            all_preds = []
            for pred in usafe_basis_preds:
                all_preds.append(self.convert_usafe_basis_pred_in_basis_center(pred, basis_center))
            #for pred in max_depth_error_star.parent.star.constraint_list:
            #    all_preds.append(self.convert_usafe_basis_pred_in_basis_center(pred, basis_center))

            ## adding constraints from the previous mode initial star (P)
            for pred in max_depth_error_star.parent.star.parent.prestar.parent.star.constraint_list:
                all_preds.append(pred.clone())

            for pred in all_preds:
                usafe_lpi.add_basis_constraint(pred.vector, pred.value)

            result = np.zeros(self.num_dims)
            is_feasible = usafe_lpi.minimize(-1 * depth_direction, result, error_if_infeasible=False)
            if is_feasible:
                feasible_point = np.dot(basis_matrix, result)
                print("CounterExample: '{}' with depth '{}' in the given direction".format(feasible_point, max_depth))
            Timers.toc('Deepest counter-example')
        return feasible_point