示例#1
0
 def is_unsat(self):
     models, _ = Z3.get_models(self.expr(), k=1)
     return models is False
示例#2
0
    def get_models(self, f, k, inp_decls=None, using_random_seed=False):
        if not using_random_seed:
            return Z3.get_models(f, k)

        def is_z3_assertions(f):
            return z3.is_expr(f) or isinstance(f, z3.AstVector)

        assert is_z3_assertions(f) or isinstance(
            f, logic.ZFormula), '{}: {}'.format(type(f), f)
        assert k >= 1, k

        if is_z3_assertions(f):
            fe = f
        else:
            fe = f.expr()

        is_nla = False
        fe_terms = self.get_mul_terms(fe)
        fe_nonlinear_terms = list(
            itertools.filterfalse(lambda t: not self.is_nonlinear_mul_term(t),
                                  fe_terms))
        if fe_nonlinear_terms:
            is_nla = True

        # mlog.debug("is_nla: {}".format(is_nla))
        # solver = Z3.create_solver()
        solver = self.mk(is_nla)
        # solver = z3.SolverFor('QF_NRA')

        pushed_labeled_conjs = False
        labeled_conjs = {}

        if isinstance(f, logic.ZConj):
            # solver.push()
            # pushed_labeled_conjs = True
            # solver.set(unsat_core=True)
            # solver.set(':core.minimize', True)
            for conj in f:
                if isinstance(conj, logic.LabeledExpr):
                    if conj.label:
                        conj_label = conj.label
                    else:
                        conj_label = 'c_' + str(self._get_expr_id(conj.expr))
                    # mlog.debug("conj: {}:{}".format(conj.expr, conj_label))
                    # solver.assert_and_track(conj.expr, conj_label)
                    labeled_conjs[conj_label] = conj.expr
                else:
                    solver.add(conj)
        else:
            solver.add(fe)

        if labeled_conjs:
            solver.push()
            pushed_labeled_conjs = True
            solver.add([conj for _, conj in labeled_conjs.items()])

        # stat = solver.check()
        # psolver = PySMT()
        # stat, _ = PySMT.check_sat(solver)
        stat, _ = self.check_sat(solver, is_nla)
        unsat_core = None

        # mlog.debug("stat: {}".format(stat))
        if stat == z3.unknown:
            # mlog.debug("reason_unknown: {}".format(solver.reason_unknown()))
            rs = None
        elif stat == z3.unsat:
            if pushed_labeled_conjs:
                # unsat_core = solver.unsat_core()
                # mlog.debug("unsat_core: {}".format(unsat_core))

                pushed_labeled_conj = False
                solver.pop()
                soft_labeled_constraints = [
                    (lbl, conj) for (lbl, conj) in labeled_conjs.items()
                ]
                unsat_core = self._get_unsat_core(solver, is_nla,
                                                  soft_labeled_constraints)
            rs = False
        else:
            # sat, get k models
            if pushed_labeled_conjs:
                pushed_labeled_conjs = False
                # solver.pop()
                # solver.add([conj for _, conj in labeled_conjs.items()])

            range_constrs = []
            if inp_decls:
                inp_ranges = list(dig_prog.Prog._get_inp_ranges(
                    len(inp_decls)))
                random.shuffle(inp_ranges)
                # mlog.debug("inp_ranges ({}): {}".format(len(inp_ranges), inp_ranges))
                inp_exprs = inp_decls.exprs(settings.use_reals)
                for inp_range in inp_ranges:
                    range_constr = z3.And([
                        z3.And(ir[0] <= v, v <= ir[1])
                        for v, ir in zip(inp_exprs, inp_range)
                    ])
                    # mlog.debug("range_constr: {}".format(range_constr))
                    range_constrs.append(range_constr)

            models = []
            model_stat = {}
            i = 0
            # while solver.check() == z3.sat and i < k:
            while i < k:
                # mlog.debug("{} -> {}".format(i, k))
                chk, m = self.check_sat_and_get_rand_model(
                    solver, is_nla, range_constrs)
                # mlog.debug("chk: {}".format(chk))
                # mlog.debug("m: {}".format(m))
                if chk != z3.sat or not m:
                    break
                i = i + 1
                models.append(m)
                block_cs = []
                for (x, v) in m:
                    model_stat.setdefault(x, {})
                    if isinstance(v, (int, float)):
                        c = model_stat[x].setdefault(v, 0)
                        model_stat[x][v] = c + 1
                        block_cs.append(z3.Int(x) == v)
                # mlog.debug("model {}: {}".format(i, m))
                # create new constraint to block the current model
                if block_cs:
                    block_c = z3.Not(z3.And(block_cs))
                    solver.add(block_c)
                for (x, v) in m:
                    if model_stat[x][v] / k > 0.1:
                        # block_x = z3.Int(x) != v
                        block_x = z3.Not(z3.Int(x) == v)
                        # mlog.debug("block_x: {}".format(block_x))
                        solver.add(block_x)

            # mlog.debug("models: {}".format(models))

            if models:
                rs = models
            else:
                rs = None
                stat = z3.unknown

        assert not (isinstance(rs, list) and not rs), rs
        return rs, stat, unsat_core
示例#3
0
    def implies(self, conseq):
        fante = self.expr()
        fconseq = conseq.expr()

        models, _ = Z3.get_models(z3.Not(z3.Implies(fante, fconseq)), k=1)
        return models is False