Beispiel #1
0
 def __init__(self, name, fabric, width, height):
     super().__init__(name, fabric, width, height)
     self._x = z3.Int(name + '_x')
     self._y = z3.Int(name + '_y')
Beispiel #2
0
def _mk_int_var(x):
    if x not in vars:
        vars[x] = z3.Int(str(x))
    return vars[x]
Beispiel #3
0
def walk_block(node, prev_g=None, cond=True):
    g = z3.Goal()
    g.add(cond)
    if prev_g is not None:
        for e in prev_g:
            if isinstance(e, z3.Goal):
                g.add(e.as_expr())
            else:
                g.add(e)

    if isinstance(node, pycp.c_ast.Compound):
        if node.block_items is not None:
            for e in node.block_items:
                g_next = walk_block(e, g)
                g = g_next
    elif isinstance(node, pycp.c_ast.Decl):
        if "int" in node.type.type.names:
            vars[node.name] = z3.Int(node.name)
        if "float" in node.type.type.names:
            vars[node.name] = z3.Real(node.name)
    elif isinstance(node, pycp.c_ast.FuncCall):
        if node.name.name == "__ASSUME":
            for e_exp in node.args.exprs:
                g.add(gen_smt_expr(e_exp))
        elif node.name.name == "__ASSERT":
            assertions = z3.Goal()
            for e_exp in node.args.exprs:
                assertions.add(gen_smt_expr(e_exp))
            print("solving..")
            print("SP:", g.as_expr())
            print("assert:", assertions)

            seen = set()

            def bv_length(e):
                li = [-1]
                if e in seen:
                    return -1
                if (z3.is_bv(e) and
                        z3.is_const(e) and
                        e.decl().kind() == z3.Z3_OP_UNINTERPRETED):
                    li.append(e.size())
                seen.add(e)
                if z3.is_app(e):
                    for ch in e.children():
                        li.append(bv_length(ch))
                elif z3.is_quantifier(e):
                    for ch in e.body().children():
                        li.append(bv_length(ch))
                return max(li)

            t = z3.Tactic('nla2bv')
            s = z3.Then(t, 'default').solver()
            fml = z3.And(g.as_expr(), z3.Not(assertions.as_expr()))
            print("solving using bitvector underapproximation..")
            s.add(fml)
            status = s.check()

            if status == z3.unknown:
                print("returned 'unknown'! trying again with bigger bit length..")
                print("getting highest bit length used in formula..")
                bv_l = bv_length(t(fml).as_expr())
                print("highest bit length used:", bv_l)

                while True:
                    bv_l += 1
                    print("trying with bit length:", bv_l)
                    s = z3.Then(z3.With('nla2bv', nla2bv_bv_size=bv_l),
                                'default').solver()
                    s.add(fml)
                    status = s.check()

                    if status != z3.unknown or bv_l >= 64:
                        break

            if status == z3.sat:
                model = s.model()
                print("program is unsafe.\nlisting an unsafe assignments..")
                for e in vars:
                    print(e, ':', model[vars[e]])
            elif status == z3.unsat:
                print("program is safe.")
            elif status == z3.unknown:
                print("unknown")

            s.reset()
        else:
            print("found a func call")
    elif isinstance(node, pycp.c_ast.Assignment):
        rexp = gen_smt_expr(node.rvalue)
        if z3.is_int(vars[node.lvalue.name]):
            hand_ = z3.Int('__hand__')
        elif z3.is_real(vars[node.lvalue.name]):
            hand_ = z3.Real('__hand__')
        if node.op == "=":
            g.add(hand_ == rexp)
        elif node.op == "+=":
            g.add(hand_ == (vars[node.lvalue.name] + rexp))
        elif node.op == "-=":
            g.add(hand_ == (vars[node.lvalue.name] - rexp))
        elif node.op == "*=":
            g.add(hand_ == (vars[node.lvalue.name] * rexp))
        elif node.op == "%=":
            g.add(hand_ == (vars[node.lvalue.name] % rexp))
        g_ = z3.Goal()
        g_.add(z3.Exists(vars[node.lvalue.name], g.as_expr()))
        g_ = t_qe_(g_)
        g = z3.Goal()
        g.add(z3.substitute(g_.as_expr(), (hand_, vars[node.lvalue.name])))
        # g = g.simplify()
    elif isinstance(node, pycp.c_ast.If):
        cond_exp = gen_smt_expr(node.cond)
        if node.iftrue is not None:
            true_expr = walk_block(node.iftrue, g, cond_exp).as_expr()
        else:
            true_expr = z3.And(cond_exp, g.as_expr())
        if node.iffalse is not None:
            false_expr = walk_block(
                node.iffalse, g, z3.Not(cond_exp)).as_expr()
        else:
            false_expr = z3.And(z3.Not(cond_exp), g.as_expr())
        g = z3.Goal()
        g.add(z3.Or(true_expr, false_expr))
        g = t(g)  # g.simplify()
    else:
        return prev_g
    # print(g.as_expr(), "\n")
    return g
Beispiel #4
0
def _int_new_var(name, nbits):
    return z3.Int(name)
Beispiel #5
0
import z3
x, y, z, n = z3.Ints("x y z n")

e1 = y * z - z3.Int("18") * x - z3.Int("12") * y + z3.Int("2") * z == z3.Int(
    "6")
e2 = (z * z) - z3.Int("12") * y + z3.Int("12") == z3.Int("6") * z
e3 = z3.Int("6") * n + z3.Int("6") == z

d1 = z == z3.Int("6") * n + z3.Int("6")
d2 = y == z3.Int("3") * n * n + z3.Int("3") * n + z3.Int("1")
d3 = x == n * n * n

e123 = z3.And(e1, e2, e3)
#z3.prove(z3.Implies(e123, d1))
#z3.prove(z3.Implies(e123, d2))
#z3.prove(z3.Implies(e123, d3))
 def prove_triple(self, precond, command, postcond):
     if command.data == "skip":
         # the inference rule for the skip command is really simple
         # given a triple in the form of {p}skip{q} is sufficient to
         # prove that p=>q
         formula_to_prove = z3.Implies(precond, postcond)
         print("found skip statement, trying to prove", formula_to_prove)
         res = self.prove_formula(formula_to_prove)
         return res
     elif command.data == "assignment":
         # the inference rule for the assignment command is again simple
         # given a triple in the form of {p}x:=E{q} is sufficient to
         # prove that p=>q[E/x]
         ide, exp = command.children
         formula_to_prove = z3.Implies(
             precond,
             z3.substitute(postcond,
                           (self.env[ide], self.expr_to_z3_formula(exp))))
         print("found assignment statement, trying to prove",
               formula_to_prove)
         res = self.prove_formula(formula_to_prove)
         return res
     elif command.data == "if":
         # the inference rule for the if command is pretty straight forward
         # to implement: given a triple in the form of {p}if E then c else s fi{q}
         # it is sufficient to prove the two triples {p and E}c{q} and {p and not E}s{q}
         guard, s1, s2 = command.children
         print("found if statement, trying to prove the first alternative")
         res_1 = self.prove_triple(
             z3.And(precond, self.expr_to_z3_formula(guard)), s1, postcond)
         if res_1:
             print("now trying to prove the second alternative")
             res_2 = self.prove_triple(
                 z3.And(precond, z3.Not(self.expr_to_z3_formula(guard))),
                 s2, postcond)
             return res_2
         else:
             return False
     elif command.data == "composition":
         # the inference rule for the composition requires a
         # special treatment. Given a triple in the form of
         # {p}c;s{q} is sufficient to find some predicate r
         # so that {p}c{r} and {r}s{q} are both valid triples.
         # To do that we try to find an axiom for the second triple,
         # so that we have a candidate for r, then we try to prove
         # {p}c{r}. If this triple is valid then the whole composition
         # triple is valid
         c1, c2 = command.children
         print("found composition, trying to find axiom for the right side")
         (res, axiom) = self.find_axiom(c2, postcond)
         if res:
             return self.prove_triple(precond, c1, axiom)
         else:
             return False
     elif command.data == "while":
         # the inference rule for the while command is kind of complicated
         # so we have to be careful: given a triple in the form
         # of {p}while E do C endw{q} we need a loop invariant (inv) and a counter (t)
         # we have to prove the following statements
         # 1) p => inv (pre)
         # 2) (inv and not E) => q (post)
         # 3) inv => t>=0 (termination)
         # 4) {inv and E}C{inv} (invariance)
         # 5) {inv and E and t==V}C{t<V} (progress)
         e, t_expr, inv, c = command.children
         print("found while statement, trying to prove:")
         invariant = self.expr_to_z3_formula(inv)
         t = self.expr_to_z3_formula(t_expr)
         guard = self.expr_to_z3_formula(e)
         pre = z3.Implies(precond, invariant)
         post = z3.Implies(z3.And(precond, z3.Not(guard)), postcond)
         term = z3.Implies(z3.And(invariant, self.env["t"] == t), t >= 0)
         print("1) [pre]", pre)
         res = self.prove_formula(pre)
         if res:
             print("2) [post]", post)
             res = self.prove_formula(post)
             if res:
                 print("3) [term]", term)
                 res = self.prove_formula(term)
                 if res:
                     print("4) [invariance]", term)
                     res = self.prove_triple(z3.And(invariant, guard), c,
                                             invariant)
                     if res:
                         print("5) [progress]", term)
                         v = z3.Int("V")
                         res = self.prove_triple(
                             z3.And(z3.And(invariant, guard), t == v), c,
                             t < v)
                         return res
         return False
