def encode_initialization(self): for q, m in product(self.automaton.initial_nodes, [self.model_init_state]): vals_by_vars = self._build_args_dict(smt_name_m(m), None, q) self.solver.assert_( self.solver.call_func( self.reach_func_desc, vals_by_vars))
def _encode_transitions(self, q:Node, m, i_o:Label, state_to_rejecting_scc:dict): # syntax sugar def smt_r(args): return self.solver.call_func(self.r_func_desc, args) def smt_reach(args): return self.solver.call_func(self.reach_func_desc, args) # smt_m = smt_name_m(m) args_dict = self._build_args_dict(smt_m, i_o, q) free_input_args = self._get_free_input_args(i_o) smt_out = self._smt_out(i_o, smt_m, q) smt_pre = self.solver.op_and([smt_reach(args_dict), smt_out]) dst_set = q.transitions[i_o] smt_m_next = self.solver.call_func(self.tau_desc, args_dict) smt_post_conjuncts = [] for q_next, is_rejecting in dst_set: if q_next is DEAD_END or 'accept_all' in q_next.name: # TODO: hack smt_post_conjuncts = [self.solver.false()] break args_dict_next = self._build_args_dict(smt_m_next, None, q_next) smt_post_conjuncts.append(smt_reach(args_dict_next)) greater_op = self._get_greater_op(q, is_rejecting, q_next, state_to_rejecting_scc) if greater_op is not None: smt_post_conjuncts.append(greater_op(smt_r(args_dict_next), smt_r(args_dict))) smt_post = self.solver.op_and(smt_post_conjuncts) pre_implies_post = self.solver.op_implies(smt_pre, smt_post) self.solver.assert_( self.solver.forall_bool(free_input_args, pre_implies_post))
def _get_all_possible_inputs(self, func_desc:FuncDesc): arg_type_pairs = func_desc.inputs get_values = lambda t: { 'Bool': ('true', 'false'), TYPE_MODEL_STATE: [smt_name_m(m) for m in self.last_allowed_states], TYPE_A_STATE: [smt_name_spec(s, TYPE_A_STATE) for s in self.automaton.nodes] }[t] records = product(*[get_values(t) for (_,t) in arg_type_pairs]) args = list(map(lambda a_t: a_t[0], arg_type_pairs)) dicts = [] for record in records: assert len(args) == len(record) arg_value_pairs = zip(args, record) dicts.append(dict(arg_value_pairs)) return dicts
def encode_model_bound(self, allowed_model_states): self.solver.comment('encoding model bound: ' + str(allowed_model_states)) # all args of tau function are quantified args_dict = dict((a, smt_name_free_arg(a)) for (a,ty) in self.tau_desc.inputs) free_vars = [(args_dict[a],ty) for (a,ty) in self.tau_desc.inputs] smt_m_next = self.solver.call_func(self.tau_desc, args_dict) disjuncts = [] for allowed_m in allowed_model_states: disjuncts.append(self.solver.op_eq(smt_m_next, smt_name_m(allowed_m))) condition = self.solver.forall(free_vars, self.solver.op_or(disjuncts)) self.solver.assert_(condition) self.last_allowed_states = allowed_model_states
def _encode_model_functions(self, model_states): self.solver.declare_enum(TYPE_MODEL_STATE, [smt_name_m(m) for m in model_states]) self._define_declare_functions([self.tau_desc]) self._define_declare_functions(self.descr_by_output.values())