Exemplo n.º 1
0
def get_concrete_state_obj(t0, x0, d0, pvt0, s0, ci, pi, u):
    if x0.ndim == 1:
        concrete_states = st.StateArray(
            t=np.array([t0]),
            x=np.array([x0]),
            d=np.array([d0]),
            pvt=np.array([pvt0]),
            u=np.array([u]),
            s=np.array([s0]),
            pi=np.array([pi]),
            ci=np.array([ci]),
        )
    elif x0.ndim == 2:

        concrete_states = st.StateArray(
            t=t0,
            x=x0,
            d=d0,
            pvt=pvt0,
            u=u,
            s=s0,
            pi=pi,
            ci=ci,
        )
    else:
        raise err.Fatal('dimension must be 1 or 2...: {}!'.format(x0.ndim))
    return concrete_states
Exemplo n.º 2
0
    def simulate(
        self,
        sim_states,
        T,
        property_checker=None,
        property_violated_flag=None,
    ):
        t_array = np.empty((sim_states.n, 1))

        num_dim = sim_states.cont_states.shape[1]
        X_array = np.empty((sim_states.n, num_dim))

        num_dim = sim_states.discrete_states.shape[1]
        D_array = np.empty((sim_states.n, num_dim))

        num_dim = sim_states.pvt_states.shape[1]
        P_array = np.empty((sim_states.n, num_dim))

        i = 0

        for state in sim_states.iterable():
            (t, X, D, pvt) = self.sim(
                (state.t, state.t + T),
                state.x,
                state.d,
                state.pvt,
                state.u,
                state.pi,
                property_checker,
                property_violated_flag,
            )
            t_array[i, :] = t
            X_array[i, :] = X
            D_array[i, :] = D
            P_array[i, :] = pvt
            i += 1

        return st.StateArray(
            t=t_array,
            x=X_array,
            d=D_array,
            pvt=P_array,
            s=sim_states.controller_states,
            u=sim_states.controller_outputs,
            pi=sim_states.plant_extraneous_inputs,
            ci=sim_states.controller_extraneous_inputs,
        )
Exemplo n.º 3
0
def sample_init_UR(sys, prop, num_samples):
    num_segments = int(np.ceil(prop.T / sys.delta_t))
    init_cons = prop.init_cons
    init_controller_state = prop.initial_controller_state
    # eliminate by removing u and removing dummu pvt...use real pvt
    num_dims = sys.num_dims
    dummy_pvt = np.zeros((num_samples, num_dims.pvt))
    dummy_u = np.zeros((num_samples, num_dims.u))

    s_array = np.tile(np.array([init_controller_state]), (num_samples, 1))

    x_array = sample_ival_constraints(init_cons, num_samples)

    if prop.ci is not None:
        ci_lb = prop.ci.l
        ci_ub = prop.ci.h
        ci_array = ci_lb + (ci_ub - ci_lb) * np.random.random(
            (num_samples, num_segments, num_dims.ci))
    else:
        ci_array = np.empty((num_samples, num_segments, num_dims.ci))

    if prop.pi is not None:
        pi_lb = prop.pi.l
        pi_ub = prop.pi.h
        pi_array = pi_lb + (pi_ub - pi_lb) * np.random.random(
            (num_samples, num_segments, num_dims.pi))
    else:
        pi_array = np.empty((num_samples, num_segments, num_dims.pi))
    #pi_array = np.zeros((num_samples, num_dims.pi))

    p_array = dummy_pvt
    d_array = np.tile(np.array(prop.initial_discrete_state), (num_samples, 1))
    u_array = dummy_u
    t_array = np.zeros((num_samples, 1))

    init_conrete_states = state.StateArray(t=t_array,
                                           x=x_array,
                                           d=d_array,
                                           pvt=p_array,
                                           s=s_array,
                                           u=u_array,
                                           pi=pi_array,
                                           ci=ci_array)
    return init_conrete_states