Beispiel #7
0
 def getIntVar(self, name):
   return z3.Int(name)
Beispiel #8
0
def run_feature_analysis_grid_search(features,
                                     features_as_boolean,
                                     contexts,
                                     attributes,
                                     constraints,
                                     optional_features,
                                     non_incremental_solver,
                                     out_stream,
                                     time_context=""):
    """
    Performs the feature analysis one feature at the time with push and pops. Time context is set to all its values
    in sequence.
    Does not check the model except the first time for pruning the remaining features.
    This helps for big instances where generating the model make take some time.
    """

    data = {"dead_features": {}, "false_optionals": {}}
    solver = z3.Solver()
    if non_incremental_solver:
        solver.set("combined_solver.solver2_timeout", 1)

    # if time variable is not defined, create a fictional one
    time_context = get_time_context(time_context, optional_features)

    log.debug("Add basic constraints")
    solver.add(
        get_basic_formula_list(features, attributes, contexts, constraints,
                               features_as_boolean))

    if not non_incremental_solver:
        log.debug("Preliminary check")
        solver.check()

    # list of the features to check
    to_check = get_dic_of_features_to_check(optional_features)
    to_check_dead = {i: set(to_check[i]) for i in to_check}
    to_check_false = {i: set(to_check[i]) for i in to_check}
    log.info("Features to check: {}, Time context {}".format(
        len(optional_features), len(to_check)))

    for i in to_check_dead:
        log.debug("Processing time instant {}, features to check {}".format(
            i, len(to_check_dead[i])))
        solver.push()
        solver.add(z3.Int(time_context).__eq__(z3.IntVal(i)))

        # run first time to prune easy features and check satisfiability
        result = solver.check()
        if result == z3.unsat:
            log.debug("All instances are dead for time {}".format(i))
            for j in to_check_dead[i]:
                if j in data["dead_features"]:
                    data["dead_features"][j].append(i)
                else:
                    data["dead_features"][j] = [i]
            continue
        elif result == z3.sat:
            to_remove_dead, to_remove_false = get_fail_checks_from_model(
                to_check_dead[i], to_check_false[i], solver.model(),
                features_as_boolean)
            to_check_dead[i].difference_update(to_remove_dead)
            to_check_false[i].difference_update(to_remove_false)
        else:
            log.debug(
                "Problems in detecting the satisfiability of the instance. Z3 returned {}"
                .format(result))
            sys.exit(1)

        log.debug("Checking for dead features")
        counter = len(to_check_dead[i])
        for j in to_check_dead[i]:
            log.debug("Processing feature {}, remaining {}".format(j, counter))
            counter -= 1
            solver.push()
            if features_as_boolean:
                solver.add(z3.Bool(j))
            else:
                solver.add(z3.Int(j).__eq__(z3.IntVal(1)))
            result = solver.check()
            log.debug("Result {}".format(result))
            if result == z3.unsat:
                log.debug("{} is a dead feature".format(j))
                if j in data["dead_features"]:
                    data["dead_features"][j].append(i)
                else:
                    data["dead_features"][j] = [i]
                to_check_false[i].discard(j)
            elif result != z3.sat:
                log.debug(
                    "Problems checking feature{} at time {}. Z3 returned {}".
                    format(j, i, result))
                sys.exit(1)
            solver.pop()

        log.debug("Checking for false optional features")
        counter = len(to_check_false[i])
        for j in to_check_false[i]:
            log.debug("Processing feature {}, remaining {}".format(j, counter))
            counter -= 1
            solver.push()
            if features_as_boolean:
                solver.add(z3.Not(z3.Bool(j)))
            else:
                solver.add(z3.Int(j).__eq__(z3.IntVal(0)))
            result = solver.check()
            log.debug("Result {}".format(result))
            if result == z3.unsat:
                log.debug("{} is a false optional feature".format(j))
                if j in data["false_optionals"]:
                    data["false_optionals"][j].append(i)
                else:
                    data["false_optionals"][j] = [i]
            elif result != z3.sat:
                log.debug(
                    "Problems checking feature{} at time {}. Z3 returned {}".
                    format(j, i, result))
                sys.exit(1)
            solver.pop()
        solver.pop()

    log.info("Printing output")
    json.dump(data, out_stream)
    out_stream.write("\n")
Beispiel #9
0
def run_feature_analysis_forall(features,
                                features_as_boolean,
                                contexts,
                                attributes,
                                constraints,
                                optional_features,
                                non_incremental_solver,
                                out_stream,
                                time_context=""):
    """
    Performs the feature analysis task.
    A quantifier formula is solved to detect the anomalies
    """

    data = {"dead_features": {}, "false_optionals": {}}
    solver = z3.Solver()
    #solver.set("smt.relevancy", 0)
    if non_incremental_solver:
        solver.set("combined_solver.solver2_timeout", 1)

    # if time variable is not defined, create a fictional one
    time_context = get_time_context(time_context, optional_features)
    # add it in context if not present
    if time_context not in contexts:
        contexts[time_context] = {}
        contexts[time_context]['min'] = 0
        contexts[time_context]['max'] = 0

    # these constraints will also be added in the forall formula and are redundant
    # hopefully they will help the SMT solver to solve the forall formula
    solver.add(contexts[time_context]["min"] <= z3.Int(time_context))
    solver.add(z3.Int(time_context) <= contexts[time_context]["max"])

    log.info("Building the FM formula")
    # will repeat the constraints about the bounds on the environment but that is OK
    formulas = get_basic_formula_list(features, attributes, contexts,
                                      constraints, features_as_boolean)

    if not non_incremental_solver:
        log.debug("Preliminary check")
        solver.check()

    log.info(
        "Computing dead or false optional features considering {} optional features"
        .format(len(optional_features)))

    opt_features_ls = optional_features.keys()
    # fresh variables representing the selected features namefresh_var
    fresh_var = "_" + uuid.uuid4().hex
    if not opt_features_ls:
        log.warning("Nothing to check")
        json.dump(data, out_stream)
        out_stream.write("\n")
        return
    elif len(
            opt_features_ls
    ) == 1:  # zip problem raised by smt if list of one element is used for z3.PbEq
        solver.add(z3.Bool(opt_features_ls[0] + fresh_var))
    else:
        # only one selected
        solver.add(
            z3.PbEq([(z3.Bool(i + fresh_var), 1) for i in opt_features_ls], 1))

    log.info(
        "Adding constraint limiting time context based on the optional features to check"
    )
    for i in opt_features_ls:
        ls = []
        for k in optional_features[i]:
            ls.append(z3.Int(time_context) >= k[0])
            ls.append(z3.Int(time_context) <= k[1])
        solver.add(z3.Implies(z3.Bool(i + fresh_var), z3.And(ls)))

    solver.push()

    if features_as_boolean:
        z3_features = [z3.Bool(j) for j in features]
    else:
        z3_features = [z3.Int(j) for j in features]

    log.info("Search for dead features")
    solver.add(
        z3.ForAll(
            z3_features + [z3.Int(j) for j in attributes.keys()] +
            [z3.Int(j) for j in contexts if j != time_context],
            z3.Implies(
                z3.And([
                    z3.Implies(
                        z3.Bool(i + fresh_var),
                        z3.Bool(i) if features_as_boolean else
                        z3.Int(i).__eq__(z3.IntVal(1)))
                    for i in opt_features_ls
                ]), z3.Not(z3.And(formulas)))))
    log.debug(unicode(solver))

    while True:
        log.info("Computing")
        result = solver.check()

        if result == z3.sat:
            model = solver.model()
            for i in opt_features_ls:
                if model[z3.Bool(i + fresh_var)] == z3.BoolVal(True):
                    found_feature = i
                    break
            assert found_feature
            found_context = model[z3.Int(time_context)].as_long()

            # remove check for false optional
            log.debug("Dead feature for time {}: {}".format(
                found_context, found_feature))
            if found_feature in data["dead_features"]:
                data["dead_features"][found_feature].append(found_context)
            else:
                data["dead_features"][found_feature] = [found_context]
            # add constraint for next iteration
            solver.add(
                z3.Not(
                    z3.And(
                        z3.Bool(found_feature + fresh_var),
                        z3.Int(time_context).__eq__(
                            z3.IntVal(found_context)))))
        elif result == z3.unsat:
            log.debug("Formula found unsat. No more dead features.")
            break
        else:
            log.critical(
                "SMT solver can not solve the forall formula (result unknown)."
            )
            log.critical("Exiting")
            sys.exit(1)

    solver.pop()

    log.info("Search for false positive features")
    solver.add(
        z3.ForAll(
            z3_features + [z3.Int(j) for j in attributes.keys()] +
            [z3.Int(j) for j in contexts if j != time_context],
            z3.Implies(
                z3.And([
                    z3.Implies(
                        z3.Bool(i + fresh_var),
                        z3.Not(z3.Bool(i)) if features_as_boolean else
                        z3.Int(i).__eq__(z3.IntVal(0)))
                    for i in opt_features_ls
                ]), z3.Not(z3.And(formulas)))))

    log.info("Remove also the checks for the {} features found dead".format(
        len(data["dead_features"])))
    for i in data["dead_features"]:
        for j in data["dead_features"][i]:
            solver.add(
                z3.Not(
                    z3.And(z3.Bool(i + fresh_var),
                           z3.Int(time_context).__eq__(z3.IntVal(j)))))
    #log.debug(unicode(solver))

    while True:
        log.info("Computing")
        result = solver.check()

        if result == z3.sat:
            model = solver.model()
            for i in opt_features_ls:
                if model[z3.Bool(i + fresh_var)] == z3.BoolVal(True):
                    found_feature = i
                    break
            assert found_feature
            found_context = model[z3.Int(time_context)].as_long()
            log.debug("False positive feature for time {}: {}".format(
                found_context, found_feature))
            if found_feature in data["false_optionals"]:
                data["false_optionals"][found_feature].append(found_context)
            else:
                data["false_optionals"][found_feature] = [found_context]
            # add constraint for next iteration
            solver.add(
                z3.Not(
                    z3.And(
                        z3.Bool(found_feature + fresh_var),
                        z3.Int(time_context).__eq__(
                            z3.IntVal(found_context)))))
        elif result == z3.unsat:
            log.debug("Formula found unsat. No more false positives.")
            break
        else:
            log.critical(
                "SMT solver can not solve the forall formula (result unknown)."
            )
            log.critical("Exiting")
            sys.exit(1)

    log.info("Printing output")
    json.dump(data, out_stream)
    out_stream.write("\n")
