def test_disj_partitioning(self): for (f, _, _, logic) in get_example_formulae(): if self.env.factory.has_solvers(logic=logic): disjuncts = list(disjunctive_partition(f)) try: ok = is_valid(Iff(f, Or(disjuncts)), logic=logic) except SolverReturnedUnknownResultError: ok = not logic.quantifier_free self.assertTrue(ok)
def test_disj_partitioning(self): for (f, _, _, logic) in get_example_formulae(): if get_env().factory.has_solvers(logic=logic): disjuncts = list(disjunctive_partition(f)) try: ok = is_valid(Iff(f, Or(disjuncts)), logic=logic) except SolverReturnedUnknownResultError: ok = not logic.quantifier_free self.assertTrue(ok)
def parametric_safety(self, prop, k_max, k_min, parameters, monotonic=True, at_most=-1): if len(parameters) == 0: Logger.error("Parameters size cannot be 0") lemmas = self.hts.lemmas self._init_at_time(self.hts.vars, k_max) monotonic = True # if monotonic: # for p in parameters: # self.set_preferred((p, False)) self.region = FALSE() generalize = lambda model, t: self._get_param_assignments( model, t, parameters, monotonic) if at_most == -1: cardinality = len(parameters) else: cardinality = at_most prev_cs_count = 0 prove = self.config.prove step = 5 same_res_counter = 0 k = step end = False has_next = TS.has_next(prop) # Strategy selection increase_k = False if cardinality == -2: (t, status) = self.solve_safety_inc_fwd(self.hts, prop, k_max, k_min, all_vars=False, generalize=generalize) else: sn = SortingNetwork.sorting_network(parameters) if increase_k: # Approach with incremental increase of bmc k while k < k_max + 1: for at in range(cardinality): Logger.msg("[%d,%d]" % ((at + 1), k), 0, not (Logger.level(1))) sn_k = sn[at + 1] if at + 1 < len(sn) else FALSE() bound_constr = Or(sn_k, self.region) bound_constr = bound_constr if not has_next else Or( bound_constr, TS.to_next(bound_constr)) self.config.prove = False (t, status) = self.solve_safety_inc_bwd( self.hts, Or(prop, bound_constr), k, generalize=generalize) if (prev_cs_count == self.cs_count): same_res_counter += 1 else: same_res_counter = 0 prev_cs_count = self.cs_count if (prove == True) and ((same_res_counter > 1) or (at == cardinality - 1)): Logger.msg("[>%d,%d]" % ((at + 1), k), 0, not (Logger.level(1))) if (at_most > -1) and (at_most < cardinality): sn_k = sn[at_most - 1] else: sn_k = FALSE() bound_constr = Or(sn_k, self.region) bound_constr = bound_constr if not has_next else Or( bound_constr, TS.to_next(bound_constr)) self.config.prove = True (t, status) = self.solve_safety( self.hts, Or(prop, bound_constr), k, max(k_min, k - step)) if status == True: end = True break if (same_res_counter > 2) and (k < k_max): break if end: break k += step else: # Approach with fixed bmc k for at in range(cardinality): Logger.msg("[%d]" % ((at + 1)), 0, not (Logger.level(1))) sn_k = sn[at + 1] if at + 1 < len(sn) else FALSE() bound_constr = Or(sn_k, self.region) bound_constr = bound_constr if not has_next else Or( bound_constr, TS.to_next(bound_constr)) self.config.prove = False (t, status) = self.solve_safety_inc_bwd( self.hts, Or(prop, bound_constr), k_max, generalize=generalize) if simplify(self.region) == TRUE(): break if (prev_cs_count == self.cs_count): same_res_counter += 1 else: same_res_counter = 0 prev_cs_count = self.cs_count if (prove == True) and ((same_res_counter > 1) or (at == cardinality - 1)): Logger.msg("[>%d]" % ((at + 1)), 0, not (Logger.level(1))) if (at_most > -1) and (at_most < cardinality): sn_k = sn[at_most - 1] else: sn_k = FALSE() bound_constr = Or(sn_k, self.region) bound_constr = bound_constr if not has_next else Or( bound_constr, TS.to_next(bound_constr)) self.config.prove = True (t, status) = self.solve_safety(self.hts, Or(prop, bound_constr), k_max, k_min) if status == True: break traces = None if (self.models is not None) and (simplify(self.region) not in [TRUE(), FALSE()]): traces = [] for (model, time) in self.models: model = self._remap_model(self.hts.vars, model, time) trace = self.generate_trace(model, time, get_free_variables(prop)) traces.append(trace) region = [] dass = {} # Sorting result by size for ass in list(disjunctive_partition(self.region)): cp = list(conjunctive_partition(ass)) size = len(cp) if size not in dass: dass[size] = [] dass[size].append(ass) indexes = list(dass.keys()) indexes.sort() for size in indexes: region += dass[size] if status == True: return (VerificationStatus.TRUE, traces, region) elif status is not None: return (VerificationStatus.FALSE, traces, region) else: return (VerificationStatus.UNK, traces, region)