Exemplo n.º 4
0
    def simulate(self, sim_state_array, T):

        num_init_state = sim_state_array.n
        X_array_complete = np.zeros((num_init_state, self.A.num_dim))
        t_array_complete = np.zeros(num_init_state)
        dummy_d_array_complete = np.zeros(num_init_state)
        dummy_p_array_complete = np.zeros(num_init_state)

        # TODO: accessing A introduces a cross reference!!

        inf_array = np.tile(np.inf, self.A.num_dim)

        #        for concrete_state in sim_state_array.iterable():

        for i in xrange(sim_state_array.n):
            cont_state = sim_state_array.cont_states[i, :]
            abs_state = self.A.get_abstract_state(cont_state)

            # All_Predetermined_Reachable_States

            aprs = self.G.neighbors(abs_state)
            if aprs:
                rchd_abs_state = random.choice(aprs)
                cons = self.A.get_concrete_state_constraints(rchd_abs_state)
                X_array = S.sample_interval(cons, 1)
                n = self.A.get_n_for(abs_state)
                t = n * T + T
                t_array_complete[i] = t
                X_array_complete[i, :] = X_array
            else:  # If not state is reachable!

                n = self.A.get_n_for(abs_state)
                t = n * T + T
                t_array_complete[i] = np.tile(t, 1)
                X_array_complete[i, :] = inf_array

        concrete_state_arr = st.StateArray(t_array_complete, X_array_complete,
                                           dummy_d_array_complete,
                                           dummy_p_array_complete)
        return concrete_state_arr