Beispiel #10
0
 def int012(self, x, y, d):
     v = z3.Int("%d,%d,%s" % (x, y, d))
     self.solver.add(v >= 0)
     self.solver.add(v <= 2)
     return v
Beispiel #11
0
def get_z3_formula(sketch_ir: str, input_bits: int) -> z3.QuantifierRef:
    """Given an intermediate representation of a sketch file and returns a z3
    formula corresponding to that IR with the specified input bits for source
    variables."""

    z3_vars = collections.OrderedDict()
    z3_asserts = []
    z3_srcs = []
    for line in sketch_ir.splitlines():
        records = line.split()
        start = records[0]
        if (start in ['dag', 'TUPLE_DEF']):
            continue
        else:
            # common processing across all nodes
            output_var = '_n' + records[0]
            operation = records[2]
            if operation in ['NEG', 'NOT']:
                operand1 = z3_vars['_n' + records[4]]
                check_sort(operand1)
            elif operation in [
                    'AND', 'OR', 'XOR', 'PLUS', 'TIMES', 'DIV', 'MOD', 'LT',
                    'EQ'
            ]:
                operand1 = z3_vars['_n' + records[4]]
                operand2 = z3_vars['_n' + records[5]]
                check_sort(operand1)
                check_sort(operand2)

            # node-specific processing
            if operation == 'ASSERT':
                z3_asserts += ['_n' + records[3]]
            elif operation == 'S':
                var_type = records[3]
                source_name = records[4]
                assert var_type == 'INT', ('Unexpected variable type found in \
                        sketch IR:', line)
                z3_vars[source_name] = z3.Int(source_name)
                z3_vars[output_var] = z3.Int(source_name)
                z3_srcs += [source_name]
            elif operation in ['NEG']:
                z3_vars[output_var] = -make_int(operand1)
            elif operation in ['NOT']:
                z3_vars[output_var] = z3.Not(make_bool(operand1))
            elif operation in [
                    'AND', 'OR', 'XOR', 'PLUS', 'TIMES', 'DIV', 'MOD', 'LT',
                    'EQ'
            ]:
                if operation == 'AND':
                    z3_vars[output_var] = z3.And(make_bool(operand1),
                                                 make_bool(operand2))
                elif operation == 'OR':
                    z3_vars[output_var] = z3.Or(make_bool(operand1),
                                                make_bool(operand2))
                elif operation == 'XOR':
                    z3_vars[output_var] = z3.Xor(make_bool(operand1),
                                                 make_bool(operand2))
                elif operation == 'PLUS':
                    z3_vars[output_var] = make_int(operand1) + make_int(
                        operand2)
                elif operation == 'TIMES':
                    z3_vars[output_var] = make_int(operand1) * make_int(
                        operand2)
                elif operation == 'DIV':
                    z3_vars[output_var] = make_int(operand1) / make_int(
                        operand2)
                elif operation == 'MOD':
                    z3_vars[output_var] = make_int(operand1) % make_int(
                        operand2)
                elif operation == 'LT':
                    z3_vars[output_var] = make_int(operand1) < make_int(
                        operand2)
                elif operation == 'EQ':
                    z3_vars[output_var] = make_int(operand1) == make_int(
                        operand2)
                else:
                    assert False, ('Invalid operation', operation)
            # One can consider ARRACC and ARRASS as array access and
            # assignment. For more details please refer this sketchusers
            # mailing list thread.
            # https://lists.csail.mit.edu/pipermail/sketchusers/2019-August/000104.html
            elif operation in ['ARRACC']:
                predicate = make_bool((z3_vars['_n' + records[4]]))
                yes_val = z3_vars['_n' + records[7]]
                no_val = z3_vars['_n' + records[6]]
                z3_vars[output_var] = z3.If(predicate, yes_val, no_val)
            elif operation in ['ARRASS']:
                var_type = type(z3_vars['_n' + records[4]])
                if var_type == z3.BoolRef:
                    assert records[6] in ['0', '1']
                    cmp_constant = records[6] == '1'
                elif var_type == z3.ArithRef:
                    cmp_constant = int(records[6])
                else:
                    assert False, ('Variable type', var_type, 'not supported')
                predicate = z3_vars['_n' + records[4]] == cmp_constant
                yes_val = z3_vars['_n' + records[8]]
                no_val = z3_vars['_n' + records[7]]
                z3_vars[output_var] = z3.If(predicate, yes_val, no_val)
            elif operation in ['CONST']:
                var_type = records[3]
                if var_type == 'INT':
                    z3_vars[output_var] = z3.IntVal(int(records[4]))
                elif var_type == 'BOOL':
                    assert records[4] in ['0', '1']
                    z3_vars[output_var] = z3.BoolVal(records[4] == '1')
                else:
                    assert False, ('Constant type', var_type, 'not supported')
            else:
                assert False, ('Unknown operation:', line)

    # To handle cases where we don't have any assert or source variable, add
    # a dummy bool variable.
    constraints = z3.BoolVal(True)
    for var in z3_asserts:
        constraints = z3.And(constraints, z3_vars[var])

    variable_range = z3.BoolVal(True)
    for var in z3_srcs:
        variable_range = z3.And(
            variable_range,
            z3.And(0 <= z3_vars[var], z3_vars[var] < 2**input_bits))

    final_assert = z3.ForAll([z3_vars[x] for x in z3_srcs],
                             z3.Implies(variable_range, constraints))
    # We could use z3.simplify on the final assert, however that could result
    # in a formula that is oversimplified and doesn't have a QuantfierRef which
    # is expected from the negated_body() function above.
    return final_assert
Beispiel #12
0
    def _baseCondition(self):
        """ Set up base conditions for the network"""
        # Basic constraints for the overall model
        n_0 = z3.Const('ctx_base_n_0', self.node)
        n_1 = z3.Const('ctx_base_n_1', self.node)
        n_2 = z3.Const('ctx_base_n_2', self.node)
        n_3 = z3.Const('ctx_base_n_3', self.node)
        n_4 = z3.Const('ctx_base_n_4', self.node)
        p_0 = z3.Const('ctx_base_p_0', self.packet)
        t_0 = z3.Int('ctx_base_t_0')
        t_1 = z3.Int('ctx_base_t_1')

        # $$send(n_0, n_1, p_0, t_0) \Rightarrow n_0 \neq n_1$$
        self.constraints.append(
                z3.ForAll([n_0, n_1, p_0, t_0], \
                    z3.Implies(self.send(n_0, n_1, p_0, t_0), n_0 != n_1)))

        # $$recv(n_0, n_1, p_0, t_0) \Rightarrow n_0 \neq n_1$$
        self.constraints.append(
                z3.ForAll([n_0, n_1, p_0, t_0], \
                    z3.Implies(self.recv(n_0, n_1, p_0, t_0), n_0 != n_1)))

        # $$send(n_0, n_1, p_0, t_0) \Rightarrow p_0.src \neq p_0.dest$$
        self.constraints.append(
                z3.ForAll([n_0, n_1, p_0, t_0], \
                    z3.Implies(self.send(n_0, n_1, p_0, t_0), \
                                    self.packet.src(p_0) != self.packet.dest(p_0))))

        # $$recv(n_0, n_1, p_0, t_0) \Rightarrow p_0.src \neq p_0.dest$$
        self.constraints.append(
                z3.ForAll([n_0, n_1, p_0, t_0], \
                    z3.Implies(self.recv(n_0, n_1, p_0, t_0), \
                                    self.packet.src(p_0) != self.packet.dest(p_0))))

        # $$recv(n_0, n_1, p_0, t_0) \Rightarrow send(n_0, n_1, p_0, t_1) \land t_1 < t_0$$
        self.constraints.append(
                z3.ForAll([n_0, n_1, p_0, t_0], \
                    z3.Implies(self.recv(n_0, n_1, p_0, t_0), \
                                z3.Exists([t_1], \
                                   z3.And(self.send(n_0, n_1, p_0, t_1), \
                                        t_1 < t_0)))))
        # $$send(n_0, n_1, p_0, t_0) \Rightarrow p_0.src\_port > \land p_0.dest\_port < MAX_PORT$$
        self.constraints.append(
                z3.ForAll([n_0, n_1, p_0, t_0], \
                    z3.Implies(self.send(n_0, n_1, p_0, t_0), \
                                    z3.And(self.src_port(p_0) >= 0, \
                                            self.src_port(p_0) < Core.MAX_PORT))))
        # $$recv(n_0, n_1, p_0, t_0) \Rightarrow p_0.src\_port > \land p_0.dest\_port < MAX_PORT$$
        self.constraints.append(
                z3.ForAll([n_0, n_1, p_0, t_0], \
                    z3.Implies(self.recv(n_0, n_1, p_0, t_0), \
                                    z3.And(self.dest_port(p_0) >= 0, \
                                            self.dest_port(p_0) < Core.MAX_PORT))))
        # $$recv(n_0, n_1, p_0, t_0) \Rightarrow t_0 > 0$$
        self.constraints.append(
                z3.ForAll([n_0, n_1, p_0, t_0], \
                    z3.Implies(self.recv(n_0, n_1, p_0, t_0), \
                                   t_0 > 0)))
        # $$send(n_0, n_1, p_0, t_0) \Rightarrow t_0 > 0$$
        self.constraints.append(
                z3.ForAll([n_0, n_1, p_0, t_0], \
                    z3.Implies(self.send(n_0, n_1, p_0, t_0), \
                                   t_0 > 0)))
