Пример #1
0
def simplify_constraints(spl_name, constraints, simplify_mode):
    """
	This function simplifies the SMT constraint in input following the simplify_mode
	:param spl_name: the name of the spl from which the constraint has been extracted
	:param constraints: the extracted constraint (actually, a list of constraints)
	:param simplify_mode: mode of simplification.
		"default" means that
	:return:
	"""
    if simplify_mode == "default":
        formula = z3.simplify(smt_and(constraints))
        if z3.is_false(formula):
            logging.warning("Dependencies in package " + spl_name +
                            " make it uninstallable.")
        return [formula]
    elif simplify_mode == "individual":
        formulas = []
        for c in constraints:
            formula = z3.simplify(c)
            if z3.is_false(formula):
                logging.warning("Dependencies in package " + spl_name +
                                " make it uninstallable.")
                return [smt_false]
            formulas.append(formula)
        return formulas
Пример #2
0
    def jumpi_(self, global_state):
        state = global_state.mstate
        disassembly = global_state.environment.code
        states = []

        op0, condition = state.stack.pop(), state.stack.pop()

        try:
            jump_addr = util.get_concrete_int(op0)
        # FIXME: to broad exception handler
        except:
            logging.debug("Skipping JUMPI to invalid destination.")
            return [global_state]

        index = util.get_instruction_index(disassembly.instruction_list,
                                           jump_addr)

        if not index:
            logging.debug("Invalid jump destination: " + str(jump_addr))
            return [global_state]
        instr = disassembly.instruction_list[index]

        # True case
        condi = simplify(condition) if type(
            condition) == BoolRef else condition != 0
        if instr['opcode'] == "JUMPDEST":
            if (type(condi) == bool and condi) or (type(condi) == BoolRef
                                                   and not is_false(condi)):
                new_state = copy(global_state)
                new_state.mstate.pc = index
                new_state.mstate.depth += 1

                new_state.mstate.constraints.append(condi if type(condi) ==
                                                    bool else simplify(condi))

                states.append(new_state)
            else:
                logging.debug("True, Pruned unreachable states. at %s" %
                              (state.pc))

        # False case
        negated = simplify(
            Not(condition)) if type(condition) == BoolRef else condition == 0

        if (type(negated) == bool and negated) or (type(negated) == BoolRef
                                                   and not is_false(negated)):
            new_state = copy(global_state)
            new_state.mstate.depth += 1
            new_state.mstate.constraints.append(negated if type(negated) ==
                                                bool else simplify(negated))
            states.append(new_state)
        else:
            logging.debug("False, Pruned unreachable states. at %s" %
                          (state.pc))

        return states
Пример #3
0
def is_false(a: Bool) -> bool:
    """Returns whether the provided bool can be simplified to false.

    :param a:
    :return:
    """
    return z3.is_false(a.raw)
Пример #4
0
    def is_false(self) -> bool:
        """Specifies whether this variable can be simplified to false.

        :return:
        """
        self.simplify()
        return z3.is_false(self.raw)
Пример #5
0
def false(value):
    """Syntactic sugar for `z3.is_false(simplify(value))`.

    i.e., return True iff `value` statically simplifies to False.
    """

    return z3.is_false(simplify(value))
Пример #6
0
def marco(Pk):
    print 'Starting to think about...', Pk
    sys.stdout.flush()
    solver = z3.Solver()
    P = []
    for line_number in conjecture_line_numbers:
        P.append(z3.Bool('P_' + str(line_number)))
    out = []
    while True:
        if solver.check() == z3.sat:
            m = solver.model()
            #seed = [conjecture_line_numbers[i] for i, Pi in enumerate(P) if m.eval(Pi, model_completion=True)]
            seed = [conjecture_line_numbers[i] for i, Pi in enumerate(P) if not z3.is_false(m[Pi])]
            #print 'Got seed:', seed
            if query(Pk, set(seed), set()):
                seed = shrink(Pk, seed)
                #print 'Shrank to:', seed, 'which works'
                out.append(seed)
                block = z3.Or([z3.Not(P[i]) for i, line_number in enumerate(conjecture_line_numbers) if line_number in seed])
                #print 'Blocking:', block
                solver.add(block)
            else:
                seed = grow(Pk, seed)
                #print 'Grew to:', seed, 'which does not work'
                block = z3.Or([P[i] for i, line_number in enumerate(conjecture_line_numbers) if line_number not in seed])
                #print 'Blocking:', block
                solver.add(block)
        else:
            #print out
            break
    print 'Fully analyzed...', Pk
    sys.stdout.flush()
    return out
Пример #7
0
    def _set(self, k, v):
        """An internal API used for actually building relations.

        Not meant to be used from outside the module.
        """

        # Typechecking
        if not isinstance(k, tuple):
            raise TypeError(k)
        if not isinstance(v, z3.BoolRef) and not isinstance(v, bool):
            raise TypeError(v)

        # Make sure the arity of `k` matches the arity of other keys in self
        if self.arity is None:
            self.arity = len(k)
        elif self.arity != len(k):
            raise TypeError(f"`Relation` has arity {self.arity}, "
                            f"but adding a key of arity {len(k)}")

        # No use adding `v` if it is known to be false.
        if v is True:
            # Convert Python type to z3 type
            super().__setitem__(k, z3.BoolVal(True))
        elif v is not False:
            # v = simplify(v)  # slower, but generates simpler expressions
            if not z3.is_false(v):
                super().__setitem__(k, v)
