Beispiel #1
0
    def __init__(self, logic,
                 spec_state_prefix, counters_postfix,
                 sys_state_type_by_process,
                 underlying_solver:SolverInterface):
        self._underlying_solver = underlying_solver

        self._logger = logging.getLogger(__name__)

        self._logic = logic

        self._spec_states_type = spec_state_prefix

        self._la_q_name = 'q'
        self._la_s_name = 's'

        counters_inputs = {self._la_q_name: self._spec_states_type}
        counters_inputs.update((self._la_s_name + str(i), s)
                               for (i, s) in enumerate(sys_state_type_by_process))

        self._laB_func_desc = FuncDescription('laB' + counters_postfix, counters_inputs, 'Bool', None)
        self._laC_func_desc = FuncDescription('laC' + counters_postfix, counters_inputs,
                                              logic.counters_type(sys.maxsize),
                                              None)

        self._last_only_states = None
Beispiel #2
0
    def _get_desc_is_active(
            self,
            proc_index: int):  # TODO: should not dependent on proc_index!
        #: :type: FuncDescription
        sends_func = self.outvar_desc_by_process[proc_index][
            self._sends_signals[proc_index]]
        assert len(sends_func.inputs) == 1, 'consider easy case for now'
        assert list(
            sends_func.inputs
        )[0][0] == self.state_arg_name, 'consider easy case for now'
        sends_args = sends_func.get_args_list(
            {self.state_arg_name: self.state_arg_name})

        #: :type: QuantifiedSignal
        sends_prev_signal = self._sends_prev_signals[proc_index]

        sched_eq_proc_arg_by_signal = self._get_equal_func_args(
            lmap(str, self._sched_signals), lmap(str, self._proc_signals))

        sched_eq_proc_args = self._get_desc_equal_bools().get_args_list(
            sched_eq_proc_arg_by_signal)

        prev_is_sched_args = map(lambda signal_type: str(signal_type[0]),
                                 self._get_desc_prev_next_is_sched(
                                     True).inputs)  # order is important

        if self.nof_processes > 1:
            body_template = '(or ({equal_bits} {sched_eq_proc_args}) \n' \
                            '    (and {sends_prev} ({prev_is_sched} {prev_is_sched_args}) )' \
                            ')'
        else:
            assert self.nof_processes == 1
            body_template = '(or ({equal_bits} {sched_eq_proc_args}) \n' \
                            '    {sends_prev})'

        body = body_template.format_map({
            'equal_bits':
            self._EQUAL_BITS_NAME,
            'sched_eq_proc_args':
            ' '.join(sched_eq_proc_args),
            'prev_is_sched':
            self._PREV_IS_SCHED_NAME,
            'prev_is_sched_args':
            ' '.join(prev_is_sched_args),
            'sends_prev':
            str(sends_prev_signal),
            'sends':
            sends_func.name,
            'sends_args':
            ' '.join(sends_args),
        })

        type_by_arg = dict([(sends_prev_signal, 'Bool')] +
                           self._sched_arg_type_pairs +
                           self._proc_arg_type_pairs)

        description = FuncDescription(self._IS_ACTIVE_NAME, type_by_arg,
                                      'Bool', body)

        return description
Beispiel #3
0
    def _get_taus_descs(self, inputs):
        tau_desc = FuncDescription(
            'tau',
            dict([(self.state_arg_name, self._state_type)] +
                 [(s, 'Bool') for s in inputs]), self._state_type, None)

        return [tau_desc]
Beispiel #4
0
    def _build_tau_desc(self, model_inputs):
        type_by_signal = dict([(self.state_arg_name, self._state_type)] +
                              [(s, 'Bool') for s in model_inputs])
        tau_desc = FuncDescription(self._tau_name, type_by_signal,
                                   self._state_type, None)

        return tau_desc
Beispiel #5
0
    def _get_desc_local_tau(self, local_tau_input_signals) -> FuncDescription:
        type_by_arg = dict([(self.state_arg_name, self._state_type)] +
                           [(s, 'Bool') for s in local_tau_input_signals])

        description = FuncDescription(self._TAU_NAME, type_by_arg,
                                      self._state_type, None)

        return description
Beispiel #6
0
    def _build_outvar_descs(self, outputs, inputs):
        descs = {}
        for s in outputs:
            type_by_signal = {self.state_arg_name: self._state_type}
            if self.is_mealy:
                type_by_signal.update((s, 'Bool') for s in inputs)

            description = FuncDescription(s.name, type_by_signal, 'Bool', None)

            descs[s] = description

        return descs
Beispiel #7
0
    def _get_desc_equal_bools(self):
        cmp_stmnt = self.underlying_solver.op_and(
            map(lambda p: '(= {0} {1})'.format(p[0], p[1]),
                zip(self._equals_first_args, self._equals_second_args)))

        body = '{cmp}'.format(cmp=cmp_stmnt)

        inputname_to_type = dict([(s, 'Bool')
                                  for s in self._equals_first_args] +
                                 [(s, 'Bool')
                                  for s in self._equals_second_args])

        description = FuncDescription(self._EQUAL_BITS_NAME, inputname_to_type,
                                      'Bool', body)

        return description
Beispiel #8
0
    def _build_func_model_from_smt(self, func_smt_lines, func_desc: FuncDescription) -> dict:
        """ Return transition(output) graph {label:output}
        """
        func_model = {}

        for l in func_smt_lines:
            #            (get-value ((tau t0 true true)))
            l = l.replace("get-value", "").replace("(", "").replace(")", "")
            tokens = l.split()
            if tokens[0] != func_desc.name:
                continue

            values = self._parse_values(tokens[1:])  # the very first - func_name
            args = Label(func_desc.get_args_dict(values[:-1]))
            func_model[args] = values[-1]

        return func_model