Beispiel #13
0
    def visit_RelExp (self, node, *args, **kwargs):
        #print("vREL+EXP")
        #print("state in REL",kwargs['state'])
        #print("node in relexp",node)

        lhs = self.visit (node.arg (0), *args, **kwargs)
        #print("lhs at 127", lhs)
        #print(lhs.type)
        rhs = self.visit (node.arg (1), *args, **kwargs)
        st=kwargs['state']
        if node.op == '<=':
            # if isinstance(lhs, unicode) or isinstance(lhs, z3.ArithRef):
            #     #Above judge is lhs is a symbol or lhs is a expression can be valued in z3
            if 'if' in kwargs:
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)

                if not isinstance(lhs,z3.IntNumRef):
                    #print("no a integer for lhs")
                    kwargs['state']=build_rst_lst(node.op,lhs,rhs,st)
                else:
                    #print("a integer for lhs")
                    if not isinstance(rhs, z3.ArithRef):
                        rhs = z3.Int(rhs)
                    kwargs['state'] =build_rst_lst(node.op,lhs,rhs,st)

                kwargs['cond']=not st.is_empty()
                return kwargs

            if 'while' in kwargs:
                #when lhs = X or Y some symbol
                #print("should not change type lhs",type(lhs))
                if not isinstance(lhs, z3.ArithRef) and not isinstance(lhs,int):
                    ## not a instance of z3.Arith
                    #print("I am in 480")
                    lhs = z3.Int(lhs)
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)
                if not isinstance(lhs,z3.IntNumRef):
                # if kwargs['times'] == 0 and not isinstance(lhs, z3.IntNumRef):
                    # the first run the while loop and lhs != Integer
                    kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                    #print("189 state in while", kwargs['state'])


                kwargs['cond']=not st.is_empty()
                return kwargs
            if 'assert' in kwargs:
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                kwargs['cond']=not st.is_empty()
                return kwargs
            if not isinstance(lhs, z3.ArithRef):
                lhs = z3.Int(lhs)
            st.add_pc(opp(node.op, lhs, rhs))
            kwargs['state'] = st
            kwargs['cond'] = not st.is_empty()
            return kwargs


        if node.op == '<':
            # if isinstance(lhs, unicode) or isinstance(lhs, z3.ArithRef):
            #     #Above judge is lhs is a symbol or lhs is a expression can be valued in z3
            if 'if' in kwargs:
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)

                if not isinstance(lhs,z3.IntNumRef):
                    #print("no a integer for lhs")
                    kwargs['state']=build_rst_lst(node.op,lhs,rhs,st)
                else:
                    #print("a integer for lhs")
                    if not isinstance(rhs, z3.ArithRef):
                        rhs = z3.Int(rhs)
                    kwargs['state'] =build_rst_lst(node.op,lhs,rhs,st)

                kwargs['cond']=not st.is_empty()
                return kwargs

            if 'while' in kwargs:
                #when lhs = X or Y some symbol
                #print("should not change type lhs",type(lhs))
                if not isinstance(lhs, z3.ArithRef) and not isinstance(lhs,int):
                    ## not a instance of z3.Arith
                    #print("I am in 480")
                    lhs = z3.Int(lhs)
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)
                if not isinstance(lhs,z3.IntNumRef):
                # if kwargs['times'] == 0 and not isinstance(lhs, z3.IntNumRef):
                    # the first run the while loop and lhs != Integer
                    kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                    #print("189 state in while", kwargs['state'])


                kwargs['cond']=not st.is_empty()
                return kwargs
            if 'assert' in kwargs:
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                kwargs['cond']=not st.is_empty()
                return kwargs
            if not isinstance(lhs, z3.ArithRef):
                lhs = z3.Int(lhs)
            st.add_pc(opp(node.op, lhs, rhs))
            kwargs['state'] = st
            kwargs['cond'] = not st.is_empty()
            return kwargs

        if node.op == '=':
            # if isinstance(lhs, unicode) or isinstance(lhs, z3.ArithRef):
            #     #Above judge is lhs is a symbol or lhs is a expression can be valued in z3
            if 'if' in kwargs:
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)

                if not isinstance(lhs,z3.IntNumRef):
                    #print("no a integer for lhs")
                    kwargs['state']=build_rst_lst(node.op,lhs,rhs,st)
                else:
                    #print("a integer for lhs")
                    if not isinstance(rhs, z3.ArithRef):
                        rhs = z3.Int(rhs)
                    kwargs['state'] =build_rst_lst(node.op,lhs,rhs,st)

                kwargs['cond']=not st.is_empty()
                return kwargs

            if 'while' in kwargs:
                #when lhs = X or Y some symbol
                #print("should not change type lhs",type(lhs))
                if not isinstance(lhs, z3.ArithRef) and not isinstance(lhs,int):
                    ## not a instance of z3.Arith
                    #print("I am in 480")
                    lhs = z3.Int(lhs)
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)
                if not isinstance(lhs,z3.IntNumRef):
                # if kwargs['times'] == 0 and not isinstance(lhs, z3.IntNumRef):
                    # the first run the while loop and lhs != Integer
                    kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                    #print("189 state in while", kwargs['state'])


                kwargs['cond']=not st.is_empty()
                return kwargs
            if 'assert' in kwargs:
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                kwargs['cond']=not st.is_empty()
                return kwargs
            if not isinstance(lhs, z3.ArithRef):
                lhs = z3.Int(lhs)
            st.add_pc(opp(node.op, lhs, rhs))
            kwargs['state'] = st
            kwargs['cond'] = not st.is_empty()
            return kwargs

        if node.op == '>=':
            # if isinstance(lhs, unicode) or isinstance(lhs, z3.ArithRef):
            #     #Above judge is lhs is a symbol or lhs is a expression can be valued in z3
            if 'if' in kwargs:
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)

                if not isinstance(lhs,z3.IntNumRef):
                    #print("no a integer for lhs")
                    kwargs['state']=build_rst_lst(node.op,lhs,rhs,st)
                else:
                    #print("a integer for lhs")
                    if not isinstance(rhs, z3.ArithRef):
                        rhs = z3.Int(rhs)
                    kwargs['state'] =build_rst_lst(node.op,lhs,rhs,st)

                kwargs['cond']=not st.is_empty()
                return kwargs

            if 'while' in kwargs:
                #when lhs = X or Y some symbol
                #print("should not change type lhs",type(lhs))
                if not isinstance(lhs, z3.ArithRef) and not isinstance(lhs,int):
                    ## not a instance of z3.Arith
                    #print("I am in 480")
                    lhs = z3.Int(lhs)
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)
                if not isinstance(lhs,z3.IntNumRef):
                # if kwargs['times'] == 0 and not isinstance(lhs, z3.IntNumRef):
                    # the first run the while loop and lhs != Integer
                    kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                    #print("189 state in while", kwargs['state'])


                kwargs['cond']=not st.is_empty()
                return kwargs
            if 'assert' in kwargs:
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                kwargs['cond']=not st.is_empty()
                return kwargs
            if not isinstance(lhs, z3.ArithRef):
                lhs = z3.Int(lhs)
            st.add_pc(opp(node.op, lhs, rhs))
            kwargs['state'] = st
            kwargs['cond'] = not st.is_empty()
            return kwargs

        if node.op == '>':
            # if isinstance(lhs, unicode) or isinstance(lhs, z3.ArithRef):
            #     #Above judge is lhs is a symbol or lhs is a expression can be valued in z3
            if 'if' in kwargs:
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)

                if not isinstance(lhs,z3.IntNumRef):
                    #print("no a integer for lhs")
                    kwargs['state']=build_rst_lst(node.op,lhs,rhs,st)
                else:
                    #print("a integer for lhs")
                    if not isinstance(rhs, z3.ArithRef):
                        rhs = z3.Int(rhs)
                    kwargs['state'] =build_rst_lst(node.op,lhs,rhs,st)

                kwargs['cond']=not st.is_empty()
                return kwargs

            if 'while' in kwargs:
                #when lhs = X or Y some symbol
                #print("should not change type lhs",type(lhs))
                if not isinstance(lhs, z3.ArithRef) and not isinstance(lhs,int):
                    ## not a instance of z3.Arith
                    #print("I am in 480")
                    lhs = z3.Int(lhs)
                if isinstance(lhs,int):
                    lhs=z3.IntVal(lhs)

                if isinstance(lhs,z3.IntNumRef) and isinstance(rhs,z3.IntNumRef):
                    #print("two integer branch")
                    return op_long(node.op,lhs,rhs)
                if not isinstance(lhs,z3.IntNumRef):
                # if kwargs['times'] == 0 and not isinstance(lhs, z3.IntNumRef):
                    # the first run the while loop and lhs != Integer
                    kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                    #print("189 state in while", kwargs['state'])


                kwargs['cond']=not st.is_empty()
                return kwargs
            if 'assert' in kwargs:
                if not isinstance(lhs, z3.ArithRef):
                    lhs = z3.Int(lhs)

                kwargs['state'] = build_rst_lst(node.op, lhs, rhs, st)
                kwargs['cond']=not st.is_empty()
                return kwargs
            if not isinstance(lhs, z3.ArithRef):
                lhs = z3.Int(lhs)
            st.add_pc(opp(node.op, lhs, rhs))
            kwargs['state'] = st
            kwargs['cond'] = not st.is_empty()
            return kwargs