Exemplo n.º 5
0
    def get_reachable_abs_states_reuses_model(self, abs_state, A,
                                              system_params):
        reachable_state_list = []

        # CA = A.controller_abs

        PA = A.plant_abs
        hd = abs_state.cs.hd + 1

        #x = self.get_new_plant_smt_var(str(abs_state.ps))
        #ci = self.get_input_smt_var(uid_str)

        # construct ci smt constraints
        #ci = self.controller_sym_path_obj.ci
        # TODO: sort this mess out...should not know its a list!
        # Need to be made a class or something
        ci = [
            self.path_var_dict['iv_input_arr__' + str(i)]
            for i in range(self.num_dims.ci)
        ]
        ci_ival_cons = system_params.ci
        ci_smt = self.solver.ic2smt(ci_ival_cons, ci)
        # print(ci_smt)

        #x = self.controller_sym_path_obj.x
        x = [
            self.path_var_dict['iv_x_arr__' + str(i)]
            for i in range(self.num_dims.x)
        ]
        X_smt = PA.get_smt2_constraints(abs_state.ps, x)
        # print(X_smt)

        # # substitute the current vars with original program vars

        #print(abs_state.cs.C)
        C_subs = self.substitute_curr_vars(abs_state.cs)
        #print(abs_state.cs.C)
        #exit()
        # print(abs_state.cs.C)

        self.controller_sym_path_obj.set_global_cons(C_subs, ci_smt, X_smt)
        ##self.controller_sym_path_obj.unset_global_cons()

        num_req_samples = A.num_samples

        #print(C_subs)
        #print(ci_smt)
        #print(X_smt)

        uid_str = str(self.gen_id())
        for p_id, pc_solver in self.controller_sym_path_obj.sat_path_gen():

            # TODO: makes life simpler for now...easier to convert solver to
            # constraints and use the existing functions instead of using the
            # solver directly.
            # This must be fixed and the solver should be directly handled to
            # get any performance benefits!
            #
            pid_str = 'p' + str(p_id)
            cumulitive_pid_str = abs_state.cs.cpid + pid_str

            reachable_controller_state = ControllerSymbolicAbstractState(
                C=C_subs,
                si=[
                    self.path_var_dict['iv_int_state_arr__' + str(i)]
                    for i in range(self.num_dims.si)
                ],
                sf=[
                    self.path_var_dict['iv_float_state_arr__' + str(i)]
                    for i in range(self.num_dims.sf)
                ],
                x=[
                    self.path_var_dict['iv_x_arr__' + str(i)]
                    for i in range(self.num_dims.x)
                ],
                si_=[
                    self.path_var_dict['rv_int_state_arr__' + str(i)]
                    for i in range(self.num_dims.si)
                ],
                sf_=[
                    self.path_var_dict['rv_float_state_arr__' + str(i)]
                    for i in range(self.num_dims.sf)
                ],
                u=[
                    self.path_var_dict['rv_output_arr__' + str(i)]
                    for i in range(self.num_dims.u)
                ],
                pid=pid_str,
                cpid=cumulitive_pid_str,
                ci=[
                    self.path_var_dict['iv_input_arr__' + str(i)]
                    for i in range(self.num_dims.ci)
                ],
                hd=hd,
            )

            #   #x=[self.path_var_dict['iv_x_arr__'+str(i)] for i in range(self.num_dims.x)],
            #    #ci=[self.path_var_dict['iv_input_arr__'+str(i)] for i in range(self.num_dims.ci)],
            # protect the solver from the changes the sampler() might make.
            #pc_solver.push()
            (
                x_array,
                u_array,
                si_array,
                sf_array,
                si__array,
                sf__array,
                ci_array,
                num_actual_samples,
            ) = self.sample_smt_solver(reachable_controller_state,
                                       num_req_samples, pc_solver)

            #print('solver', pc_solver)
            #print(x_array)

            #pc_solver.pop()

            pc_ = self.solver.And(*pc_solver.assertions())

            x = self.get_new_plant_smt_var(str(abs_state.ps))
            ci = self.get_input_smt_var(uid_str)
            # print(abs_state.cs)
            si = abs_state.cs.si_  # C'[s] = C[s']
            sf = abs_state.cs.sf_  # C'[s] = C[s']
            (si_, sf_,
             u) = self.get_new_cumulitive_smt_vars(abs_state.cs, uid_str,
                                                   pid_str)

            pc_ = self.instantiate(pc_, si, sf, x, si_, sf_, u, ci)

            reachable_controller_state.C = pc_
            reachable_controller_state.si = si
            reachable_controller_state.sf = sf
            reachable_controller_state.x = x
            reachable_controller_state.si_ = si_
            reachable_controller_state.sf_ = sf_
            reachable_controller_state.u = u
            reachable_controller_state.ci = ci

            # n = actual number of samples

            #(
            #    x_array,
            #    u_array,
            #    si_array,
            #    sf_array,
            #    si__array,
            #    sf__array,
            #    ci_array,
            #    num_actual_samples,
            #)\
            #    = self.get_concrete_states_from_abs_state(reachable_controller_state, num_req_samples)

            # TODO: remove the below d and p arrays
            # One strategy is to separate concrete states of plant and
            # controller

            d_array = np.tile(abs_state.ps.d, (num_actual_samples, 1))
            p_array = np.tile(abs_state.ps.pvt, (num_actual_samples, 1))
            pi_array = np.zeros((num_actual_samples, A.num_dims.pi))
            t = abs_state.plant_state.n * A.delta_t
            ######################################
            #TODO: wrap this up somehow
            print()
            print(term.move_up + term.move_up)
            ######################################
            with term.location():
                print('t:', t)
            t_array = np.tile(t, (num_actual_samples, 1))

            s_array = np.concatenate((si_array, sf_array), axis=1)
            #print('s:', s_array)
            #s__array = np.concatenate((si__array, sf__array))

            state = st.StateArray(
                t=t_array,
                x=x_array,
                d=d_array,
                pvt=p_array,
                s=s_array,
                u=u_array,
                pi=pi_array,
                ci=ci_array,
            )

            # if history depth exceeded, concretize all states!

            if abs_state.cs.hd >= self.max_hd:

                # NOTE: when concretizing, need to pick only one sample
                # Let's pick the first one
                i = 0
                # for i in range(num_actual_samples):

                #reachable_controller_state.C = self.solver.And(
                #        self.solver.equal(si_, si__array[i, :]),
                #        self.solver.equal(sf_, sf__array[i, :]))
                reachable_controller_state.C = self.solver.And(
                    self.solver.equal(si, si__array[i, :]),
                    self.solver.equal(sf, sf__array[i, :]))
                reachable_controller_state.hd = 0
                reachable_state_list.append(
                    (reachable_controller_state, state))

                # clear cpid history as well

                reachable_controller_state.cpid = \
                    reachable_controller_state.pid
            else:
                reachable_state_list.append(
                    (reachable_controller_state, state))

                # print(reachable_controller_state)

        if not reachable_state_list:
            raise err.Fatal('no reachable state found!')

        return reachable_state_list