Пример #8
0
def elim_bool_ite(exp):
    if z3.is_quantifier(exp):
        (qvars, matrix) = strip_qblock(exp)
        matrix = elim_bool_ite(matrix)
        if exp.is_forall():
            e = z3.ForAll(qvars, matrix)
        else:
            e = z3.Exists(qvars, matrix)
        return e
    if not z3.is_bool(exp): return exp
    if z3.is_true(exp) or z3.is_false(exp): return exp
    assert z3.is_app(exp)
    decl = exp.decl()
    args = map(elim_bool_ite, exp.children())
    # need to worry about And and Or because they can take >2 args and
    # decl(*args) doesn't seem to work with the py interface
    if z3.is_and(exp):
        return z3.And(*args)
    elif z3.is_or(exp):
        return z3.Or(*args)
    elif is_ite(exp):
        impl1 = z3.Implies(args[0], args[1])
        impl2 = z3.Implies(z3.Not(args[0]), args[2])
        return z3.And(impl1, impl2)
    else:
        return decl(*args)
Пример #9
0
    def query(self, *query, **kwargs):
        if 'max_solutions' in kwargs:
            max_solutions = kwargs['max_solutions']
        else:
            max_solutions = -1

        body_atms = [x.as_muz() for x in query]
        self._solver.query(*body_atms)

        ans = self._solver.get_answer()

        query_vars = [x.get_variables() for x in query]
        query_vars = reduce(lambda x, y: x + [v for v in y if v not in x],
                            query_vars, [])

        if is_false(ans):
            # no solution
            return []
        elif not (is_and(ans) or is_or(ans)):
            # single solution, value of a single variable
            val = int(ans.children()[1].as_long())
            #varb = query.get_variables()[0]
            varb = query_vars[0]
            return [{varb: c_id_to_const(val, varb.get_type())}]
        elif is_or(ans) and not (is_and(ans.children()[0])
                                 or is_or(ans.children()[0])):
            # multiple solutions of single variable
            vals = [int(x.children()[1].as_long()) for x in ans.children()]
            #varbs = query.get_variables()[0]
            varbs = query_vars[0]
            varbs = [varbs] * len(vals)
            return [{
                k: c_id_to_const(v, varbs[0].get_type())
            } for k, v in zip(varbs, vals)]
        elif is_and(ans):
            # single solution of more than 1 variable
            ans = [int(x.children()[1].as_long()) for x in ans.children()]
            ans = [ans]
        elif is_or(ans):
            # multiple solutions of more than 1 variable
            ans = ans.children()
            ans = [[int(y.children()[1].as_long()) for y in x.children()]
                   for x in ans]
        else:
            raise Exception(f"don't know how to parse {ans}")

        tmp_args = [v for x in query for v in x.get_variables()]
        args = reduce(lambda x, y: x + [y] if y not in x else x, tmp_args, [])

        answer = [
            dict([(v, c_id_to_const(c,
                                    v.get_type().name))
                  for v, c in zip(args, x)]) for x in ans
        ]

        if max_solutions > 0:
            return answer[:max_solutions]
        else:
            return answer
Пример #10
0
def num_clauses(formula):
    if z3.is_and(formula):
        return len(formula.children())
    elif formula == True or z3.is_true(formula) or \
         formula == False or z3.is_false(formula):
        return 0
    else:
        return 1
Пример #11
0
def num_clauses(formula):
    if z3.is_and(formula):
        return len(formula.children())
    elif formula == True or z3.is_true(formula) or \
         formula == False or z3.is_false(formula):
        return 0
    else:
        return 1
Пример #12
0
def _is_literal(z3ast):
    if z3.is_int(z3ast):
        return z3.is_int_value(z3ast)
    if z3.is_bool(z3ast):
        return z3.is_true(z3ast) or z3.is_false(z3ast)
    if z3ast.sort_kind() == z3.Z3_UNINTERPRETED_SORT:
        return z3.is_const(z3ast) and '!' in str(z3ast)
    raise NotImplementedError('Don\'t know how to literal-check %s' % z3ast)
Пример #13
0
def is_bool_or_int_value(value):
    if z3.is_int_value(value):
        return True
    if value.sort() == z3.BoolSort():
        if z3.is_true(value) or z3.is_false(value):
            return True
    else:
        return False
Пример #14
0
def _is_literal(z3ast):
    if z3.is_int(z3ast):
        return z3.is_int_value(z3ast)
    if z3.is_bool(z3ast):
        return z3.is_true(z3ast) or z3.is_false(z3ast)
    if z3ast.sort_kind() == z3.Z3_UNINTERPRETED_SORT:
        return z3.is_const(z3ast) and '!' in str(z3ast)
    raise NotImplementedError('Don\'t know how to literal-check %s' % z3ast)