Beispiel #14
0
o = z3.Optimize()

# define formal integer variables x, y, and z
x, y, z = z3.Ints('x y z')

# for each bot, define a function in_range_[i] which is
# 1 if the selected bot is in range, and 0 otherwise
in_range = []

for (k, bot) in enumerate(nanobots):
    _x = bot.x
    _y = bot.y
    _z = bot.z
    _r = bot.r
    in_range.append(z3.Int(f"in_range_{k}"))
    # this defines the in_range[k] function
    o.add(in_range[k] == z3.If(
        zabs(x - _x) + zabs(y - _y) + zabs(z - _z) <= _r, 1, 0))

# variable for the number of bots in range from the current bot
bots_in_range = z3.Int('bots_in_range')
o.add(bots_in_range == sum(in_range))

# variable for the distance of the current bot from (0,0)
magnitude = z3.Int('magnitude')
o.add(magnitude == zabs(x) + zabs(y) + zabs(z))

# now, we want to maximise the number of bots in range,
# while minimising our distance from the origin
# the order here is important!
Beispiel #15
0
def test_variable() -> None:
    assert Variable("RecordFlux").z3expr() == z3.Int("RecordFlux")
    assert z3.simplify(Sub(Variable("foo"), Variable("foo")).z3expr()) == z3.IntVal(0)
Beispiel #16
0
def run_feature_analysis_with_optimization(features,
                                           features_as_boolean,
                                           contexts,
                                           attributes,
                                           constraints,
                                           optional_features,
                                           non_incremental_solver,
                                           out_stream,
                                           time_context=""):
    """
    Performs the feature analysis task.
    Tries first to prune level features at the time with a given timeout.
    If the timeout expires then level is decreased
    When level reaches 1 than one of the possible dead features is checked using an or
    If found another more restricting or constraint is added, until all the dead features are found.
    """

    data = {"dead_features": {}, "false_optionals": {}}
    solver = z3.Solver()
    #solver = z3.Then('simplify', 'nla2bv', 'smt').solver()
    if non_incremental_solver:
        solver.set("combined_solver.solver2_timeout", 1)

    # if time variable is not defined, create a fictional one
    time_context = get_time_context(time_context, optional_features)

    log.debug("Add basic constraints")
    solver.add(
        get_basic_formula_list(features, attributes, contexts, constraints,
                               features_as_boolean))

    if not non_incremental_solver:
        log.debug("Preliminary check")
        solver.check()

    # list of the features to check
    to_check = get_dic_of_features_to_check(optional_features)
    to_check_dead = {i: set(to_check[i]) for i in to_check}
    to_check_false = {i: set(to_check[i]) for i in to_check}

    log.info("Features to check: {}, Time context".format(
        len(optional_features), len(to_check)))

    for i in to_check_dead:
        log.debug("Processing time instant {}, features to check {}".format(
            i, len(to_check_dead[i])))
        solver.push()
        solver.add(z3.Int(time_context).__eq__(z3.IntVal(i)))

        if not non_incremental_solver:
            log.debug("Preliminary check")
            solver.check()

        solver.push()

        log.debug("Checking for dead features")
        limit = STARTING_LEVEL_FEATURE_SPECULATIVE_PRUNING
        all_in_once = max(len(to_check_dead[i]) / 2, 1)
        all_in_once = min(limit, all_in_once)

        while to_check_dead[i]:

            log.debug("{} ({}) dead (false optional) features to check".format(
                len(to_check_dead[i]), len(to_check_false[i])))

            if all_in_once == 1:
                solver.set('smt.timeout', 4294967295)
                if features_as_boolean:
                    solver.add(z3.Or([z3.Bool(j) for j in to_check_dead[i]]))
                else:
                    solver.add(
                        z3.Or([
                            z3.Int(j).__eq__(z3.IntVal(1))
                            for j in to_check_dead[i]
                        ]))
            else:
                solver.push()
                solver.set('smt.timeout', SPECULATIVE_PRUNING_TIMEOUT)
                log.debug(
                    "Attempt to prune {} features at once".format(all_in_once))
                if features_as_boolean:
                    solver.add(
                        z3.PbGe([(z3.Bool(j), 1) for j in to_check_dead[i]],
                                all_in_once))
                else:
                    solver.add(
                        z3.PbGe([(z3.Int(j).__eq__(z3.IntVal(1)), 1)
                                 for j in to_check_dead[i]], all_in_once))

            result = solver.check()
            log.debug("Solver result {}".format(result))
            if result == z3.unsat:
                if all_in_once == 1:
                    to_check_false[i].difference_update(to_check_dead[i])
                    for j in to_check_dead[i]:
                        if j in data["dead_features"]:
                            data["dead_features"][j].append(i)
                        else:
                            data["dead_features"][j] = [i]
                    break
                else:
                    solver.pop()
                    all_in_once = max(all_in_once / 2, 1)
            elif result == z3.sat:
                to_remove_dead, to_remove_false = get_fail_checks_from_model(
                    to_check_dead[i], to_check_false[i], solver.model(),
                    features_as_boolean)
                to_check_dead[i].difference_update(to_remove_dead)
                to_check_false[i].difference_update(to_remove_false)

                if all_in_once != 1:
                    solver.pop()
                all_in_once = max(min(all_in_once,
                                      len(to_check_dead[i]) / 2), 1)
                all_in_once = min(limit, all_in_once)
            else:
                log.debug(
                    "Execution not terminated without the timeout. Moving on")
                solver.pop()
                all_in_once = max(all_in_once / 2, 1)

        solver.pop()
        solver.push()

        log.debug("Checking for false optional features")
        while to_check_false[i]:
            log.debug("{} false optional features to check".format(
                len(to_check_false[i])))
            if features_as_boolean:
                solver.add(
                    z3.Or([z3.Not(z3.Bool(j)) for j in to_check_false[i]]))
            else:
                solver.add(
                    z3.Or([
                        z3.Int(j).__eq__(z3.IntVal(0))
                        for j in to_check_false[i]
                    ]))
            result = solver.check()
            if result == z3.unsat:
                for j in to_check_false[i]:
                    if j in data["false_optionals"]:
                        data["false_optionals"][j].append(i)
                    else:
                        data["false_optionals"][j] = [i]
                break
            elif result == z3.sat:
                _, to_remove_false = get_fail_checks_from_model(
                    [], to_check_false[i], solver.model(), features_as_boolean)
                to_check_false[i].difference_update(to_remove_false)
        solver.pop()
        solver.pop()

    log.info("Printing output")
    json.dump(data, out_stream)
    out_stream.write("\n")
Beispiel #17
0
#P4 - mask that identifies rightmost 1-bit and trailing 0s

import z3
#from z3 import * considered bad practice but defines namespace z3

# List of Variables
I = z3.BitVec('I', 8)
O = z3.BitVec('O',8)
Y1 = z3.BitVec('Y1',8)
Y2 = z3.BitVec('Y2',8)
X11 = z3.BitVec('X11',8)
X21 = z3.BitVec('X21',8)
X22 = z3.BitVec('X22',8)

# List of numbering for each variables
ly1 = z3.Int('ly1')
ly2 = z3.Int('ly2')

lx11 = z3.Int('lx11')
lx12 = z3.Int('lx12')
lx21 = z3.Int('lx21')
lx22 = z3.Int('lx22')

# List of components.
phi1 = (Y1 == (X11 - 1))
phi2 = (Y2 == X21 ^ X22)

# Write the spec
spec_list = []
for t in range(8) :
    input_extract = []