Exemplo n.º 6
0
def random_test(
        A,
        system_params,
        initial_state_list,
        ci_seq_list,
        pi_seq_list,
        init_cons,
        init_d,
        initial_controller_state,
        sample_ci
        ):

    # ##!!##logger.debug('random testing...')

    A.prog_bar = False

    res = []
    # initial_state_set = set(initial_state_list)

    if A.num_dims.ci != 0:
        if sample_ci:
            ci_seq_array = np.array([np.array(ci_seq_list).T]).T
        else:
            ci_seq_array = np.array(ci_seq_list)

        # print('ci_seq_array', ci_seq_array)
        # print('ci_seq_array.shape', ci_seq_array.shape)

    if A.num_dims.pi != 0:
        pi_seq_array = np.array([np.array(pi_seq_list).T]).T

    #print(ci_seq_array.shape)
    #print(pi_seq_array.shape)
    x_array = np.empty((0.0, A.num_dims.x), dtype=float)

    print('checking initial states')

    # for abs_state in initial_state_set:

    for abs_state in initial_state_list:
        ival_cons = A.plant_abs.get_ival_cons_abs_state(abs_state.plant_state)

        # ##!!##logger.debug('ival_cons: {}'.format(ival_cons))

        # find the intersection b/w the cell and the initial cons
        # print('init_cons', init_cons)

        ic = ival_cons & init_cons
        if ic is not None:

            # scatter the continuous states

            x_samples = SaMpLe.sample_ival_constraints(ic, A.num_samples)

            # ##!!##logger.debug('ic: {}'.format(ic))
            # ##!!##logger.debug('samples: {}'.format(x_samples))

            x_array = np.concatenate((x_array, x_samples))
        else:
            raise err.Fatal('Can not happen! Invalid states have already been filtered out by filter_invalid_abs_states()')

            # # ##!!##logger.debug('{}'.format(samples.x_array))

            # ##!!##logger.debug('ignoring abs states: {}'.format(ival_cons))

            # ignore the state as it is completely outside the initial
            # constraints

    # print(x_array)
    # print(x_array.shape)

    print(x_array.shape)
    num_samples = len(x_array)
    if num_samples == 0:
        print(initial_state_list)
        print('no valid sample found during random testing. STOP')
        return False
    else:

        # ##!!##logger.debug('num_samples = 0')

        print('simulating {} samples'.format(num_samples))

    trace_list = [traces.Trace(A.num_dims, A.N) for i in range(num_samples)]

    s_array = np.tile(initial_controller_state, (num_samples, 1))

