Exemple #1
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)
Exemple #2
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
Exemple #3
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
Exemple #4
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
Exemple #5
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)
Exemple #6
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)
Exemple #7
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)
Exemple #8
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
Exemple #9
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
Exemple #10
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
    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
Exemple #12
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
    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
    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
Exemple #15
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_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
Exemple #17
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
    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