Beispiel #18
0
def run_model_test(model: ModelProto):
    data = bytearray(("1" * 32).encode())
    x = np.array(data, dtype=np.int64)
    i = np.array([0], dtype=np.int64)
    keep_going = np.array([True], dtype=np.bool)
    max_index = np.array([32], dtype=np.int64)
    model_rep = prepare(model)
    standard = model_rep.run([x, i, keep_going, max_index])[1].reshape(
        (1, 30))[0]
    res = []
    for c in range(0, 32):
        inp = "1" * c + "2" + "1" * (31 - c)
        data = bytearray((inp).encode())
        x = np.array(data, dtype=np.int64)
        i = np.array([0], dtype=np.int64)
        keep_going = np.array([True], dtype=np.bool)
        max_index = np.array([32], dtype=np.int64)
        model_rep = prepare(model)
        out = model_rep.run([x, i, keep_going, max_index])[1].reshape(
            (1, 30))[0]
        buf = (out - standard)
        res.append(buf)
        print(str(c) + ": " + str(buf))
    fin = [
        16780,
        9831,
        2538,
        14031,
        8110,
        19136,
        17547,
        13929,
        16911,
        20265,
        15014,
        24203,
        9238,
        12759,
        17883,
        5871,
        15265,
        13222,
        11014,
        8290,
        7843,
        16989,
        7222,
        20835,
        15431,
        4554,
        8498,
        11543,
        6214,
        7169,
    ]
    X = [z3.Int('x%s' % i) for i in range(32)]
    s = z3.Solver()
    for i in range(len(res[0])):
        string = ""
        for b in range(len(res)):
            if (res[b][i] != 0):
                string += f"{res[b][i]}*X[{b}]+"
        string = string[:-1] + f"=={fin[i]}"
        s.add(eval(string))
    for i in range(32):
        s.add(X[i] >= 32, X[i] < 126)
    print(s.check())
    for i in range(32):
        print(chr(int(s.model()[X[i]].as_string())), end="")
    print()
Beispiel #19
0
import z3
#745UI-82JFS-9KNDB-CBJO7-OUM4G
s = z3.Solver()

len_flag = 25
a1 = [z3.Int("flag{}".format(i)) for i in range(len_flag)]

# constraint printable
# for c in flag:
#     s.add(
#         z3.And(
#             ord(' ') <= c,
#             ord(' ') >= c))

s.add(a1[20] - a1[0] == 24)
s.add(a1[8] + a1[5] == 126)
s.add(a1[14] * a1[5] == 3696)
s.add(a1[21] - a1[1] == 33)
s.add(a1[10] - a1[0] == 2)
s.add(a1[17] - a1[0] == 19)
s.add(a1[17] * a1[1] == 3848)
s.add(a1[4] + a1[6] == 123)
s.add(a1[13] * a1[16] == 4488)
s.add(a1[1] * a1[6] == 2600)
s.add(a1[13] * a1[23] == 3536)
s.add(a1[8] - a1[5] == 14)
s.add(a1[15] + a1[5] == 123)
s.add(a1[20] - a1[17] == 5)
s.add(a1[17] + a1[16] == 140)
s.add(a1[16] + a1[14] == 132)
s.add(a1[3] * a1[6] == 4250)
Beispiel #20
0
#!/usr/bin/env python3
import z3
from z3 import *
import sys
import random

z3._main_ctx = None
z3.main_ctx()
z3.set_param('smt.random_seed', random.SystemRandom().randint(0, sys.maxsize))

a = z3.Int('a')
b = z3.Int('b')

f = z3.Function('f', IntSort(), IntSort())
s = z3.Solver()
s.add(ForAll([a, b], f(a*b)== a*f(b)))

x = z3.Int('x')
y = z3.Int('y')
s.add(f(x * y) != x * f(y))
print(s.check())

Beispiel #21
0
 def _z3expr(self, printable):
     return z3.Int(self.id)
Beispiel #22
0
def solve(s1, s2, s3):
    vars = {}
    solver = z3.Solver()
    for word in [s1, s2, s3]:
        for v in word:
            if v not in vars:
                vars[v] = z3.Int(v)
                solver.add(vars[v] >= 0)
                solver.add(vars[v] <= 9)

    val_a = reduce(lambda x, y: 10 * x + vars[y], s1, 0)
    val_b = reduce(lambda x, y: 10 * x + vars[y], s2, 0)
    val_c = reduce(lambda x, y: 10 * x + vars[y], s3, 0)
    solver.add(vars[s1[0]] != 0)
    solver.add(vars[s2[0]] != 0)
    solver.add(vars[s3[0]] != 0)
    solver.add(val_a + val_b == val_c)
    solver.add(z3.Distinct(vars.values()))

    if solver.check() == z3.sat:
        model = solver.model()
        print("The value of each letter for given words is calculated as:")
        print([(v, model[vars[v]]) for v in s1])

        init_const = 0.1

        for len_i in range(len(s1)):
            init_const = init_const * 10

        first_word = 0

        for vs1 in s1:
            vars_val = model[vars[vs1]]
            vv = vars_val.as_long()
            first_word = first_word + int(vv * init_const)
            init_const = init_const / 10

        #print(first_word)

        print([(v, model[vars[v]]) for v in s2])

        for len_i in range(len(s2)):
            init_const = init_const * 10

        second_word = 0

        for vs2 in s2:
            vars_val = model[vars[vs2]]
            vv = vars_val.as_long()
            second_word = second_word + int(vv * init_const)
            init_const = init_const / 10

        #print(second_word)

        print([(v, model[vars[v]]) for v in s3])

        for len_i in range(len(s3)):
            init_const = init_const * 10

        resultant_word = 0

        for vs3 in s3:
            vars_val = model[vars[vs3]]
            vv = vars_val.as_long()
            resultant_word = resultant_word + int(vv * init_const)
            init_const = init_const / 10

        #print(resultant_word)

        if first_word + second_word == resultant_word:
            return first_word, second_word, resultant_word

    else:
        print("failed to solve")

    # Replace with your solution
    pass
Beispiel #23
0
# List of Variables
I = z3.BitVec('I', 8)
O = z3.BitVec('O', 8)
Y1 = z3.BitVec('Y1', 8)
Y2 = z3.BitVec('Y2', 8)
Y3 = z3.BitVec('Y3', 8)
X11 = z3.BitVec('X11', 8)
X12 = z3.BitVec('X12', 8)
X21 = z3.BitVec('X21', 8)
X22 = z3.BitVec('X22', 8)
X31 = z3.BitVec('X31', 8)
X32 = z3.BitVec('X32', 8)

# List of numbering for each variables
ly1 = z3.Int('ly1')
ly2 = z3.Int('ly2')
ly3 = z3.Int('ly3')

lx11 = z3.Int('lx11')
lx12 = z3.Int('lx12')
lx21 = z3.Int('lx21')
lx22 = z3.Int('lx22')
lx31 = z3.Int('lx31')
lx32 = z3.Int('lx32')

# List of components.
phi1 = (Y1 == X11 >> 31)
phi2 = (Y2 == X21 ^ X22)
phi3 = (Y3 == X31 - X32)
Beispiel #24
0
import pprint

# In[2]:

import z3
#https://z3prover.github.io/api/html/z3py_8py_source.html

# In[3]:

optimizer = z3.Optimize()
optimizer.help()

# In[4]:

optimizer = z3.Optimize()
x = z3.Int('x')  # (declare-const x Int)
y = z3.Int('y')  #(declare-const y Int)

print(optimizer.param_descrs())
optimizer.assert_exprs(x < 2)  #(assert (< x 2))
optimizer.assert_exprs((y - x) > 1)  #(assert (> (- y x) 1))
my_max = optimizer.maximize(x + y)  #(maximize (+ x y))
my_min = optimizer.minimize(x + y)
#optimizer.set("priority", "box")
optimizer.check()  #(check-sat)
print(optimizer.lower(my_min))
print(optimizer.lower(my_max))
print(optimizer.upper(my_min))
print(optimizer.upper(my_max))
print(optimizer.model())
#print(optimizer.statistics())
Beispiel #25
0
 def symbolic(self, name):
     """
     Return a symbolic variable. As of now, only integers are handled.
     """
     return z3.Int(name)
Beispiel #26
0
# List of Variables
I = z3.BitVec('I', 8)
O = z3.BitVec('O', 8)
Y1 = z3.BitVec('Y1', 8)
Y2 = z3.BitVec('Y2', 8)
Y3 = z3.BitVec('Y3', 8)
Y4 = z3.BitVec('Y4', 8)
X11 = z3.BitVec('X11', 8)
X21 = z3.BitVec('X21', 8)
X31 = z3.BitVec('X31', 8)
X41 = z3.BitVec('X41', 8)
X42 = z3.BitVec('X42', 8)

# List of numbering for each variables
ly1 = z3.Int('ly1')
ly2 = z3.Int('ly2')
ly3 = z3.Int('ly3')
ly4 = z3.Int('ly4')

lx11 = z3.Int('lx11')
lx21 = z3.Int('lx21')
lx31 = z3.Int('lx31')
lx41 = z3.Int('lx41')
lx42 = z3.Int('lx42')