#     if system_params.pi is not None:
#         pi_array = SaMpLe.sample_ival_constraints(system_params.pi, num_samples)
#         print(pi_array)
#         exit()
#     else:
#         pi_array = None

    t_array = np.tile(0.0, (num_samples, 1))

    d_array = np.tile(init_d, (num_samples, 1))

    # TODO: initializing pvt states to 0

    p_array = np.zeros((num_samples, 1))

    # save x_array to print x0 in case an error is found
    # TODO: need to do something similar for u,ci,pi

    x0_array = x_array
    d0_array = d_array

    # sanity check

    if len(x_array) != len(s_array):
        raise err.Fatal('internal: how is len(x_array) != len(s_array)?')

    def property_checker(t, Y): return Y in system_params.final_cons

    # while(simTime < A.T):
    sim_num = 0
    simTime = 0.0
    i = 0
    while sim_num < A.N:
        if A.num_dims.ci == 0:
            ci_array = np.zeros((num_samples, 0))
        else:
            if sample_ci:
                ci_cons_list = list(ci_seq_array[:, i, :])
                ci_cons_list = [ci_cons.tolist()[0] for ci_cons in ci_cons_list]

                ci_lb_list = [np.tile(ci_cons.l, (A.num_samples, 1)) for ci_cons in ci_cons_list]
                ci_ub_list = [np.tile(ci_cons.h, (A.num_samples, 1)) for ci_cons in ci_cons_list]

                ci_cons_lb = reduce(lambda acc_arr, arr: np.concatenate((acc_arr, arr)), ci_lb_list)
                ci_cons_ub = reduce(lambda acc_arr, arr: np.concatenate((acc_arr, arr)), ci_ub_list)

                random_arr = np.random.rand(num_samples, A.num_dims.ci)

                ci_array = ci_cons_lb + random_arr * (ci_cons_ub - ci_cons_lb)
            else:
                ci_array = ci_seq_array[:, i, :]
                ci_array = np.repeat(ci_array, A.num_samples, axis=0)

        if A.num_dims.pi == 0:
            pi_array = np.zeros((num_samples, 0))
        else:
            pi_cons_list = list(pi_seq_array[:, i, :])
            pi_cons_list = [pi_cons.tolist()[0] for pi_cons in pi_cons_list]
            #print(pi_cons_list)
            #pi_cons_list = map(A.plant_abs.get_ival_cons_pi_cell, pi_cells)

            pi_lb_list = [np.tile(pi_cons.l, (A.num_samples, 1)) for pi_cons in pi_cons_list]
            pi_ub_list = [np.tile(pi_cons.h, (A.num_samples, 1)) for pi_cons in pi_cons_list]

            pi_cons_lb = reduce(lambda acc_arr, arr: np.concatenate((acc_arr, arr)), pi_lb_list)
            pi_cons_ub = reduce(lambda acc_arr, arr: np.concatenate((acc_arr, arr)), pi_ub_list)

            random_arr = np.random.rand(num_samples, A.num_dims.pi)

#             print('pi_cons_lb.shape:', pi_cons_lb.shape)
#             print('pi_cons_ub.shape:', pi_cons_ub.shape)
#             print('num_samples', num_samples)
            pi_array = pi_cons_lb + random_arr * (pi_cons_ub - pi_cons_lb)

        (s_array_, u_array) = cc.compute_concrete_controller_output(
            A,
            system_params.controller_sim,
            ci_array,
            x_array,
            s_array,
            num_samples,
            )

        concrete_states = st.StateArray(  # t
                                        # cont_state_array
                                        # abs_state.discrete_state
                                        # abs_state.pvt_stat
                                        t_array,
                                        x_array,
                                        d_array,
                                        p_array,
                                        s_array_,
                                        u_array,
                                        pi_array,
                                        ci_array,
                                        )

        # print(concrete_states)

        property_violated_flag = [False]

        rchd_concrete_state_array = system_params.plant_sim.simulate(
                concrete_states,
                A.delta_t,
                property_checker,
                property_violated_flag)

        for kdx, rchd_state in enumerate(rchd_concrete_state_array.iterable()):
            trace = trace_list[kdx]
            trace.append(rchd_state.s, rchd_state.u, rchd_state.x, rchd_state.ci, rchd_state.pi, rchd_state.t, rchd_state.d)

        if property_violated_flag[0]:
            print(U.decorate('concretized!'))
            for (idx, xf) in enumerate(rchd_concrete_state_array.iterable()):
                if xf.x in system_params.final_cons:
                    res.append(idx)
                    print(x0_array[idx, :], d0_array[idx, :], '->', '\t', xf.x, xf.d)
                    #if A.num_dims.ci != 0:
                    #    print('ci:', ci_array[idx])
                    #if A.num_dims.pi != 0:
                    #    print('pi:', pi_array[idx])
            break
        i += 1
        sim_num += 1

        # increment simulation time

        simTime += A.delta_t
        t_array += A.delta_t
        concrete_states = rchd_concrete_state_array
        x_array = concrete_states.cont_states
        s_array = concrete_states.controller_states
        d_array = concrete_states.discrete_states
        p_array = concrete_states.pvt_states

        # u_array =

    return map(trace_list.__getitem__, res)