Пример #15
0
 def get(self, v):
     assert self._model is not None
     assert type(v) is Z3BoolRef
     v = self._model.eval(v.val, model_completion=True)
     assert z3.is_bool(v)
     t = z3.is_true(v)
     f = z3.is_false(v)
     assert t or f, f'bad {v}'
     return int(t)
Пример #16
0
def try_bool(b):
    b = try_simplify(b)
    # HACK: z3 python interface has bug/weird behavior where (x == y) is
    # always False for unknown x and y, so use is_true and is_false instead
    if z3.is_true(b):
        return True
    if z3.is_false(b):
        return False
    return None
def get_value(r):
    # https://stackoverflow.com/questions/12598408/z3-python-getting-python-values-from-model/12600208
    """
    Convert from Z3 to python values.
    """
    if z3.is_true(r):
        return z3.is_true(r)
    elif z3.is_false(r):
        return z3.is_false(r)
    elif z3.is_int_value(r):
        return r.as_long()
    elif z3.is_algebraic_value(r):
        return round(num(r.approx(15)), 10)
    elif z3.is_rational_value(r):
        return r.as_decimal(20)
    elif r is None:
        None
    else:
        return num(r)
Пример #18
0
 def l_get(self, ast):
     val = self.solver.model().eval(ast.ast)
     if val == None:
         return esbmc.solve.tvt(esbmc.solve.tvt_enum.unknown)
     elif z3.is_true(val):
         return esbmc.solve.tvt(esbmc.solve.tvt_enum.true)
     elif z3.is_false(val):
         return esbmc.solve.tvt(esbmc.solve.tvt_enum.false)
     else:
         raise Exception("Unknown model eval value from l_get")
 def l_get(self, ast):
     val = self.solver.model().eval(ast.ast)
     if val == None:
         return esbmc.solve.tvt(esbmc.solve.tvt_enum.unknown)
     elif z3.is_true(val):
         return esbmc.solve.tvt(esbmc.solve.tvt_enum.true)
     elif z3.is_false(val):
         return esbmc.solve.tvt(esbmc.solve.tvt_enum.false)
     else:
         raise Exception("Unknown model eval value from l_get")
Пример #20
0
def ite(x, y, z):
    if x is True:
        return y
    if x is False:
        return z
    x = z3.simplify(x)
    if z3.is_true(x):
        return y
    if z3.is_false(x):
        return z
    return z3.If(x, y, z)
Пример #21
0
 def _extract_var(self, z3model, var):
     val = z3model[var]
     if val is None:
         return None
     if z3.is_rational_value(val):
         n = val.numerator_as_long()
         d = val.denominator_as_long()
         return float(n / d)
     if z3.is_true(val):
         return True
     if z3.is_false(val):
         return False
     raise RuntimeError("var not supported")
Пример #22
0
def generalize_cube(z3_formula, model, all_vars):
    assigned_vars = set([_v for _v in all_vars if model[_v] is not None])
    my_model = MyModel({v: model[v] for v in assigned_vars})
    go_over_vars = list(assigned_vars)
    for _var in go_over_vars:
        model_tag = MyModel(dict(my_model.assignment))

        model_tag[_var] = BoolVal(is_false(my_model[_var]))

        z3_assigned = simplify(
            substitute(z3_formula,
                       *[(_v, model_tag[_v]) for _v in assigned_vars]))
        if is_false(z3_assigned):
            continue

        s = SatSolverSelector.SatSolverCtor()
        res = s.add(z3_assigned)

        if res and s.check():
            assigned_vars -= {_var}
            my_model.unassign(_var)

    return my_model
Пример #23
0
    def branch(self, ctx, cond, cond_type, iftrue, iffalse):
        self.assertion(ctx, not cond.is_poison(), "path condition is poison")
        assert itypes.integer_size(cond_type) == 1

        scond = util.simplify(cond)

        can_be_true = not z3.is_false(scond)
        can_be_false = not z3.is_true(scond)

        if ctx['depth'] >= ctx['prune_depth']:
            can_be_true = not z3.is_false(
                scond) and not util.path_condition_implies(ctx, z3.Not(scond))
            can_be_false = not can_be_true or (
                not z3.is_true(scond)
                and not util.path_condition_implies(ctx, scond))

        true_branch_exc = None
        false_branch_exc = None

        trueval = None
        falseval = None

        if can_be_true:
            try:
                ctx.push(path_condition=scond)
                trueval = iftrue()
            except ex.UnreachableException, e:
                stacktrace = getattr(e, 'stacktrace', None)
                self.assertion(ctx,
                               util.path_condition_implies(ctx,
                                                           z3.BoolVal(False),
                                                           print_model=True),
                               "Panic " + repr(e),
                               stacktrace=stacktrace)
                can_be_true = False
            except BaseException, e:
                true_branch_exc = e
Пример #24
0
def clause_model_simp(m, c):
    """ Simplify a clause by dropping literals while maintaining its truth in a model. """
    res = []
    for l in c:
        if not is_ground_lit(l):
            res.append(l)
            continue
        #        if isinstance(l.atom,ivy_logic.And):
        #            print "clause_model_simp: {}".format(c)
        v = m.eval(literal_to_z3(l))
        if z3.is_true(v):
            return [l]
        if not z3.is_false(v):
            res.append(l)
    return res