# List of components. phi-lib
phi1 = (Y1 == X11 >> 31)
phi2 = (Y2 == -X21)
phi3 = (Y3 == (X31 >> 31) & 0x01)
phi4 = (Y4 == X41 | X42)
    def _parseSmt1String(self, string):
        #self._logger.setVerbose(True)
        stack = list()
        functionSymbols = '&|~<=*+-'
        try:
            string = string.replace('\n', '').split('(')
            idx = 0
            for pos, elem in enumerate(string):
                self._logger.writeToLog('{} - reading :{}:'.format(pos, elem))
                if elem == '':
                    continue

                elemL = elem.split()
                # ALL lines should start with '('
                if elemL[0] in functionSymbols:
                    stack.append(elemL[0])
                elif elemL[0] == 'var':
                    varName = elemL[2].replace(')', '')
                    if elemL[1] == 'bool':
                        formula = z3.Bool(varName)
                        stack.append(self._abstraction(formula))
                    elif elemL[1] == 'real':
                        formula = z3.Real(varName)
                        stack.append(formula)
                    elif elemL[1] == 'int':
                        formula = z3.Int(varName)
                        stack.append(formula)
                    else:
                        raise Exception(
                            'Unknown Variable format: {}'.format(elemL))
                elif elemL[0] == 'const':
                    const = elemL[2].replace(')', '')
                    if elemL[1] == 'real':
                        stack.append(z3.RealVal(const))
                    elif elemL[1] == 'int':
                        stack.append(z3.IntVal(const))
                    else:
                        raise Exception(
                            'Unknown Constant format: {}'.format(elemL))
                else:
                    raise Exception('Unknown format : {}'.format(elemL))

                closedBrackets = elem.count(')') - 1
                self._logger.writeToLog(
                    "{} - new element in stack: {}\t,cB {}".format(
                        pos, stack[-1], closedBrackets))

                if closedBrackets < 1:
                    continue

                while closedBrackets > 0:
                    self._logger.writeToLog('{} - stack: {},{}'.format(
                        pos, stack, closedBrackets))
                    tmpPredi = []
                    pred = None
                    while True:
                        pred = stack.pop()
                        #if isinstance(pred,Predicate) or isinstance(pred,z3.BoolRef) or str(pred).replace('.','',1).isdigit():
                        #if z3.is_rational_value(pred) or z3.is_int_value(pred) or z3.is_int(pred) or z3.is_real(pred) or z3.is_bool(pred):
                        if isinstance(pred, float) or isinstance(
                                pred, int) or z3.is_int(pred) or z3.is_real(
                                    pred) or z3.is_bool(pred):
                            tmpPredi.append(pred)
                        else:
                            if len(tmpPredi) == 1:
                                tmpPredi = tmpPredi[0]
                            else:
                                tmpPredi = tmpPredi[::-1]
                            break
                    self._logger.writeToLog('{} - {} is applied to {}'.format(
                        pos, pred, tmpPredi))
                    newElem = self._mapFunctionSymbol(pred)(tmpPredi)
                    # newElemSimplified = z3.simplify(newElem)
                    stack.append(newElem)
                    self._logger.writeToLog(
                        "{} - new element in stack: {}\t,cB {}".format(
                            pos, stack[-1], closedBrackets))
                    closedBrackets -= 1
                self._logger.writeToLog('{} - finished :{}:'.format(
                    pos, stack))
        except Exception as e:
            self._logger.writeToLog(
                "Some Error : {}\n\t Occured parsing formula: {}".format(
                    e, string))
            raise e

        if len(stack) != 1:
            raise Exception("Parsing Error, stack != 1")
        return self._recusiveSimplification(stack[0])
Beispiel #28
0
def walk_block(body):
    assumptions = []
    prog_path = []
    assertions = []
    for e in body.block_items:
        if isinstance(e, pycp.c_ast.Decl):
            vars[e.type.declname] = [e.type.type.names, []]
            if "int" in e.type.type.names:
                vars[e.type.declname][1].append(
                    z3.Int("%s__0_" % e.type.declname))
                vars[e.type.declname].append(vars[e.type.declname][1][-1])
            if "float" in e.type.type.names:
                vars[e.type.declname][1].append(
                    z3.Real("%s__0_" % e.type.declname))
                vars[e.type.declname].append(vars[e.type.declname][1][-1])
        elif isinstance(e, pycp.c_ast.FuncCall):
            if e.name.name == "__ASSUME":
                for e_exp in e.args.exprs:
                    assumptions.append(gen_smt_expr(e_exp))
            elif e.name.name == "__ASSERT":
                for e_exp in e.args.exprs:
                    assertions.append(gen_smt_expr(e_exp))
            else:
                print("found a func call")
        elif isinstance(e, pycp.c_ast.Assignment):
            rexp = gen_smt_expr(e.rvalue)
            if "int" in vars[e.lvalue.name][0]:
                vars[e.lvalue.name][1].append(
                    z3.Int("%s__%i_" %
                           (e.lvalue.name, len(vars[e.lvalue.name][1]))))
            elif "float" in vars[e.lvalue.name][0]:
                vars[e.lvalue.name][1].append(
                    z3.Real("%s__%i_" %
                            (e.lvalue.name, len(vars[e.lvalue.name][1]))))
            if e.op == "=":
                prog_path.append(vars[e.lvalue.name][1][-1] == rexp)
            elif e.op == "+=":
                prog_path.append(
                    vars[e.lvalue.name][1][-1] == (vars[e.lvalue.name][1][-2] +
                                                   rexp))
            elif e.op == "-=":
                prog_path.append(
                    vars[e.lvalue.name][1][-1] == (vars[e.lvalue.name][1][-2] -
                                                   rexp))
            elif e.op == "*=":
                prog_path.append(
                    vars[e.lvalue.name][1][-1] == (vars[e.lvalue.name][1][-2] *
                                                   rexp))
            elif e.op == "%=":
                prog_path.append(
                    vars[e.lvalue.name][1][-1] == (vars[e.lvalue.name][1][-2] %
                                                   rexp))
        elif isinstance(e, pycp.c_ast.If):
            cond_exp = gen_smt_expr(e.cond)
            curr_ix = {key: len(vars[key][1]) - 1 for key in vars}
            bool_exp_true, bool_exp_false = [], []
            if e.iftrue is not None and e.iftrue.block_items is not None:
                bool_exp_true = walk_block(e.iftrue)
                for key in curr_ix:
                    vars[key][1][curr_ix[key]], vars[key][1][-1] = vars[key][
                        1][-1], vars[key][1][curr_ix[key]]
            if e.iffalse is not None and e.iffalse.block_items is not None:
                bool_exp_false = walk_block(e.iffalse)
            for key in vars:
                if curr_ix[key] + 1 == len(vars[key][1]):
                    continue
                if "int" in vars[key][0]:
                    vars[key][1].append(
                        z3.Int("%s__%i_" % (key, len(vars[key][1]))))
                elif "float" in vars[key][0]:
                    vars[key][1].append(
                        z3.Real("%s__%i_" % (key, len(vars[key][1]))))
                bool_exp_true.append(
                    vars[key][1][-1] == vars[key][1][curr_ix[key]])
                bool_exp_false.append(vars[key][1][-1] == vars[key][1][-2])
            prog_path.append(
                z3.If(cond_exp, z3.And(bool_exp_true), z3.And(bool_exp_false)))

    li = assumptions + prog_path
    if assertions:
        if len(assertions) > 1:
            assertions = z3.And(assertions)
        else:
            assertions = assertions[0]
        li.append(z3.Not(assertions))
    return li