Exemplo n.º 7
0
    def get_reachable_abs_states(
        self,
        abs_state,
        A,
        system_params,
    ):
        #ci_ival_cons = system_params.ci
        #pi_ival_cons = system_params.pi

        # can have more samples than A.num_samples due to more than one pi_cell
        # associated with abs_state
        samples = system_params.sampler.sample(abs_state, A, system_params,
                                               A.num_samples)

        total_num_samples = samples.n

        # ##!!##logger.debug('num_samples = {}'.format(total_num_samples))
        # ##!!##logger.debug('samples = \n{}'.format(samples))
        # ##!!##logger.debug(U.decorate('sampling done'))

        x_array = samples.x_array
        s_array = samples.s_array

        # print s_array

        t_array = samples.t_array
        pi_array = samples.pi_array
        #if ci_ival_cons is None:
        #ci_array = np.zeros((total_num_samples, 1))
        #else:
        #    ci_array = samples.ci_array
        ci_array = samples.ci_array

        # ci_array = S.sample_ival_constraints(ci_ival_cons, total_num_samples)

        # TODO: knows that d is an np array

        d = np.array([abs_state.plant_state.d])
        pvt = np.array([abs_state.plant_state.pvt])

        d_array = np.repeat(d, samples.n, axis=0)
        pvt_array = np.repeat(pvt, samples.n, axis=0)

        # sanity check

        if len(d_array) == total_num_samples and len(pvt_array) \
            == total_num_samples and len(x_array) == total_num_samples \
            and len(s_array) == total_num_samples and len(t_array) \
            == total_num_samples:
            pass
        else:
            raise err.Fatal('sanity_check fails')

        # print x_array, s_array

        (s_array_, u_array) = cc.compute_concrete_controller_output(
            A,
            system_params.controller_sim,
            ci_array,
            x_array,
            s_array,
            total_num_samples,
        )

        # print s_array_, u_array
        # print samples.ci_array

        ######################################
        #TODO: wrap this up somehow
        print()
        print(term.move_up + term.move_up)
        ######################################
        with term.location():
            print('t:', t_array.T)

        state = st.StateArray(
            t=t_array,
            x=x_array,
            d=d_array,
            pvt=pvt_array,
            s=s_array_,
            u=u_array,
            pi=pi_array,
            ci=ci_array,
        )

        return state