Пример #25
0
def clause_model_simp(m, c):
    """ Simplify a clause by dropping literals while maintaining its truth in a model. """
    res = []
    for l in c:
        if not is_ground_lit(l):
            res.append(l)
            continue
        if isinstance(l.atom, ivy_logic.And):
            print "clause_model_simp: {}".format(c)
        v = m.eval(literal_to_z3(l))
        if z3.is_true(v):
            return [l]
        if not z3.is_false(v):
            res.append(l)
    return res
Пример #26
0
def convert_patterns(pattern_repository, id_repository, patterns):
    spls = set()
    constraints = []
    for pattern in patterns:
        new_spls = pattern_repository.get_with_default(pattern).matched_spls
        spls.update(new_spls)
        #print(core_data.pattern_to_atom(pattern) + " => " + str([spl.name for spl in new_spls]))
        constraint = z3.simplify(
            smt_or([get_spl_smt(id_repository, spl.name) for spl in new_spls]))
        if z3.is_false(constraint):
            logging.warning("atom \"" + (core_data.pattern_to_atom(pattern)) +
                            "\" is satisfied by no ebuild")
            return set(), []
        constraints.append(constraint)
    return spls, smt_list_to_strings(constraints)
Пример #27
0
def try_bool(b):
    # Just ignore attributes here
    if isinstance(b, Value):
        b = b.value
    if z3.is_bv(b) or isinstance(b, int):
        b = (b != 0)
    b = try_simplify(b)
    if isinstance(b, bool):
        return (b, None)
    # HACK: z3 python interface has bug/weird behavior where (x == y) is
    # always False for unknown x and y, so use is_true and is_false instead
    if z3.is_true(b):
        return (True, None)
    if z3.is_false(b):
        return (False, None)
    return (None, b)
Пример #28
0
def simplify_z3_constraints(constraints):
    """
    Simplifies the constraint list, only by expressions that can be determined to evaluate to a a specific boolean value
    :param constraints:
    :return:
    """
    simp_const = constraints
    # Currently not running the individual simplification algorithm on every simplification call for
    # simp_const = simplify_constraints_individually(constraints)
    simp_const = list(
        filter(lambda c: not is_bool(c) or not is_true(c), simp_const))
    falses = list(filter(lambda c: is_bool(c) and is_false(c), simp_const))
    if len(falses) > 0:
        return [deepcopy(falses[0])]

    return simp_const
Пример #29
0
 def build_rule(self, rule, env):
     vars = {}
     head = self.compile_atom(vars, rule.head, env)
     body = [
         self.compile_atom(vars, atom, env)
         for atom in rule.body
         if atom is not None]
     if any(z3.is_false(at) for at in body):
         return
     body = [at for at in body if not z3.is_true(at)]
     body_conj = body[0] if len(body) == 1 else z3.And(*body)
     term1 = head if body == [] else z3.Implies(body_conj, head)
     term2 = (
         term1 if vars == {}
         else z3.ForAll(list(vars.values()), term1))
     self.context.rule(term2)
Пример #30
0
    def val(self, exp):
        '''Evaluate a z3 ref to a python value based on this solution.
         '''
        v = self.model.eval(exp)
        if z3.is_true(v):
            return True
        if z3.is_false(v):
            return False
        if z3.is_algebraic_value(v):
            v = v.approx(20)
        if z3.is_int_value(v):
            return v.as_long()
        if z3.is_rational_value(v):
            return v.numerator_as_long() / v.denominator_as_long()

        return z3.is_true(v)
Пример #31
0
def get_py_val_from_z3_val(z3_result):
    if z3_result is not None:
        if z3.is_int_value(z3_result):
            return z3_result.as_long()
        elif z3.is_real(z3_result):
            return float(z3_result.numerator_as_long()) / float(
                z3_result.denominator_as_long())
        elif z3.is_true(z3_result):
            return True
        elif z3.is_false(z3_result):
            return False
        elif z3.is_string_value(z3_result):
            return z3_result.as_string()
        else:
            raise NotImplementedError(
                "Z3 model result other than int, real, bool, string is not supported yet!"
            )
Пример #32
0
 def z3ToPoint(self, point):
     res = []
     # get the variables corresponding to the axis names
     for idx, i in enumerate(self.axis_names):
         locals()[i] = Globals.z3variables[i]
         if i in Globals.z3types:  # non-numeric points -> coord to value
             value = Globals.z3types[i][point[locals()[i]].as_long()]
         elif None == point[locals()[i]]:
             info("no value for %s, take %r (incomplete model)" %
                  (self.axis_names[idx], self.axis_val_ranges[idx][0]))
             value = self.axis_val_ranges[idx][0]
         elif z3.is_int_value(point[locals()[i]]):
             value = point[locals()[i]].as_long()
         elif z3.is_true(point[locals()[i]]) or z3.is_false(
                 point[locals()[i]]):
             value = z3.is_true(point[locals()[i]])
         res.append(value)
     return res