def from_bv_to_int_domain(z3from, typestr=None):
    """attempt to convert the-bit-vector expression z3from to the integer domain
    If this expression is a value, you can specify its type."""
    def return_and_log(z3from, result, msg=None):
        logger.info(" ")
        logger.info("---------------------------")
        logger.info("convert_from_bv_to_int_domain on: " + str(z3from.sexpr()))
        logger.info("convert result is " + str(result))
        logger.info("number of arguments at top level: " +
                    str(z3from.num_args()))
        if msg is not None:
            logger.info(msg)
        logger.info(
            "---------------------------------------------------------")
        logger.info(" ")
        return result

    #this is problematic... at times our pattern matching relies on simplification
    #e.g., different forms of extract, at times simplification can make things worse
    #TODO. remove the simplification by handling more patterns.
    z3from = z3.simplify(z3from, push_ite_bv=True)

    if z3from.decl().kind() == z3.Z3_OP_UNINTERPRETED:
        label = z3from.decl().name()
        return return_and_log(z3from, z3.Int(label))

    if not z3.is_expr(z3from):
        return return_and_log(z3from, z3from,
                              "CONVERSION ERROR: not an expression on ")

    if z3from.decl().kind() == z3.Z3_OP_SGEQ:
        (lhs, rhs) = get_lhs_rhs(z3from)
        return return_and_log(z3from, lhs >= rhs)

    if z3from.decl().kind() == z3.Z3_OP_SLEQ:
        (lhs, rhs) = get_lhs_rhs(z3from)
        return return_and_log(z3from, lhs <= rhs)

    if z3from.decl().kind() == z3.Z3_OP_SGT:
        (lhs, rhs) = get_lhs_rhs(z3from)
        return return_and_log(z3from, lhs > rhs)

    if z3from.decl().kind() == z3.Z3_OP_SLT:
        (lhs, rhs) = get_lhs_rhs(z3from)
        return return_and_log(z3from, lhs < rhs)

    if z3from.decl().kind() == z3.Z3_OP_BADD and z3from.num_args() == 2:
        (lhs, rhs) = get_lhs_rhs(z3from)
        return return_and_log(z3from, lhs + rhs)

    if z3from.decl().kind() == z3.Z3_OP_BMUL and z3from.num_args() == 2:
        (lhs, rhs) = get_lhs_rhs(z3from)
        return return_and_log(z3from, lhs * rhs)

    if z3from.decl().kind() == z3.Z3_OP_BSUB and z3from.num_args() == 2:
        (lhs, rhs) = get_lhs_rhs(z3from)
        return return_and_log(z3from, lhs - rhs)

    if z3from.decl().kind() == z3.Z3_OP_BADD and z3from.num_args() > 2:
        converted_children_list = get_children_of(z3from)
        for i in range(len(converted_children_list)):
            if i == 0:
                result = converted_children_list[0]
            else:
                result = result + converted_children_list[i]
        return return_and_log(z3from, result)

    #TODO >2 arguments for BMUL, BSUB, and other operators
    if z3from.decl().kind() == z3.Z3_OP_BNUM:
        if typestr is None:
            #all bitvectors are treated as signed long in the absence of typing
            return return_and_log(z3from, z3from.as_signed_long())
        if typestr == "intle:32" and z3from.size() == 32:
            return bv_value_to_int_value(z3from, typestr)
        if typestr == "intbe:32" and z3from.size() == 32:
            return bv_value_to_int_value(z3from, typestr)
        logger.warning("MORE CODE NEEDED TO HANDLE type " + typestr + "!!!!")
        return return_and_log(z3from, z3from.as_signed_long())
    #for BAR2020, we don't worry about premature simplification
    #if check_special_concat_extract_concat(z3from, typestr):
    if z3from.decl().kind() == z3.Z3_OP_CONCAT:
        #eliminate concat(concat(concat(... ) using simplify
        z3from_simplified = z3.simplify(z3from)
        #if all variables in the concat are the same
        all_are_extract = True
        same_variable = True
        is_bitvec32 = True
        ends_with_concat_of_zero = False
        ends_with_concat_of_zero_size = 0
        bv_variable = None
        last_variable = ""
        concat_extract_list = []
        for i in range(z3from_simplified.num_args()):
            arg = z3from_simplified.arg(i)
            if (z3.is_bv(arg) and arg.decl().kind() == z3.Z3_OP_BNUM
                    and i == z3from_simplified.num_args() - 1
                    and arg.as_signed_long() == 0):
                ends_with_concat_of_zero = True
                ends_with_concat_of_zero_size = arg.size()
                continue
            concat_extract_list.append(arg)
            if not arg.decl().kind() == z3.Z3_OP_EXTRACT:
                all_are_extract = False
            else:
                if i == 0:
                    last_variable = arg.arg(0).decl().name()
                    bv_variable = arg.arg(0)
                else:
                    if str(arg.arg(0)) != last_variable:
                        same_variable = False
                if not str(
                        arg.arg(0).sort()) == "BitVec(32)":  #TODO..find const
                    is_bitvec32 = False

        conditions = [all_are_extract, same_variable, is_bitvec32]
        if all(conditions):
            if not ends_with_concat_of_zero:
                if not is_typed_bv_le32(bv_variable):
                    return_and_log(
                        z3from, z3from,
                        "CONVERSION ERROR for " + bv_variable.decl().name() +
                        ", at present can only handle types of intle:32")
                if confirm_concat_little_endian_hypothesis(
                        32, concat_extract_list, 0):
                    return return_and_log(z3from, z3.Int(last_variable))
                return_and_log(
                    z3from, z3from,
                    "CONVERSION ERROR for " + bv_variable.decl().name() +
                    ", could not handle concat due to declared little endian "
                    + "but doesn't look like little endian")
            else:
                if not is_typed_bv_le32(bv_variable):
                    return_and_log(
                        z3from, z3from,
                        "CONVERSION ERROR for " + bv_variable.decl().name() +
                        " , at present can only handle types of intle:32")
                if confirm_concat_little_endian_hypothesis(
                        32, concat_extract_list,
                        ends_with_concat_of_zero_size):
                    constant = int(math.pow(2, ends_with_concat_of_zero_size))
                    return return_and_log(z3from,
                                          z3.Int(last_variable) * constant)
                return_and_log(
                    z3from, z3from,
                    "CONVERSION ERROR for " + bv_variable.decl().name() +
                    ", could not handle concat due to declared little endian "
                    + "but doesn't look like little endian")

        return return_and_log(
            z3from, z3from, "CONVERSION ERROR for " + str(z3from) +
            ", could not handle concat")

    if z3from.decl().kind() == z3.Z3_OP_AND:
        #deal with and of booleans and extract
        z3from_simplified = z3.simplify(z3from)
        # we need to pull out things of type Extract(31,24,y_intle:32) == 3
        equality_extracts = []
        other = []
        for i in range(z3from_simplified.num_args()):
            arg = z3from_simplified.arg(i)
            kind = arg.decl().kind()
            if not kind == z3.Z3_OP_EQ:
                other.append(arg)
                continue
            arg1kind = arg.arg(0).decl().kind()
            arg2kind = arg.arg(1).decl().kind()
            if not arg1kind == z3.Z3_OP_EXTRACT and not arg2kind == z3.Z3_OP_EXTRACT:
                other.append(arg)
                continue
            if not arg1kind == z3.Z3_OP_BNUM and not arg2kind == z3.Z3_OP_BNUM:
                other.append(arg)
                continue
            equality_extracts.append(arg)
        #TODO.now partition the extracts for different variables and different sizes,
        #e.g. intle:16, etc. for now, just see if there are exactly four of them
        if len(equality_extracts) == 0:
            process = []
            for x in other:
                process.append(from_bv_to_int_domain(x))
            return return_and_log(z3from, z3.And(*process),
                                  "via process and without equality extracts")
        if len(equality_extracts) == 4:
            #in z3, it is just a bit vector with extracts
            xbytes = [0, 0, 0, 0]
            for i in range(len(equality_extracts)):
                ee = equality_extracts[i]
                extract_arg = ee.arg(0)
                number_arg = ee.arg(1)
                #TODO...handle arg1 is the number
                if not extract_arg.decl().kind() == z3.Z3_OP_EXTRACT:
                    return return_and_log(z3from, z3from, "TROUBLE 1")
                if not number_arg.decl().kind() == z3.Z3_OP_BNUM:
                    return return_and_log(z3from, z3from, "TROUBLE 1b")
                partial_number = number_arg.as_long()
                #todo..what if the extract is not on a variable at all????
                if i == 0:
                    last_variable = extract_arg.arg(0).decl().name()
                elif not last_variable == extract_arg.arg(0).decl().name():
                    return return_and_log(z3from, z3from,
                                          "EXTRACT VARIABLES ARE DIFFERENT")
                start = extract_arg.params()[0]
                stop = extract_arg.params()[1]
                if start < stop or stop + 7 != start:
                    return return_and_log(
                        z3from, z3from, "TROUBLE3" + " start: " + str(start) +
                        " stop: " + str(stop))
                if stop == 0 or stop == 8 or stop == 16 or stop == 24:
                    xbytes[int(stop / 8)] = partial_number
                else:
                    return return_and_log(z3from, z3from, "TROUBLE 4")
            n = bitstring.pack('uint:8, uint:8, uint:8, uint:8', xbytes[3],
                               xbytes[2], xbytes[1], xbytes[0])
            #AGAIN NOTE SPECIAL TREATMENT AS INTLE
            extract_equality = z3.Int(last_variable) == n.intle
        else:
            return return_and_log(
                z3from, z3from, "extract equality on " +
                str(len(equality_extracts)) + " more needed")
        if len(other) > 0:
            #should be easy to fix
            return return_and_log(z3from, z3from,
                                  "FIX THE other booleans plus extract")
        return return_and_log(z3from, extract_equality)

    if z3from.decl().kind() == z3.Z3_OP_OR:
        #at present, no special checks for or
        orme = []
        for child in z3from.children():
            child_converted = from_bv_to_int_domain(child)
            orme.append(child_converted)
        result = z3.Or(orme)
        return return_and_log(z3from, result)

    if z3from.decl().kind() == z3.Z3_OP_NOT:
        child = from_bv_to_int_domain(z3from.children()[0])
        return return_and_log(z3from, z3.Not(child))

    if z3from.decl().kind() == z3.Z3_OP_EQ:
        if all_args_bitvectors(z3from):
            #special check for single bit extract
            if sign_check(z3from):
                answer = evaluate_sign_check(z3from)
                return return_and_log(z3from, answer)
            #else it is nothing special
            if sign_check_with_ite(z3from):
                answer = evaluate_sign_check_with_ite(z3from)
                return return_and_log(z3from, answer)
            (lhs, rhs) = get_lhs_rhs(z3from)
            return return_and_log(z3from, lhs == rhs)

        return return_and_log(z3from, z3.And(*z3from.children()),
                              "-----AVOIDED sign check, explore further")
    if z3from.decl().kind() == z3.Z3_OP_ITE:
        ite = []
        for child in z3from.children():
            child_converted = from_bv_to_int_domain(child)
            ite.append(child_converted)
        result = z3.If(ite[0], ite[1], ite[2])
        return return_and_log(z3from, result)
    if z3.is_bv(z3from):
        msg = ("CONVERSION ERROR!  No conversion options found for kind: " +
               str(z3from.decl().kind()) + " attempting to convert: " +
               str(z3from))
    else:
        msg = "did not pass any check"
    return return_and_log(z3from, z3from, msg)
Beispiel #30
0
import z3

hearts_8 = z3.Int('8 of Hearts')
diamonds_10 = z3.Int('10 of Diamonds')
club_king = z3.Int('King of Clubs')
spades_10 = z3.Int('10 of Spades')
diamonds_queen = z3.Int('Queen of Diamonds')

cards = [hearts_8, diamonds_10, club_king, spades_10, diamonds_queen]

s = z3.Solver()

# Each card must be in [1..5]
for card in cards:
    s.add(z3.And(card >= 1, card <= 5))

# No two cards can be in the same position
s.add(z3.Distinct(*cards))

def adjacent(a, b):
    return z3.Or(a - b == 1, b - a == 1)

# The diamonds are adjacent
s.add(adjacent(diamonds_10, diamonds_queen))

# The 10s are not adjacent
s.add(z3.Not(adjacent(diamonds_10, spades_10)))

# The 8 is somewhere above both 10s
s.add(z3.And(hearts_8 < diamonds_10, hearts_8 < spades_10))