Exemplo n.º 8
0
    def simulate(
        self,
        sim_states,
        T,
        property_checker=None,
        property_violated_flag=None,
    ):

        # print sim_states.cont_states
        # print sim_states.discrete_states
        # print sim_states.pvt_states

        T_array = np.array([T])
        comm = self.communicator
        comm.put_value('t', sim_states.t)
        comm.put_value('initial_continuous_states', sim_states.cont_states)
        comm.put_value('initial_discrete_states', sim_states.discrete_states)
        comm.put_value('initial_pvt_states', sim_states.pvt_states)
        comm.put_value('control_inputs', sim_states.controller_outputs)
        comm.put_value('T', T_array)
        if property_checker is None:
            comm.put_value('property_check', np.array([0]))
        else:
            comm.put_value('property_check', np.array([1]))

        # TODO: dummy control input!

        comm.put_value('inputs', np.zeros(sim_states.cont_states.shape))

        #        # TODO: dummy exogenous input!
        #        comm.put_value('inputs', np.zeros(sim_states.cont_states.shape))

        ret_val_str_list = ['ret_t', 'ret_X', 'ret_D', 'ret_P', 'pvf']
        arg_str_list = [
            'sim_function',
            't',
            'T',
            'initial_continuous_states',
            'initial_discrete_states',
            'initial_pvt_states',
            'control_inputs',
            'inputs',
            'property_check',
        ]

        if self.parallel:
            print 'unhandled..modify signature to include time first'
            exit()
            fun_name_str = 'simulate_system_par'
            [X_, D_,
             P_] = comm.call_function_retVal(ret_val_str_list, fun_name_str,
                                             arg_str_list)
        else:
            fun_name_str = 'simulate_system'
            [T_, X_, D_, P_,
             pvf] = comm.call_function_retVal(ret_val_str_list, fun_name_str,
                                              arg_str_list)

        # print 'output'
        # print X_
        # print D_
        # print P_
        # print '='*20
        # t_array = np.tile(T, (sim_states.n))
        # property_violated_flag = property_checker

        if property_checker is not None:
            property_violated_flag[0] = bool(pvf)

            # print pvf, property_violated_flag[0]
        # return st.StateArray(t_array, X_, D_, P_)
        # TODO: fix this weird matlab-numpy interfacing

        t_array = np.array(T_, ndmin=2).T
        x = np.array(X_, ndmin=2)
        if D_.ndim <= 1:
            d = np.array(D_, ndmin=2).T
        else:
            d = D_
        if P_.ndim <= 1:
            pvt = np.array(P_, ndmin=2).T
        else:
            pvt = P_
        return st.StateArray(
            t=t_array,
            x=x,
            d=d,
            pvt=pvt,
            s=sim_states.controller_states,
            u=sim_states.controller_outputs,
            pi=sim_states.plant_extraneous_inputs,
            ci=sim_states.controller_extraneous_inputs,
        )
Exemplo n.º 9
0
    def simulate(
        self,
        sim_states,
        T,
        property_checker=None,
        property_violated_flag=None,
    ):

        #print '='*100
        #print sim_states
        #print '='*100

        if property_checker is None:
            property_check = 0
        else:
            property_check = 1

        matlab = self.matlab

        m_t = matlab.double(sim_states.t.tolist())
        m_T = matlab.double([T])
        m_c = matlab.double(sim_states.cont_states.tolist())
        m_d = matlab.double(sim_states.discrete_states.tolist())
        m_p = matlab.double(sim_states.pvt_states.tolist())
        m_u = matlab.double(sim_states.controller_outputs.tolist())
        #m_p = matlab.double([0.0] * sim_states.cont_states.shape[0])
        m_pi = matlab.double(sim_states.plant_extraneous_inputs.tolist())
        #m_pc = matlab.double([property_check])
        m_pc = property_check

        #TAG:CLSS
        if self.sim_is_class:
            [T__, X__, D__, P__, pvf_] = self.eng.simulate_plant(
                self.sim_obj,
                m_t,
                m_T,
                m_c,
                m_d,
                m_p,
                m_u,
                m_pi,
                m_pc,
            )
        else:
            [T__, X__, D__, P__, pvf_] = self.eng.simulate_plant_fun(
                self.m_fun_str,
                m_t,
                m_T,
                m_c,
                m_d,
                m_p,
                m_u,
                m_pi,
                m_pc,
            )

        T_ = np.array(T__)
        X_ = np.array(X__)
        D_ = np.array(D__)
        P_ = np.array(P__)
        #print T__, X__
        #print T_, X_

        pvf = pvf_

        if property_checker is not None:
            property_violated_flag[0] = bool(pvf)

        # TODO: fix this weird matlab-numpy interfacing
        # FIXED: is it correct though?
        t_array = np.array(T_, ndmin=2)
        x = np.array(X_, ndmin=2)
        if D_.ndim <= 1:
            d = np.array(D_, ndmin=2).T
        else:
            d = D_
        if P_.ndim <= 1:
            pvt = np.array(P_, ndmin=2).T
        else:
            pvt = P_
        statearray = st.StateArray(
            t=t_array,
            x=x,
            d=d,
            pvt=pvt,
            s=sim_states.controller_states,
            u=sim_states.controller_outputs,
            pi=sim_states.plant_extraneous_inputs,
            ci=sim_states.controller_extraneous_inputs,
        )
        #print '='*100
        #print statearray
        #print '='*100
        return statearray