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
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
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]
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
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
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
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
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
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
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
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
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
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
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
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