Пример #33
0
 def mk_const(self, c):
     if z3.is_int_value(c):
         return ii(c.as_long())
     if z3.is_rational_value(c):
         # TODO: what should we convert a rational to?
         return rr(Fraction(c.numerator_as_long(), \
                            c.denominator_as_long()))
     elif z3.is_true(c):
         return true
     elif z3.is_false(c):
         return false
     else:
         try:
             return self.context.decls[str(c)]
         except KeyError:
             #Constant is not found in the context
             typ = self.mk_sort(c.sort())
             return const(str(c), typ)
Пример #34
0
 def tfFlags(self, pred, flags_len):
     """
     return two lists, one for true and one false flags
     """
     false_idxs = list()
     true_idxs = list ()
     if debug_cex: print "Get list of failing flags from : ", pred
     ch = pred.children()
     i=0
     for val in ch[0:flags_len]:
         if z3.is_false(val):
             false_idxs.append(i)
             i+=1
         elif z3.is_true(val):
             true_idxs.append(i)
             i+=1
         else: i+=1
     return true_idxs, false_idxs
Пример #35
0
 def mk_const(self, c):
     if z3.is_int_value(c):
         return ii(c.as_long())
     if z3.is_rational_value(c):
         # TODO: what should we convert a rational to?
         return rr(Fraction(c.numerator_as_long(), \
                            c.denominator_as_long()))
     elif z3.is_true(c):
         return true
     elif z3.is_false(c):
         return false
     else:
         try:
             return self.context.decls[str(c)]
         except KeyError:
             #Constant is not found in the context
             typ = self.mk_sort(c.sort())
             return const(str(c), typ)
Пример #36
0
Файл: inc.py Проект: alx441/XSHM
 def tfFlags(self, pred, flags_len):
     """
     return two lists, one for true and one false flags
     """
     false_idxs = list()
     true_idxs = list()
     if verbose: print "Get list of failing flags from : ", pred
     ch = pred.children()
     i = 0
     for val in ch[0:flags_len]:
         if z3.is_false(val):
             false_idxs.append(i)
             i += 1
         elif z3.is_true(val):
             true_idxs.append(i)
             i += 1
         else:
             i += 1
     return true_idxs, false_idxs
Пример #37
0
def z3_to_val(z3_expr):
    """Send a z3 expression to it's value
    as a python expression, if it has one,
    otherwise return the expresson itself.
    
    Arguments:
    - `z3_expr`: a z3 AST
    """
    if z3.is_int_value(z3_expr):
        return z3_expr.as_long()
    if z3.is_rational_value(z3_expr):
        return Fraction(z3_expr.numerator_as_long(), \
                        z3_expr.denominator_as_long())
    elif z3.is_true(z3_expr):
        return True
    elif z3.is_false(z3_expr):
        return False
    elif isinstance(z3_expr, z3.FuncInterp):
        return z3_to_fun(z3_expr)
    else:
        return z3_expr
Пример #38
0
def constant_from_z3(sort, c):
    if z3.is_true(c):
        return ivy_logic.And()
    if z3.is_false(c):
        return ivy_logic.Or()
    return ivy_logic.Constant(ivy_logic.Symbol(repr(c), sort))
Пример #39
0
print c4.result
stop = time.time()
print stop - start

print "Running simple compression test"
ResetZ3()
start = time.time()
out = TrivialWanOptimizer()
result = out.check.CheckIsolationProperty(out.a, out.b)
assert z3.sat == result.result, \
        "Nothing is blocking the way, packets should get from A -> B"
assert is_true(result.model.eval(out.ctx.send(out.w.z3Node, out.b.z3Node, result.violating_packet))), \
        "Violating packet was never sent"
assert is_true(result.model.eval(out.ctx.recv(out.w.z3Node, out.b.z3Node, result.violating_packet))), \
        "Violating packet was never received"
assert is_false(result.model.eval(out.ctx.recv(out.a.z3Node, out.w.z3Node, result.violating_packet))), \
        "The packet should not get to b unmodified"
assert is_false(result.model.eval(out.ctx.send(out.a.z3Node, out.w.z3Node, result.violating_packet))), \
        "The packet should not get to b unmodified"
stop = time.time()
print stop - start

print "Running simple compression-decompression test"
ResetZ3()
start = time.time()
out = TrivialWanOptimizerDeOptimizer()
result = out.check.CheckIsolatedIf(lambda p: z3.Not(out.ctx.send(out.w0.z3Node, out.w1.z3Node, p)), out.a, out.b)
assert z3.sat == result.result, \
        "Nothing is blocking the way, packets should get from A -> B"
assert is_true(result.model.eval(out.ctx.send(out.w1.z3Node, out.b.z3Node, result.violating_packet))), \
        "Violating packet was never sent"