Beispiel #9
0
    def _do_desc_by_out(self, out_signals, is_mealy: bool,
                        model_inputs) -> dict:
        desc_by_signal = dict()

        for s_ in out_signals:
            #: :type: QuantifiedSignal
            s = s_

            type_by_arg = {self.state_arg_name: self._state_type}

            if is_mealy:
                type_by_arg.update((s, 'Bool') for s in model_inputs)

            desc_by_signal[s] = FuncDescription(s.name, type_by_arg, 'Bool',
                                                None)

        return desc_by_signal
Beispiel #10
0
    def _build_func_model_from_smt(self, func_smt_lines, func_desc:FuncDescription) -> dict:
        """ Return transition(output) graph {label:output}
        """
        func_model = {}

        for l in func_smt_lines:
        #            (get-value ((tau t0 true true)))
            l = l.replace('get-value', '').replace('(', '').replace(')', '')
            tokens = l.split()
            if tokens[0] != func_desc.name:
                continue

            values = self._parse_values(tokens[1:])  # the very first - func_name
            args = Label(func_desc.get_args_dict(values[:-1]))
            func_model[args] = values[-1]

        return func_model
Beispiel #11
0
    def _build_desc_by_outvar(
            self, output_signals, archi_outputs,
            all_model_inputs):  # TODO: mess -- self.arg vs arg to the function
        desc_by_signal = dict()
        for s_ in output_signals:
            #: :type: QuantifiedSignal
            s = s_

            type_by_signal = {self.state_arg_name: self._state_type}

            if self.is_mealy and s not in archi_outputs:
                type_by_signal.update((s, 'Bool') for s in all_model_inputs)

            desc_by_signal[s] = FuncDescription(s.name, type_by_signal, 'Bool',
                                                None)

        return desc_by_signal
Beispiel #12
0
def call_func(func_desc:FuncDescription, func_args_dict:dict):
    func_name = func_desc.name
    smt_func_args_dict = dict()
    for (var,val) in func_args_dict.items():
        if val is True:
            val = true()
        elif val is False:
            val = false()
        smt_func_args_dict[var] = val

    func_args_dict = smt_func_args_dict

    args = func_desc.get_args_list(func_args_dict)  # TODO: bad dependence

    smt_str = '(' + func_name + ' '
    for arg in args:
        smt_str += str(arg) + ' '
    if len(args):
        smt_str = smt_str[:-1]
    smt_str += ')'

    return smt_str
Beispiel #13
0
def call_func(func_desc: FuncDescription, func_args_dict: dict):
    func_name = func_desc.name
    smt_func_args_dict = dict()
    for (var, val) in func_args_dict.items():
        if val is True:
            val = true()
        elif val is False:
            val = false()
        smt_func_args_dict[var] = val

    func_args_dict = smt_func_args_dict

    args = func_desc.get_args_list(func_args_dict)  # TODO: bad dependence

    smt_str = '(' + func_name + ' '
    for arg in args:
        smt_str += str(arg) + ' '
    if len(args):
        smt_str = smt_str[:-1]
    smt_str += ')'

    return smt_str
Beispiel #14
0
    def _get_desc_tau_sched_wrapper(self, proc_index: int,
                                    all_models_inputs) -> FuncDescription:
        local_tau_input_signals = _filter_by_proc(proc_index,
                                                  all_models_inputs)
        local_tau_arg_type_pairs = self._get_desc_local_tau(
            local_tau_input_signals).inputs

        type_by_signal = dict(local_tau_arg_type_pairs +
                              self._sched_arg_type_pairs +
                              self._proc_arg_type_pairs)

        local_tau_arg_type_pairs = list(
            map(lambda signal_type: signal_type[0], local_tau_arg_type_pairs))

        is_active_desc = self._get_desc_is_active(proc_index)
        is_active_inputs = lmap(
            lambda signal: signal[0], is_active_desc.inputs
        )  # TODO: hack: knowledge: var names are the same

        body = """
        (ite ({is_active} {is_active_inputs}) ({tau} {local_tau_inputs}) {state})
        """.format_map({
            'tau':
            self._TAU_NAME,
            'local_tau_inputs':
            ' '.join(map(str, local_tau_arg_type_pairs)),
            'state':
            self.state_arg_name,
            'is_active':
            self._IS_ACTIVE_NAME,
            'is_active_inputs':
            ' '.join(map(str, is_active_inputs))
        })

        description = FuncDescription(self._TAU_SCHED_WRAPPER_NAME,
                                      type_by_signal, self._state_type, body)

        return description
Beispiel #15
0
    def _get_desc_prev_next_is_sched(self, get_prev: bool):
        enum_clauses = []

        if get_prev:
            accumulator = lambda prev, crt: self._accumulator(
                prev, crt, enum_clauses)
            func_name = self._PREV_IS_SCHED_NAME
        else:
            accumulator = lambda prev, crt: self._accumulator(
                crt, prev, enum_clauses)
            func_name = self._NEXT_IS_SCHED_NAME

        self._ring_modulo_iterate(self.nof_processes, accumulator)

        type_by_arg = dict(self._sched_arg_type_pairs +
                           self._proc_arg_type_pairs)

        body = '(or {enum_clauses})'.format(
            enum_clauses='\n\t'.join(enum_clauses))

        description = FuncDescription(func_name, type_by_arg, 'Bool', body)

        return description