Пример #40
0
Файл: z3.py Проект: 0Chuzz/pysmt
    def _back_single_term(self, expr, args, model=None):
        assert z3.is_expr(expr)

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        res = None
        if z3.is_and(expr):
            res = self.mgr.And(args)
        elif z3.is_or(expr):
            res = self.mgr.Or(args)
        elif z3.is_add(expr):
            res = self.mgr.Plus(args)
        elif z3.is_div(expr):
            res = self.mgr.Div(args[0], args[1])
        elif z3.is_eq(expr):
            if self._get_type(args[0]).is_bool_type():
                res = self.mgr.Iff(args[0], args[1])
            else:
                res = self.mgr.Equals(args[0], args[1])
        elif z3.is_iff(expr):
            res = self.mgr.Iff(args[0], args[1])
        elif z3.is_xor(expr):
            res = self.mgr.Xor(args[0], args[1])
        elif z3.is_false(expr):
            res = self.mgr.FALSE()
        elif z3.is_true(expr):
            res = self.mgr.TRUE()
        elif z3.is_gt(expr):
            res = self.mgr.GT(args[0], args[1])
        elif z3.is_ge(expr):
            res = self.mgr.GE(args[0], args[1])
        elif z3.is_lt(expr):
            res = self.mgr.LT(args[0], args[1])
        elif z3.is_le(expr):
            res = self.mgr.LE(args[0], args[1])
        elif z3.is_mul(expr):
            res = self.mgr.Times(args[0], args[1])
        elif z3.is_uminus(expr):
            tp = self._get_type(args[0])
            if tp.is_real_type():
                minus_one = self.mgr.Real(-1)
            else:
                assert tp.is_int_type()
                minus_one = self.mgr.Int(-1)
            res = self.mgr.Times(args[0], minus_one)
        elif z3.is_sub(expr):
            res = self.mgr.Minus(args[0], args[1])
        elif z3.is_not(expr):
            res = self.mgr.Not(args[0])
        elif z3.is_implies(expr):
            res = self.mgr.Implies(args[0], args[1])
        elif z3.is_quantifier(expr):
            raise NotImplementedError
        elif z3.is_const(expr):
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                res = self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                res = self.mgr.Int(n)
            elif z3.is_bv_value(expr):
                n = expr.as_long()
                w = expr.size()
                res = self.mgr.BV(n, w)
            elif z3.is_as_array(expr):
                if model is None:
                    raise NotImplementedError("As-array expressions cannot be" \
                                              " handled as they are not " \
                                              "self-contained")
                else:
                    interp_decl = z3.get_as_array_func(expr)
                    interp = model[interp_decl]
                    default = self.back(interp.else_value(), model=model)
                    assign = {}
                    for i in xrange(interp.num_entries()):
                        e = interp.entry(i)
                        assert e.num_args() == 1
                        idx = self.back(e.arg_value(0), model=model)
                        val = self.back(e.value(), model=model)
                        assign[idx] = val
                    arr_type = self._z3_to_type(expr.sort())
                    res = self.mgr.Array(arr_type.index_type, default, assign)
            elif z3.is_algebraic_value(expr):
                # Algebraic value
                return self.mgr._Algebraic(Numeral(expr))
            else:
                # it must be a symbol
                res = self.mgr.get_symbol(str(expr))
        elif z3.is_ite(expr):
            res = self.mgr.Ite(args[0], args[1], args[2])
        elif z3.is_function(expr):
            res = self.mgr.Function(self.mgr.get_symbol(expr.decl().name()), args)
        elif z3.is_to_real(expr):
            res = self.mgr.ToReal(args[0])
        elif z3.is_bv_and(expr):
            res = self.mgr.BVAnd(args[0], args[1])
        elif z3.is_bv_or(expr):
            res = self.mgr.BVOr(args[0], args[1])
        elif z3.is_bv_xor(expr):
            res = self.mgr.BVXor(args[0], args[1])
        elif z3.is_bv_not(expr):
            res = self.mgr.BVNot(args[0])
        elif z3.is_bv_neg(expr):
            res = self.mgr.BVNeg(args[0])
        elif z3.is_bv_concat(expr):
            res = self.mgr.BVConcat(args[0], args[1])
        elif z3.is_bv_ult(expr):
            res = self.mgr.BVULT(args[0], args[1])
        elif z3.is_bv_uleq(expr):
            res = self.mgr.BVULE(args[0], args[1])
        elif z3.is_bv_slt(expr):
            res = self.mgr.BVSLT(args[0], args[1])
        elif z3.is_bv_sleq(expr):
            res = self.mgr.BVSLE(args[0], args[1])
        elif z3.is_bv_ugt(expr):
            res = self.mgr.BVUGT(args[0], args[1])
        elif z3.is_bv_ugeq(expr):
            res = self.mgr.BVUGE(args[0], args[1])
        elif z3.is_bv_sgt(expr):
            res = self.mgr.BVSGT(args[0], args[1])
        elif z3.is_bv_sgeq(expr):
            res = self.mgr.BVSGE(args[0], args[1])
        elif z3.is_bv_extract(expr):
            end = z3.get_payload(expr, 0)
            start = z3.get_payload(expr, 1)
            res = self.mgr.BVExtract(args[0], start, end)
        elif z3.is_bv_add(expr):
            res = self.mgr.BVAdd(args[0], args[1])
        elif z3.is_bv_mul(expr):
            res = self.mgr.BVMul(args[0], args[1])
        elif z3.is_bv_udiv(expr):
            res = self.mgr.BVUDiv(args[0], args[1])
        elif z3.is_bv_sdiv(expr):
            res = self.mgr.BVSDiv(args[0], args[1])
        elif z3.is_bv_urem(expr):
            res = self.mgr.BVURem(args[0], args[1])
        elif z3.is_bv_srem(expr):
            res = self.mgr.BVSRem(args[0], args[1])
        elif z3.is_bv_lshl(expr):
            res = self.mgr.BVLShl(args[0], args[1])
        elif z3.is_bv_lshr(expr):
            res = self.mgr.BVLShr(args[0], args[1])
        elif z3.is_bv_ashr(expr):
            res = self.mgr.BVAShr(args[0], args[1])
        elif z3.is_bv_sub(expr):
            res = self.mgr.BVSub(args[0], args[1])
        elif z3.is_bv_rol(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ror(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_ext_rol(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ext_ror(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_sext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVSExt(args[0], amount)
        elif z3.is_bv_zext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVZExt(args[0], amount)
        elif z3.is_array_select(expr):
            res = self.mgr.Select(args[0], args[1])
        elif z3.is_array_store(expr):
            res = self.mgr.Store(args[0], args[1], args[2])
        elif z3.is_const_array(expr):
            arr_ty = self._z3_to_type(expr.sort())
            k = args[0]
            res = self.mgr.Array(arr_ty.index_type, k)
        elif z3.is_power(expr):
            res = self.mgr.Pow(args[0], args[1])
        if res is None:
            raise ConvertExpressionError(message=("Unsupported expression: %s" %
                                                   str(expr)),
                                         expression=expr)
        return res
Пример #41
0
    def _back_single_term(self, expr, args):
        assert z3.is_expr(expr)

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        res = None
        if z3.is_and(expr):
            res = self.mgr.And(args)
        elif z3.is_or(expr):
            res = self.mgr.Or(args)
        elif z3.is_add(expr):
            res = self.mgr.Plus(args)
        elif z3.is_div(expr):
            res = self.mgr.Div(args[0], args[1])
        elif z3.is_eq(expr):
            if self._get_type(args[0]).is_bool_type():
                res = self.mgr.Iff(args[0], args[1])
            else:
                res = self.mgr.Equals(args[0], args[1])
        elif z3.is_iff(expr):
            res = self.mgr.Iff(args[0], args[1])
        elif z3.is_xor(expr):
            res = self.mgr.Xor(args[0], args[1])
        elif z3.is_false(expr):
            res = self.mgr.FALSE()
        elif z3.is_true(expr):
            res = self.mgr.TRUE()
        elif z3.is_gt(expr):
            res = self.mgr.GT(args[0], args[1])
        elif z3.is_ge(expr):
            res = self.mgr.GE(args[0], args[1])
        elif z3.is_lt(expr):
            res = self.mgr.LT(args[0], args[1])
        elif z3.is_le(expr):
            res = self.mgr.LE(args[0], args[1])
        elif z3.is_mul(expr):
            res = self.mgr.Times(args[0], args[1])
        elif z3.is_uminus(expr):
            tp = self._get_type(args[0])
            if tp.is_real_type():
                minus_one = self.mgr.Real(-1)
            else:
                assert tp.is_int_type()
                minus_one = self.mgr.Int(-1)
            res = self.mgr.Times(args[0], minus_one)
        elif z3.is_sub(expr):
            res = self.mgr.Minus(args[0], args[1])
        elif z3.is_not(expr):
            res = self.mgr.Not(args[0])
        elif z3.is_implies(expr):
            res = self.mgr.Implies(args[0], args[1])
        elif z3.is_quantifier(expr):
            raise NotImplementedError
        elif z3.is_const(expr):
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                res = self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                res = self.mgr.Int(n)
            elif z3.is_bv_value(expr):
                n = expr.as_long()
                w = expr.size()
                res = self.mgr.BV(n, w)
            else:
                # it must be a symbol
                res = self.mgr.get_symbol(str(expr))
        elif z3.is_ite(expr):
            res = self.mgr.Ite(args[0], args[1], args[2])
        elif z3.is_function(expr):
            res = self.mgr.Function(self.mgr.get_symbol(expr.decl().name()), args)
        elif z3.is_to_real(expr):
            res = self.mgr.ToReal(args[0])
        elif z3.is_bv_and(expr):
            res = self.mgr.BVAnd(args[0], args[1])
        elif z3.is_bv_or(expr):
            res = self.mgr.BVOr(args[0], args[1])
        elif z3.is_bv_xor(expr):
            res = self.mgr.BVXor(args[0], args[1])
        elif z3.is_bv_not(expr):
            res = self.mgr.BVNot(args[0])
        elif z3.is_bv_neg(expr):
            res = self.mgr.BVNeg(args[0])
        elif z3.is_bv_concat(expr):
            res = self.mgr.BVConcat(args[0], args[1])
        elif z3.is_bv_ult(expr):
            res = self.mgr.BVULT(args[0], args[1])
        elif z3.is_bv_uleq(expr):
            res = self.mgr.BVULE(args[0], args[1])
        elif z3.is_bv_slt(expr):
            res = self.mgr.BVSLT(args[0], args[1])
        elif z3.is_bv_sleq(expr):
            res = self.mgr.BVSLE(args[0], args[1])
        elif z3.is_bv_ugt(expr):
            res = self.mgr.BVUGT(args[0], args[1])
        elif z3.is_bv_ugeq(expr):
            res = self.mgr.BVUGE(args[0], args[1])
        elif z3.is_bv_sgt(expr):
            res = self.mgr.BVSGT(args[0], args[1])
        elif z3.is_bv_sgeq(expr):
            res = self.mgr.BVSGE(args[0], args[1])
        elif z3.is_bv_extract(expr):
            end = z3.get_payload(expr, 0)
            start = z3.get_payload(expr, 1)
            res = self.mgr.BVExtract(args[0], start, end)
        elif z3.is_bv_add(expr):
            res = self.mgr.BVAdd(args[0], args[1])
        elif z3.is_bv_mul(expr):
            res = self.mgr.BVMul(args[0], args[1])
        elif z3.is_bv_udiv(expr):
            res = self.mgr.BVUDiv(args[0], args[1])
        elif z3.is_bv_sdiv(expr):
            res = self.mgr.BVSDiv(args[0], args[1])
        elif z3.is_bv_urem(expr):
            res = self.mgr.BVURem(args[0], args[1])
        elif z3.is_bv_srem(expr):
            res = self.mgr.BVSRem(args[0], args[1])
        elif z3.is_bv_lshl(expr):
            res = self.mgr.BVLShl(args[0], args[1])
        elif z3.is_bv_lshr(expr):
            res = self.mgr.BVLShr(args[0], args[1])
        elif z3.is_bv_ashr(expr):
            res = self.mgr.BVAShr(args[0], args[1])
        elif z3.is_bv_sub(expr):
            res = self.mgr.BVSub(args[0], args[1])
        elif z3.is_bv_rol(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ror(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_ext_rol(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ext_ror(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_sext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVSExt(args[0], amount)
        elif z3.is_bv_zext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVZExt(args[0], amount)

        if res is None:
            raise ConvertExpressionError(message=("Unsupported expression: %s" %
                                                   str(expr)),
                                         expression=expr)
        return res
    def maxSAT(self, solver, var_weight_pairs):
        # A classic argmax loop, holding on to our best cost and the
        # cooresponding solution.
        min_cost = None
        best_solution = None
        # The variables that keep us from trying a solution we've
        # already tried, or a subset of that solution.
        conflictVars = []
        # Get our first solver result, the solution if we don't need
        # to accomplish any of our weighted vars.
        next_solver_result = solver.check()
        while(next_solver_result == z3.sat):
            # The cost of this solution.
            cost = 0
            # Get the solvers model.
            model = solver.model()
            # For each soft variable that was set to false in the
            # current solution, incur a cost.
            for var, weight in var_weight_pairs:
                if self.debugPrint:
                    print "adding cost of " + str(var) + ": " + str(weight) + " * "\
                        + str(not z3.is_false(model[var]))
                if z3.is_false(model[var]):
                    cost += weight

            # Extract a solution object. We would just save the model,
            # but it turns out z3 models are invalidated when you next
            # run the solver.
            solution = self.modelToSolution(model)

            # If our new cost is the best cost we've seen so far,
            # update our best.
            if min_cost == None or cost < min_cost:
                min_cost = cost
                best_solution = solution

            if self.debugPrint:
                print "found solution: "
                self.printSolution(solution)
                print "with cost " + str(cost)

            # Create a fresh variable that blocks any future solution
            # that does not include at least one of the tasks that
            # were excluded from this solution. That statement may
            # take a bit of unpacking. Basically the idea is, if we
            # have some solution, then there exists no better solution
            # which only does a subset of the tasks which this
            # solution does. So, we block all solutions which don't
            # include at least one other task that this solution
            # doesn't have. I got the algorithm from this paper:
            # http://research.microsoft.com/en-US/peopleb/nbjorner/scss2014.pdf
            # The paper actually shows that another algorithm is more
            # efficient, but this one is simpler, so we use this one
            # until we hit a performance bottleneck with it.
            fresh_var_name = "block"
            interp = [v for v,w in var_weight_pairs \
                      if z3.is_false(model[v])]
            for v in interp:
                fresh_var_name += "_" + str(v)
            fresh_var = z3.Bool(fresh_var_name)
            # Tie our blocking constraint to a new "conflict
            # variable," and add that variable to our set of
            # assumptions.
            block_constraint = Or(Not(fresh_var), *interp)
            if self.debugPrint:
                print "adding block constraint " + str(block_constraint)
            solver.add(block_constraint)
            conflictVars.append(fresh_var)
            # Get a new result for the next time around the while loop.
            next_solver_result = solver.check(*conflictVars)
        if self.debugPrint:
            print "best solution was "
            self.printSolution(best_solution)
            print "with cost " + str(min_cost)
        return best_solution
Пример #43
0
 def evaluate(self, t):
     s = self.solver.model().eval(t.z3Node())
     assert z3.is_true(s) or z3.is_false(s)
     return z3.is_true(s)