Exemplo n.º 1
0
def infer_change(old, new):
    solver = z3.Optimize()
    included_features = {}
    positive_features = {}
    for feature, value in old.items():
        control_included = z3.Bool(f'|{feature} included|')
        control_positive = z3.Bool(f'|{feature} positive|')
        input_included = value != '0'
        input_positive = value == '+'
        output_included = new[feature] != '0'
        output_positive = new[feature] == '+'

        included_features[control_included] = feature
        positive_features[feature] = control_positive

        positive_explanations = []
        for implying_feature, implying_value in ipa_data.get_implying(
                feature, '+'):
            implying_included = z3.Bool(f'|{implying_feature} included|')
            implying_positive = z3.Bool(f'|{implying_feature} positive|')
            if implying_value == '+':
                positive_explanations.append(
                    z3.And(implying_included, implying_positive))
            else:
                positive_explanations.append(
                    z3.And(implying_included, z3.Not(implying_positive)))

        negative_explanations = []
        for implying_feature, implying_value in ipa_data.get_implying(
                feature, '-'):
            implying_included = z3.Bool(f'|{implying_feature} included|')
            implying_positive = z3.Bool(f'|{implying_feature} positive|')
            if implying_value == '+':
                positive_explanations.append(
                    z3.And(implying_included, implying_positive))
            else:
                positive_explanations.append(
                    z3.And(implying_included, z3.Not(implying_positive)))

        if not output_included:
            solver.add(z3.Not(control_included))

        solver.add(
            z3.If(
                z3.And(control_included, input_included),
                z3.And(output_included == control_included,
                       output_positive == control_positive),
                z3.Implies(
                    z3.And(input_included, output_included),
                    z3.Or(
                        output_positive == input_positive,
                        z3.And(output_positive, z3.Or(*positive_explanations),
                               z3.Not(z3.Or(*negative_explanations))),
                        z3.And(z3.Not(output_positive),
                               z3.Or(*negative_explanations),
                               z3.Not(z3.Or(*positive_explanations)))))))

    for var in included_features.keys():
        solver.add_soft(z3.Not(var))

    if solver.check() == z3.sat:
        rule = {}
        model = solver.model()
        for ident, feature in included_features.items():
            if model[ident]:
                positive_feature = positive_features[feature]
                rule[feature] = '+' if model[positive_feature] else '-'
        return rule
    else:
        print('unsat')
Exemplo n.º 2
0
 def visitB_term(self, ctx):
     formula = ctx.getChild(ctx.getChildCount() - 1).accept(self)
     if ctx.getChildCount() > 1:
         return z3.Not(formula)
     return formula
Exemplo n.º 3
0
 def z3Node(self):
     return z3.Not(self.sub.z3Node())
Exemplo n.º 4
0
 def rec(t):
     if t.is_var():
         z3_t = convert_const(t.name, t.T, ctx)
         if t.T == NatType and t.name not in assms:
             assms[t.name] = z3_t >= 0
         return z3_t
     elif t.is_forall():
         nm = name.get_variant_name(t.arg.var_name, var_names)
         var_names.append(nm)
         v = Var(nm, t.arg.var_T)
         z3_v = convert_const(nm, t.arg.var_T, ctx)
         return z3.ForAll(z3_v, rec(t.arg.subst_bound(v)))
     elif t.is_exists():
         nm = name.get_variant_name(t.arg.var_name, var_names)
         var_names.append(nm)
         v = Var(nm, t.arg.var_T)
         z3_v = convert_const(nm, t.arg.var_T, ctx)
         return z3.Exists(z3_v, rec(t.arg.subst_bound(v)))
     elif t.is_number():
         return t.dest_number()
     elif t.is_implies():
         return z3.Implies(rec(t.arg1), rec(t.arg))
     elif t.is_equals():
         return rec(t.arg1) == rec(t.arg)
     elif t.is_conj():
         return z3.And(rec(t.arg1), rec(t.arg)) if ctx is None else z3.And(
             rec(t.arg1), rec(t.arg), ctx)
     elif t.is_disj():
         return z3.Or(rec(t.arg1), rec(t.arg)) if ctx is None else z3.Or(
             rec(t.arg1), rec(t.arg), ctx)
     elif logic.is_if(t):
         b, t1, t2 = t.args
         return z3.If(rec(b), rec(t1), rec(t2), ctx)
     elif t.is_not():
         return z3.Not(rec(t.arg), ctx)
     elif t.is_plus():
         return rec(t.arg1) + rec(t.arg)
     elif t.is_minus():
         m, n = rec(t.arg1), rec(t.arg)
         if t.arg1.get_type() == NatType:
             return z3.If(m >= n, m - n, 0, ctx)
         return m - n
     elif t.is_uminus():
         return -rec(t.arg)
     elif t.is_times():
         return rec(t.arg1) * rec(t.arg)
     elif t.is_less_eq():
         return rec(t.arg1) <= rec(t.arg)
     elif t.is_less():
         return rec(t.arg1) < rec(t.arg)
     elif t.is_greater_eq():
         return rec(t.arg1) >= rec(t.arg)
     elif t.is_greater():
         return rec(t.arg1) > rec(t.arg)
     elif t.is_divides():
         return rec(t.arg1) / rec(t.arg)
     elif t.is_comb('of_nat', 1):
         if t.get_type() == RealType:
             if t.arg.is_var():
                 if t.arg.name not in to_real:
                     nm = name.get_variant_name("r" + t.arg.name, var_names)
                     var_names.append(nm)
                     to_real[t.arg.name] = nm
                     z3_t = convert_const(nm, RealType, ctx)
                     assms[nm] = z3_t >= 0
                     return z3_t
                 else:
                     return convert_const(to_real[t.arg.name], RealType,
                                          ctx)
             return z3.ToReal(rec(t.arg))
         else:
             raise Z3Exception("convert: unsupported of_nat " + repr(t))
     elif t.is_comb('max', 2):
         a, b = rec(t.arg1), rec(t.arg)
         return z3.If(a >= b, a, b, ctx)
     elif t.is_comb('min', 2):
         a, b = rec(t.arg1), rec(t.arg)
         return z3.If(a <= b, a, b, ctx)
     elif t.is_comb('abs', 1):
         a = rec(t.arg)
         return z3.If(a >= 0, a, -a, ctx)
     elif t.is_comb('member', 2):
         a, S = rec(t.arg1), rec(t.arg)
         return S(a)
     elif t.is_comb():
         return rec(t.fun)(rec(t.arg))
     elif t.is_const():
         if t == true:
             return z3.BoolVal(True, ctx)
         elif t == false:
             return z3.BoolVal(False, ctx)
         else:
             raise Z3Exception("convert: unsupported constant " + repr(t))
     else:
         raise Z3Exception("convert: unsupported operation " + repr(t))
Exemplo n.º 5
0
    def JUMPI(self, gstate, jump_addr, condition):
        new_gstates = []

        active_address = gstate.environment.active_address
        active_account = gstate.wstate.address_to_account[active_address]
        mstate = gstate.mstate

        jump_addr = svm_utils.get_concrete_int(jump_addr)
        function_entry = False

        gstate.jump_count += 1
        if (gstate.jump_count % 3 == 0 and
                gstate.jump_count > 20 and
                not svm_utils.check_wstate_reachable(gstate.wstate, 100)):
            gstate.halt = True
            return

        if gstate.pc_addr_to_depth.setdefault((gstate.mstate.pc, jump_addr), 0) >= 3:
            gstate.halt = True
            return
        increase_depth = True
        current_contract = active_account.contract
        line = solidity_utils.offset_to_line(current_contract.src_code, mstate.pc, current_contract.src_map)
        src_code = current_contract.src_code.split('\n')[line].strip()
        concrete_cond = False
        if 'assert' in src_code:
            increase_depth = False
        if type(condition) == bool:
            increase_depth = False
        else:
            simplified_cond = z3.simplify(condition)
            if z3.is_true(simplified_cond) or z3.is_false(simplified_cond):
                concrete_cond = True
                increase_depth = False
        if increase_depth:
            gstate.pc_addr_to_depth[(mstate.pc, jump_addr)] = gstate.pc_addr_to_depth[(mstate.pc, jump_addr)] + 1

        instr_idx = svm_utils.get_instruction_index(gstate.environment.disassembly.instruction_list, jump_addr)
        if instr_idx is None:
            raise SVMRuntimeError('JUMP to invalid address')
        dest_opcode = gstate.environment.disassembly.instruction_list[instr_idx]['opcode']
        if dest_opcode != 'JUMPDEST':
            raise SVMRuntimeError('JUMP to invalid address')

        condition = z3.BoolVal(condition) if isinstance(condition, bool) else condition
        condition = (condition == 0) if isinstance(condition, z3.BitVecRef) else condition
        assert isinstance(condition ,z3.BoolRef), 'Invalid condition types!'

        if not z3.is_false(z3.simplify(condition)):
            true_gstate = copy(gstate)
            true_gstate.mstate.pc = instr_idx
            true_gstate.wstate.constraints.append(condition)
            if true_gstate.wstate.trace is None:
                jump_func_name, jump_func_hash = gstate.environment.extract_func_name_hash(gstate.mstate.pc)
                if jump_func_name:
                    jump_trace = make_trace(active_account, jump_func_name)
                    logging.debug('Entering function %s', jump_trace)
                    true_gstate.wstate.trace = jump_trace
            new_gstates.extend(self.execute_gstate(true_gstate))

        negated_condition = z3.Not(condition)

        if not z3.is_false(z3.simplify(negated_condition)):
            false_gstate = copy(gstate)
            false_gstate.mstate.pc += 1
            false_gstate.wstate.constraints.append(negated_condition)
            new_gstates.extend(self.execute_gstate(false_gstate))

        gstate.halt = True
        return new_gstates
Exemplo n.º 6
0
 def get_gadget_constraint(self):
     A = self.get_output0() == self.binop(self.get_input0(),
                                          self.get_param0())
     return z3.Not(), None
Exemplo n.º 7
0
    def pred_to_z3(self, predicate_name, step_index, z3_head_vars):
        assert predicate_name in self.program.get_idb_predicate_names()

        z3_bodies = []
        z3_body_free_vars = []
        # Encode all rule bodies into Z3
        for rule in self.program.get_rules_for_predicate(predicate_name):

            skip_rule = False
            for literal in rule.get_literals():
                if literal.atom.name in self.program.get_recursive_idb_predicate_names(
                ) and step_index == 1:
                    skip_rule = True
            if skip_rule:
                continue

            substitution = {}
            for var_index in range(len(z3_head_vars)):
                substitution[rule.head.get_vars()
                             [var_index]] = z3_head_vars[var_index]

            z3_body_constraints = []
            # Keep track of all free variables in the body (which are existentially quantified later)

            # Encode all literals that appear in the body
            for literal in rule.get_literals():
                literal_predicate = self.get_predicate(literal.atom.name,
                                                       step_index)
                z3_literal_vars = []
                for literal_var_index in range(len(literal.get_vars())):
                    literal_var = literal.get_vars()[literal_var_index]
                    if literal_var.wildcard:  # e.g. Node(_, ..)
                        z3_fresh_var = self.get_fresh_var(
                            literal_predicate.domain(literal_var_index))
                        z3_body_free_vars.append(z3_fresh_var)
                        z3_literal_vars.append(z3_fresh_var)
                    elif literal_var in substitution.keys():
                        z3_literal_vars.append(substitution[literal_var])
                    else:
                        z3_fresh_var = self.get_fresh_var(
                            literal_predicate.domain(literal_var_index))
                        substitution[literal_var] = z3_fresh_var
                        z3_body_free_vars.append(z3_fresh_var)
                        z3_literal_vars.append(z3_fresh_var)
                if literal.atom.name in self.program.get_edb_predicate_names(
                ) or literal.atom.name in self.program.get_nonrecursive_idb_predicate_names(
                ):
                    if literal.negated:
                        z3_body_constraints.append(
                            z3.Not(literal_predicate(z3_literal_vars)))
                    else:
                        z3_body_constraints.append(
                            literal_predicate(z3_literal_vars))
                else:
                    if step_index > 1:
                        (tmp_free_vars, body_constraint) = self.pred_to_z3(
                            literal.atom.name, step_index - 1, z3_literal_vars)
                        z3_body_free_vars = z3_body_free_vars + tmp_free_vars
                        z3_body_constraints.append(body_constraint)
                    else:
                        z3_body_constraints.append(False)

            # Encode all comparisons that appear in the body (e.g. cost = cost1 + cost2)
            for comparison in rule.get_comparisons():
                # Assume all variables that appear in comparisons are bound to literals
                z3_left = substitution[comparison.left]
                z3_right_terms = []
                for right_term in comparison.right.get_terms():
                    if right_term.is_variable:
                        z3_right_terms.append(substitution[right_term])
                    elif right_term.is_constant and right_term.type == Constant.INTEGER_CONSTANT:
                        z3_right_terms.append(right_term.value)
                    elif right_term.is_constant and right_term.type == Constant.STRING_CONSTANT:
                        z3_right_terms.append(
                            get_string_const_val(right_term.value))
                    else:
                        raise NameError('Unknown term: {}'.format(right_term))
                if comparison.right.is_atomic:
                    z3_right = z3_right_terms[0]
                else:
                    if comparison.right.op == '+':
                        z3_right = reduce(lambda x, y: x + y, z3_right_terms)
                    else:
                        raise NameError(
                            'Add support for arithmetic expressions of type {}'
                            .format(comparison.right.op))
                if comparison.op == '<':
                    z3_comparison = z3_left < z3_right
                elif comparison.op == '=':
                    z3_comparison = z3_left == z3_right
                elif comparison.op == '!=':
                    z3_comparison = z3_left != z3_right
                else:
                    raise NameError(
                        'Add support for comparisons of type {}'.format(
                            comparison.op))
                z3_body_constraints.append(z3_comparison)

            # Get the conjunction of all z3 body constraints
            if len(z3_body_constraints) == 1:
                z3_body_constraints_conjunction = z3_body_constraints[0]
            else:
                z3_body_constraints_conjunction = z3.And(z3_body_constraints)
            z3_bodies.append(z3_body_constraints_conjunction)

        # Construct the Z3 constraint for the current predicate
        z3_constraint = z3.Or(
            z3_bodies) if len(z3_bodies) > 1 else z3_bodies[0]
        return (z3_body_free_vars, z3_constraint)
Exemplo n.º 8
0
def send_recv(old, pid, val, inpn, size, infd, outpn, outfd):
    cond = z3.And(
        is_pid_valid(pid),

        old.procs[pid].state == dt.proc_state.PROC_SLEEPING,

        # inpn is a valid pn and belongs to current
        is_pn_valid(inpn),
        old.pages[inpn].owner == old.current,

        z3.ULE(size, dt.PAGE_SIZE),

        z3.Implies(is_fd_valid(infd),
                   is_fn_valid(old.procs[old.current].ofile(infd))),

        # outpn is a valid pn and belongs to current
        is_pn_valid(outpn),
        old.pages[outpn].owner == old.current,
        old.pages[outpn].type == dt.page_type.PAGE_TYPE_FRAME,

        z3.Implies(is_fd_valid(outfd),
                   z3.Not(is_fn_valid(old.procs[old.current].ofile(outfd)))),

        # if ipc from is set, it must be set to current
        z3.Implies(old.procs[pid].ipc_from != 0,
                   old.procs[pid].ipc_from == old.current)
    )

    new = old.copy()

    new.procs[old.current].ipc_page = outpn
    new.procs[old.current].ipc_fd = outfd

    new.procs[pid].ipc_from = old.current
    new.procs[pid].ipc_val = val

    # memcpy
    new.pages.data = lambda pn0, idx0, oldfn=new.pages.data: \
        util.If(z3.And(pn0 == old.procs[pid].ipc_page, z3.ULT(idx0, size)),
                oldfn(inpn, idx0),
                oldfn(pn0, idx0))

    new.procs[pid].ipc_size = size

    new2 = new.copy()

    cond2 = z3.And(is_fd_valid(infd), is_fd_valid(new2.procs[pid].ipc_fd))

    fn = old.procs[old.current].ofile(infd)
    fd = old.procs[pid].ipc_fd

    new2.procs[pid].ofile[fd] = fn

    # bump proc nr_fds
    new2.procs[pid].nr_fds[fd] += 1

    # bump file refcnt
    new2.files[fn].refcnt[(pid, fd)] += 1

    new3 = util.If(cond2, new2, new)

    new3.procs[old.current].state = dt.proc_state.PROC_SLEEPING
    new3.procs[pid].state = dt.proc_state.PROC_RUNNING

    return cond, util.If(cond, new3, old)
Exemplo n.º 9
0
#create space for n variables
vars = [None] * n

#create n z3 Boolean variables
for i in range(0, n):
    vars[i] = z3.Bool("x" + str(i))

# looking for independent set of size 4
k = 4
# we need all combinations of n-k+1 variables
comb = n - k + 1
#instantiate a z3 solver
solver = z3.Solver()
#crearte an Or clause for each combination of n-k+1 variables
for c in itertools.combinations(vars, comb):
    solver.add(z3.Or(c))
# Add constraints on the edges
for (s, e) in edges:
    solver.add(z3.Or(z3.Not(vars[s]), z3.Not(vars[e])))

if (solver.check() == z3.sat):
    print("Found and IS of size {}".format(k))
    m = solver.model()
    for d in m.decls():
        if (m[d] == True):
            print(d.name())

else:
    print("No IS of size {} exits".format(k))
Exemplo n.º 10
0
    def to_z3(self):
        z3_constraints = []
        for predicate_name in self.program.get_idb_predicate_names():
            for step_index in range(
                    self.unroll_limit) + [self.unroll_limit + 1]:
                predicate = self.get_predicate(predicate_name, step_index + 1)
                #var_names = [ascii_uppercase[-i-1] for i in range(len(ascii_uppercase))]
                var_names = ['VAR%d' % i for i in range(2000)]

                z3_head_vars = []
                for var_id in range(predicate.arity()):
                    z3_head_vars.append(
                        z3.Const(var_names.pop(), predicate.domain(var_id)))
                # Declare the head Z3 predicate (e.g. node(X) == ...)
                z3_head = predicate(z3_head_vars)

                z3_bodies = []
                # Encode all rule bodies into Z3
                for rule in self.program.get_rules_for_predicate(
                        predicate_name):
                    lb_vars_to_z3_vars = {}
                    # Consistently substitute all variables that appear in the head
                    for arg_id in range(len(z3_head_vars)):
                        lb_vars_to_z3_vars[rule.head.get_vars()
                                           [arg_id]] = z3_head_vars[arg_id]

                    z3_body_constraints = []

                    # Keep track of all free variables in the body (which are existentially quantified later)
                    z3_body_free_vars = []

                    # Encode all literals that appear in the body
                    for literal in rule.get_literals():
                        literal_predicate = self.get_predicate(
                            literal.atom.name, step_index)
                        z3_body_vars = []
                        for body_var_index in range(len(literal.get_vars())):
                            body_var = literal.get_vars()[body_var_index]
                            if body_var.wildcard:  # e.g. Node(_, ..)
                                z3_fresh_var = z3.Const(
                                    var_names.pop(),
                                    literal_predicate.domain(body_var_index))
                                z3_body_free_vars.append(z3_fresh_var)
                                z3_body_vars.append(z3_fresh_var)
                            else:
                                if body_var not in lb_vars_to_z3_vars.keys():
                                    # Declare a fresh variable if it does not appear in the head
                                    z3_fresh_var = z3.Const(
                                        var_names.pop(),
                                        literal_predicate.domain(
                                            body_var_index))
                                    z3_body_free_vars.append(z3_fresh_var)
                                    lb_vars_to_z3_vars[body_var] = z3_fresh_var
                                z3_body_vars.append(
                                    lb_vars_to_z3_vars[body_var])
                        if literal.atom.name in self.recursive_idb_predicate_names and step_index == 0:
                            z3_body_constraints.append(False)
                            continue
                        if literal.negated:
                            z3_body_constraints.append(
                                z3.Not(literal_predicate(z3_body_vars)))
                        else:
                            z3_body_constraints.append(
                                literal_predicate(z3_body_vars))

                    # Encode all comparisons that appear in the body (e.g. cost = cost1 + cost2)
                    for comparison in rule.get_comparisons():
                        # Assume all variables that appear in comparisons are bound to literals
                        z3_left = lb_vars_to_z3_vars[comparison.left]
                        z3_right_terms = []
                        for right_term in comparison.right.get_terms():
                            if right_term.is_variable:
                                z3_right_terms.append(
                                    lb_vars_to_z3_vars[right_term])
                            elif right_term.is_constant and right_term.type == Constant.INTEGER_CONSTANT:
                                z3_right_terms.append(right_term.value)
                            elif right_term.is_constant and right_term.type == Constant.NODE_CONSTANT and right_term.value in STRING_TO_NODE.keys(
                            ):
                                z3_right_terms.append(
                                    STRING_TO_NODE[right_term.value])
                            elif right_term.is_constant and right_term.type == Constant.INTERFACE_CONSTANT and right_term.value in STRING_TO_INTERFACE.keys(
                            ):
                                z3_right_terms.append(
                                    STRING_TO_INTERFACE[right_term.value])
                            elif right_term.is_constant and right_term.type == Constant.NETWORK_CONSTANT and right_term.value in STRING_TO_NETWORK.keys(
                            ):
                                z3_right_terms.append(
                                    STRING_TO_NETWORK[right_term.value])
                            elif right_term.is_constant and right_term.type == Constant.STRING_CONSTANT and right_term.value in STRING_TO_BITVAL.keys(
                            ):
                                z3_right_terms.append(
                                    STRING_TO_BITVAL[right_term.value])
                            elif right_term.is_constant and right_term.type == Constant.NODE_CONSTANT and right_term.value not in STRING_TO_NODE.keys(
                            ) + STRING_TO_NETWORK.keys(
                            ) + STRING_TO_INTERFACE.keys(
                            ) + STRING_TO_BITVAL.keys():
                                z3_right_terms.append(
                                    get_string_const_val(right_term.value))
                            else:
                                raise NameError(
                                    'Unknown term: {}'.format(right_term))
                        if comparison.right.is_atomic:
                            z3_right = z3_right_terms[0]
                        else:
                            if comparison.right.op == '+':
                                z3_right = reduce(lambda x, y: x + y,
                                                  z3_right_terms)
                            else:
                                raise NameError(
                                    'Add support for arithmetic expressions of type {}'
                                    .format(comparison.right.op))
                        if comparison.op == '<':
                            z3_comparison = z3_left < z3_right
                        elif comparison.op == '=':
                            z3_comparison = z3_left == z3_right
                        elif comparison.op == '!=':
                            z3_comparison = z3_left != z3_right
                        else:
                            raise NameError(
                                'Add support for comparisons of type {}'.
                                format(comparison.op))
                        z3_body_constraints.append(z3_comparison)

                    # Get the conjunction of all z3 body constraints
                    if len(z3_body_constraints) == 1:
                        z3_body_constraints_conjunction = z3_body_constraints[
                            0]
                    else:
                        z3_body_constraints_conjunction = z3.And(
                            z3_body_constraints)
                    # Quantify free variables (if any)
                    if len(z3_body_free_vars) == 0:
                        z3_body = z3_body_constraints_conjunction
                    else:
                        z3_body = z3.Exists(z3_body_free_vars,
                                            z3_body_constraints_conjunction)

                    z3_bodies.append(z3_body)

                # Construct the Z3 constraint for the current predicate
                z3_constraint = z3.ForAll(
                    z3_head_vars, z3_head
                    == z3.Or(z3_bodies)) if len(z3_bodies) > 1 else z3.ForAll(
                        z3_head_vars,
                        predicate(z3_head_vars) == z3_bodies[0])

                z3_constraints.append(z3_constraint)
                if predicate_name in self.nonrecursive_idb_predicate_names:
                    break
        return z3_constraints
Exemplo n.º 11
0
 def get_gadget_constraint(self):
     return z3.Not(self.get_output0() == self.binop(
         self.get_input0(), self.get_input1())), None
Exemplo n.º 12
0
    def synthetize_rule(self, rule_num, model):
        """
        Synthetize a rule as close as possible to the trace.
        Print all the unstatisfiable steps and highlight anomalies.
        """
        self.solver.push()

        # fix dummy variables
        for soft in self.soft_constr[rule_num]:
            if model[soft.literal] == True:
                self.solver.add(soft.literal)
            elif model[soft.literal] == False:
                self.solver.add(z3.Not(soft.literal))

        # try to optimize intervals
        # cerco di trovare i numeri più grandi che soddisfano la regola.
        interval_cost = z3.Real('interval_cost')
        cost = []
        for j, const in enumerate(self.rules[rule_num].constraints):
            for k in const.greater_equal:
                cost.append(self.thresholds[rule_num][j][k])
            for k in const.lower_equal:
                cost.append(-self.thresholds[rule_num][j][k])

        total_cost = z3.Sum(cost)
        self.solver.add(interval_cost == total_cost)
        self.solver.minimize(interval_cost)

        # check if SAT or UNSAT
        print('Check Formulas')
        result = self.solver.check()
        # print(result)

        m = self.solver.model()
        # remove intervall optimization requirements
        self.solver.pop()

        # exit if unsat
        #in teoria non potrebbe mai essere unsat perchè l'abbiamo già risolto prima, ora abbiamo spostato solo le threshold.
        #se è unsat mi dovrebbe dare delle prove. (NON guardare i log)
        if result != z3.sat:
            print("IMPOSSIBLE TO SATISFY, ):")
            return

        # print results
        self.print_rule_result(rule_num, m)

        # generate 1000 random points inside the rule
        rule_points = []
        generated_points = 0
        #crei dei punti perchè potrei non aver visto tutti i casi strani dalle traccie.
        while generated_points < 1000:
            point = [0.0, 0.0, 0.0]
            point[0] = random.uniform(0.0, 1.0)
            point[1] = random.uniform(0.0, 1.0 - point[0])
            point[2] = 1.0 - point[0] - point[1]

            satisfy_a_constraint = False
            for i, constraint in enumerate(self.rules[rule_num].constraints):
                is_ok = True
                for c in constraint.lower_equal:
                    threshold = to_real(m[self.thresholds[rule_num][i][c]])
                    if point[c] > threshold:
                        is_ok = False
                        break
                if not is_ok:
                    continue

                for c in constraint.greater_equal:
                    threshold = to_real(m[self.thresholds[rule_num][i][c]])
                    if point[c] < threshold:
                        is_ok = False
                        break
                if not is_ok:
                    continue

                satisfy_a_constraint = True
                break

            if satisfy_a_constraint:
                rule_points.append(point)
                generated_points += 1

        # Hellinger distance of unsatisfiable steps
        failed_rules_diff_action = []
        Hellinger_min = []
        failed_step_counter = 0
        for num, soft in enumerate(self.soft_constr[rule_num]):
            if m[soft.literal] == False or not (self.actions_in_runs[soft.run][
                    soft.step] in self.rules[rule_num].speeds):
                continue
            failed_rules_diff_action.append(num)
            P = [
                self.belief_in_runs[soft.run][soft.step][0],
                self.belief_in_runs[soft.run][soft.step][1],
                self.belief_in_runs[soft.run][soft.step][2]
            ]
            hel_dst = [Hellinger_distance(P, Q) for Q in rule_points]
            Hellinger_min.append(min(hel_dst))

        # print unsatisfiable steps in decreasing order of hellinger distance
        print('Unsatisfiable steps same action:')
        #anomaly_positions = []
        for soft, hel in [[
                self.soft_constr[rule_num][x], h
        ] for h, x in sorted(zip(Hellinger_min, failed_rules_diff_action),
                             key=lambda pair: pair[0],
                             reverse=True)]:
            print("({})".format(failed_step_counter), end='')
            if hel > self.threshold:
                print('ANOMALY: ', end='')

            print(
                'run {} step {}: action {} with belief P_0 = {:.3f} P_1 = {:.3f} P_2 = {:.3f} --- Hellinger = {}'
                .format(self.run_folders[soft.run], soft.step,
                        self.actions_in_runs[soft.run][soft.step],
                        self.belief_in_runs[soft.run][soft.step][0],
                        self.belief_in_runs[soft.run][soft.step][1],
                        self.belief_in_runs[soft.run][soft.step][2], hel))
            failed_step_counter += 1
            # if hel > self.threshold:
            #     anomaly_positions.append(pos)

        failed_steps_same_action = []
        for num, soft in enumerate(self.soft_constr[rule_num]):
            if m[soft.literal] == False or (
                    self.actions_in_runs[soft.run][soft.step]
                    in self.rules[rule_num].speeds):
                continue
            failed_steps_same_action.append(soft)

        # print unsatisfiable steps in decreasing order of hellinger distance
        if len(failed_steps_same_action) > 0:
            print('Unsatisfiable steps different action:')
        #anomaly_positions = []
        for soft in failed_steps_same_action:

            print(
                '({}) run {} step {}: action {} with belief P_0 = {:.3f} P_1 = {:.3f} P_2 = {:.3f}'
                .format(failed_step_counter, self.run_folders[soft.run],
                        soft.step, self.actions_in_runs[soft.run][soft.step],
                        self.belief_in_runs[soft.run][soft.step][0],
                        self.belief_in_runs[soft.run][soft.step][1],
                        self.belief_in_runs[soft.run][soft.step][2]))
            failed_step_counter += 1
Exemplo n.º 13
0
    def find_max_satisfiable_rule(self, rule_num):
        """
        Build a model that satisfies as many soft clauses as possible using MAX-SMT
        """
        print('Find maximum number of satisfiable step in rule {}'.format(
            rule_num))
        rule = self.rules[rule_num]

        # enforce probability axioms
        for c in range(len(rule.constraints)):  # constraint in rule
            self.thresholds[rule_num].append([None, None, None])
            for s in range(3):  # state in constraint
                # TODO 1: questo va tolto e spostato/generalizzato fuori
                t = z3.Real('t_r{}_c{}_state{}'.format(rule_num, c, s))
                self.thresholds[rule_num][c][s] = t
                # each threshold is a probability and must have a value
                # bethween 0 and 1
                self.solver.add(0.0 < t)
                self.solver.add(t <= 1.0)
            # the sum of the probability on the three states must be 1
            prob_sum = z3.Sum(self.thresholds[rule_num][c])
            self.solver.add(prob_sum == 1.0)

        # hard constraint, they must be be specified by hand in this version
        # e.g: x_1 >= 0.9

        # TODO 3: usare le variabili dichiarate per esprimere hard-constraint
        # e.g. rs.add_hard_constraint(x >= 0.7)
        # TODO 4: rimuovere codice specifico del problema di velocity regulation come la stampa, generazione di punti ecc
        if rule_num == 0:
            self.solver.add(self.thresholds[0][0][0] >= 0.70)

        if rule_num == 1:
            self.solver.add(self.thresholds[1][0][2] >= 0.70)

        # build soft clauses
        for run in range(len(self.belief_in_runs)):
            t = self.thresholds[rule_num]
            for bel, belief in enumerate(self.belief_in_runs[run]):
                # generate boolean var for soft constraints
                soft = z3.Bool('b_{}_{}_{}'.format(rule_num, run, bel))
                self.soft_constr[rule_num].append(
                    DummyVar(soft, rule_num, run, bel))

                # add the rule
                subrules = []
                for c in range(len(rule.constraints)):
                    subrule = []
                    for i in rule.constraints[c].greater_equal:
                        subrule.append(
                            belief[i] >= t[c][i]
                        )  #100 > x1 (esempio) ogni belief è preso da uno step, x1 deve essere soddisfatta per tutti gli step
                    for i in rule.constraints[c].lower_equal:
                        subrule.append(belief[i] <= t[c][i])
                    subrules.append(z3.And(subrule))

                formula = z3.Or(
                    subrules)  #ho più modi per soddisfare queste regole.

                #la mia regola deve spiegare se ha fatto l'azione, altrimenti non deve spiegarla.
                if self.actions_in_runs[run][
                        bel] not in rule.speeds:  #vedo se l'azione scelta viene rispettata dal bielef
                    formula = z3.Not(formula)

                self.solver.add(
                    z3.Or(soft, formula)
                )  #può essere risolto dall cheat (soft) oppure dalla formula.

        # solve MAX-SMT problem
        low_threshold = 0
        total_soft_constr = len(self.soft_constr[rule_num])
        high_threshold = len(self.soft_constr[rule_num])
        final_threshold = -1
        best_model = []

        #uso una ricerca binaria per risolvere l'or gigante definito sopra!
        while low_threshold <= high_threshold:
            self.solver.push(
            )  #risolutore incrementale, consente di evitare di rifare calcoli creando un ambiente virtuale

            threshold = (low_threshold + high_threshold) // 2
            #Pble pseudo boolean less equal
            self.solver.add(
                z3.PbLe([(soft.literal, 1)
                         for soft in self.soft_constr[rule_num]], threshold)
            )  #l'add viene fatto sull'ambiente virtuale appena creato.
            result = self.solver.check()
            if result == z3.sat:
                final_threshold = threshold
                best_model = self.solver.model()
                high_threshold = threshold - 1
            else:
                low_threshold = threshold + 1
            self.solver.pop()

        print('fail to satisfy {} steps out of {}'.format(
            final_threshold, total_soft_constr))
        # return a model that satisfy all the hard clauses and the maximum number of soft clauses
        # print(best_model)
        return best_model
Exemplo n.º 14
0
 def _assert(self, modelset, i, g, a):
     return z3.Not(self.pred._assert(modelset, i, g, a))
Exemplo n.º 15
0
 def get_gadget_constraint(self):
     A = self.get_stack_offset() > self.arch.bytes
     B = self.get_ip_in_stack_offset() == self.arch.bytes
     return z3.Not(z3.And(A, B)), None
Exemplo n.º 16
0
def test_smt():
    # fac 0 = 1.
    # fac {N + 1} = P <== {N >= 0}, {(N + 1) * M = P}, fac N = M.
    go = lambda t: lambda log, solver: disj(
        unify(t, arr(lit('fac'), SMT(0), lit('='), SMT(1))),
        (lambda n, m, p: conj(
            unify(t, arr(lit('fac'), SMT(n.a + 1), lit('='), p)),
            add(n.a >= 0),
            add((n.a + 1) * m.a == p.a),
            go(arr(lit('fac'), n, lit('='), m)),
        ))(SMT(z3.Int(nab())), SMT(z3.Int(nab())), SMT(z3.Int(nab()))))(log,
                                                                        solver)
    # fac 100! X
    # ----------
    # {X = 100!}
    x = SMT(z3.Int('x'))
    log = []
    solver = z3.Solver()
    for _ in go(arr(lit('fac'), SMT(100), lit('='), x))(log, solver):
        print(
            solver,
            solver.check(),
            'x =',
            (solver.model()[x.a] if solver.check() == z3.sat else None),
        )
    print(solver)
    print()
    # fac X 720
    # ---------
    #   X = 7
    x = SMT(z3.Int('x'))
    log = []
    solver = z3.Solver()
    for _ in go(arr(lit('fac'), x, lit('='), SMT(720 * 7)))(log, solver):
        print(
            solver,
            solver.check(),
            'x =',
            (solver.model()[x.a] if solver.check() == z3.sat else None),
        )
    print(solver)
    print()
    # enumerating all solutions to constraints
    # pythag A B C N <==
    #   {0 < A}, {A <= B}, {B <= C}, {C <= N}
    #   {A^2 + B^2 = C^2}.
    go = lambda t: lambda log, solver: (lambda a, b, c, n: conj(
        unify(t, arr(lit('pythag'), a, b, c, n)),
        add(0 < a.a, a.a <= b.a, b.a <= c.a, c.a <= n.a, a.a**2 + b.a**2 == c.a
            **2))(log, solver))(SMT(z3.Int(nab())), SMT(z3.Int(nab())),
                                SMT(z3.Int(nab())), SMT(z3.Int(nab())))
    a = SMT(z3.Int('a'))
    b = SMT(z3.Int('b'))
    c = SMT(z3.Int('c'))
    log = []
    solver = z3.Solver()
    for _ in go(arr(lit('pythag'), a, b, c, SMT(30)))(log, solver):
        solver.push()
        while solver.check() == z3.sat:
            m = solver.model()
            ma, mb, mc = m[a.a], m[b.a], m[c.a]
            print(f'a = {ma}, b = {mb}, c = {mc}')
            solver.add(z3.Not(z3.And(a.a == ma, b.a == mb, c.a == mc)))
        solver.pop()
    print()
    # cbrt {N * N * N} = N.
    go = lambda t: (lambda n: conj(
        unify(t, arr(lit('cbrt'), SMT(n.a * n.a * n.a), lit('='), n))))(SMT(
            z3.Int(nab())))
    n = SMT(z3.Int('n'))
    log = []
    solver = z3.Solver()
    for _ in go(arr(lit('cbrt'), SMT(2019 * 2019 * 2019), lit('='),
                    n))(log, solver):
        solver.push()
        while solver.check() == z3.sat:
            m = solver.model()
            mn = m[n.a]
            print(f'n = {mn}')
            solver.add(n.a != mn)
        solver.pop()
    print()
Exemplo n.º 17
0
 def get_gadget_constraint(self):
     A = self.get_output0() == self.get_param0()
     return z3.Not(A), None
Exemplo n.º 18
0
 def z3expr(self) -> z3.BoolRef:
     z3expr = self.expr.z3expr()
     if isinstance(z3expr, z3.BoolRef):
         return z3.Not(z3expr)
     raise TypeError
Exemplo n.º 19
0
 def get_gadget_constraint(self):
     mem_value = utils.z3_get_memory(self.get_mem_before(),
                                     self.get_input0() + self.get_param0(),
                                     self.arch.bits, self.arch)
     A = self.get_output0() == self.binop(mem_value, self.get_input1())
     return z3.Not(A), None
Exemplo n.º 20
0
 def __k_not_bool__(self):
     for val in self.__k_bool__():
         yield inference.InferenceResult(Z3Proxy.init_expr(
             z3.Not(val.strip_inference_result()), self.defaults),
                                         status=True)
Exemplo n.º 21
0
 def __ne__(self, o):
     r = self == o
     if r is NotImplemented:
         return NotImplemented
     return wrap(z3.Not(unwrap(r)))
Exemplo n.º 22
0
 def learn_certain_not_impostor(self, colour):
     """ learn that the player with the specified colour is certainly not an impostor """
     p = self.pid(colour)
     self.knowns.append(z3.Not(self.impostor[p]))
Exemplo n.º 23
0

# ### The CFG with Path Taken

if __name__ == "__main__":
    print('\n### The CFG with Path Taken')




if __name__ == "__main__":
    show_cfg(check_triangle, arcs=cov.arcs())


if __name__ == "__main__":
    z3.solve(a == b, a == c, z3.Not(b == c))


if __name__ == "__main__":
    z3.solve(a == b, z3.Not(a == c))


if __name__ == "__main__":
    with ArcCoverage() as cov:
        assert check_triangle(1, 1, 0) == 'Isosceles'
    [i for fn, i in cov._trace if fn == 'check_triangle']


if __name__ == "__main__":
    paths['<path 3>']
Exemplo n.º 24
0
 def _ddosSendRules(self):
     p_0 = z3.Const('%s_dpi_send_p_0'%(self.node), self.ctx.packet)
     n_0 = z3.Const('%s_dpi_send_n_0'%(self.node), self.ctx.node)
     t_0 = z3.Int('%s_dpi_send_t_0'%(self.node))
     self.constraints.append(z3.ForAll([n_0, p_0, t_0], z3.Not(self.ctx.send(self.node, n_0, p_0, t_0))))
Exemplo n.º 25
0
    def solve(self):

        # The way it works is, each box is represented by four symbolic integers,
        # representing the X/Y coordinates of its top-left and bottom-right vertices.

        # (Note, however, that because computers are silly, the Y coordinates DECREASE
        # as you go UP the tower. Just something to keep in mind. Otherwise we get
        # upside-down stalactite-towers.)

        svs = {}
        solver = z3.Solver()
        for node in self.get_nodes():
            svs[node] = ((z3.Int(node + '_x0'), z3.Int(node + '_y0')),
                         (z3.Int(node + '_x1'), z3.Int(node + '_y1')))

            # Almost immediately, we need to make some sanity assertions. We want the
            # top-left corner to actually be "to the left" and "on top of" the bottom-right
            # corner, so we have to tell the solver that.

            solver.add(svs[node][0][0] < svs[node][1][0])
            solver.add(svs[node][0][1] < svs[node][1][1])

            # There's also a bit of logic here to automatically make boxes taller if they
            # have a lot of text, so that text doesn't overflow awkwardly. This is janky,
            # but it works!

            solver.add(
                svs[node][1][1] - svs[node][0][1] >=\
                (len(self.text[node].split('\\')) - len(self.text[node].split('\\')) / 2)
            )

            # And finally, we enforce that everything happens in the first quadrant.

            solver.add(svs[node][0][0] >= 0)

# Now we can put root (recall, the "ground") literally on the ground!

        solver.add(svs[dag.ROOT][0][0] == 0)
        solver.add(svs[dag.ROOT][0][1] == 0)

        # Up next, we enforce that no boxes intersect. This is done by checking if the
        # X and Y ranges are disjoint (at least one needs to be -- but not necessarily
        # both!).

        def ranges_disjoint(x0min, x0max, x1min, x1max):
            return z3.Or(x0min >= x1max, x0max <= x1min)

        for node1 in self.get_nodes():
            for node2 in self.get_nodes():
                if node1 != node2:
                    solver.add(
                        z3.Or(
                            ranges_disjoint(svs[node1][0][0], svs[node1][1][0],
                                            svs[node2][0][0],
                                            svs[node2][1][0]),
                            ranges_disjoint(svs[node1][0][1], svs[node1][1][1],
                                            svs[node2][0][1],
                                            svs[node2][1][1])))

# This is the hard one: for each pair of nodes, it creates an "A is on top of
# B" assertion, and then asserts either it or its negation, depending on
# whether or not B is a direct dependency of A.

        for node in self.get_nodes():
            for dep in self.get_nodes():
                on_top = z3.And(

                    # When is "A" on top of "B"? There are two conditions:

                    # First, A's box's floor is directly on B's box's ceiling.
                    svs[node][1][1] == svs[dep][0][1],

                    # Second, the boxes have intersecting X ranges.
                    z3.Not(
                        ranges_disjoint(svs[node][0][0], svs[node][1][0],
                                        svs[dep][0][0], svs[dep][1][0])))
                if self.is_direct_dependency(node, dep):
                    solver.add(on_top)
                else:
                    solver.add(z3.Not(on_top))

# Finally, for the sake of ~aesthetics~, there's a bit of logic to
# automatically minimize the total perimeter of all the blocks. (Why not area,
# you ask? Because area is nonlinear and the solver takes *much* longer to work
# with such constrants!)

        def perimeter(node):
            return (svs[node][1][0] - svs[node][0][0]) + (svs[node][1][1] -
                                                          svs[node][0][1])

        total_perim = sum([perimeter(node) for node in self.get_nodes()])

        # (That's what the loop is for: it keeps asking the solver to "do better" until
        # the solver can't do any better and gives up. It may or may not be a metaphor
        # for life.)

        rects = None
        perim_tgt = len(self.get_nodes()) * 4 * 3
        while True:
            perim_tgt -= 1
            solver.add(total_perim < perim_tgt)
            check = solver.check()
            if check == z3.sat:
                model = solver.model()

                rects = []

                # I translate the solver output into SVG coordinates using some hardcoded
                # scaling factors and randomized fudge factors.

                for node in self.get_nodes():
                    x0 = model.eval(svs[node][0][0])
                    y0 = model.eval(svs[node][0][1])
                    x1 = model.eval(svs[node][1][0])
                    y1 = model.eval(svs[node][1][1])

                    import random
                    x0 = int(str(x0)) * 160 + 10 + random.choice(range(10))
                    y0 = int(str(y0)) * 50
                    x1 = int(str(x1)) * 160 - 10 + random.choice(range(10))
                    y1 = int(str(y1)) * 50

                    rects.append((node, x0, y0, x1, y1))

# This is the "solver gives up" case

            else:
                return rects
Exemplo n.º 26
0
 def get_gadget_constraint(self):
     A = self.get_output0() == self.get_input0()
     B = self.get_output0() == self.arch.ip
     return z3.Not(z3.And(A, B)), None
Exemplo n.º 27
0
            else:
                s.add(z3.Implies(line[l], connected(a, b)))
                s.add(z3.Implies(z3.Not(line[l]), z3.Not(connected(a, b))))

    # Transitive closure of "is connected to"
    path_connected = z3.TransitiveClosure(connected)

    # For every point, if it's activated then it's transitively connected to a point adjacent to a 3-cell
    xy3 = [xy for (xy, c) in grid.cells() if c == "3"][0]
    dot3 = grid.cell_dots(*xy3)[0]
    atom3 = dot_atom[dot3]

    for d in grid.dots():
        s.add(z3.Implies(dot[d], path_connected(dot_atom[d], atom3)))
        s.add(
            z3.Implies(z3.Not(dot[d]),
                       z3.Not(path_connected(dot_atom[d], atom3))))

    # Constrain the number of activated lines surrounding each known cell
    def line_count_of_cell(xy):
        """xy is the dot at the top-left
        Return an invocation of line_count for the lines around it.
        """
        return z3.Sum(*(bool_to_int(line[l]) for l in grid.cell_lines(*xy)))

    for xy, c in grid.cells():
        if c != " ":
            print("adding constraint for ", xy, c,
                  [str(l) for l in grid.cell_lines(*xy)])
            s.add(line_count_of_cell(xy) == int(c))
Exemplo n.º 28
0
 def get_gadget_constraint(self):
     regconstrait = z3.Not(
         self.get_output0() != self.arch.registers['sp'][0])
     offsetconstraint = z3.Not(self.get_param0() < self.arch.bytes * 8)
     return z3.Or(regconstrait, offsetconstraint), None
Exemplo n.º 29
0
def is_true(cond):
    # NOTE: This differs from `not is_false(cond)`, which corresponds to "may be true"
    return is_false(z3.Not(cond))
Exemplo n.º 30
0
def query_z3(triples_changed):
    shared = shared_features(
        [triple for triple, changed in triples_changed if changed])
    idents_to_features = {
        to_ident(feature, position): (feature, position)
        for feature, position in shared.keys()
    }

    opt = z3.Optimize()
    solver = z3.Solver()
    solver.set(unsat_core=True)
    formulas = {}

    soft_assertions = []
    position_weights = {'left': 1000, 'center': 0, 'right': 1000}
    for control_included, (feature, position) in idents_to_features.items():
        # We use 10000 so that including new features is much worse than using more specific features.
        weight = 10000 + position_weights[position] + ipa_data.get_weight(
            feature, shared[(feature, position)])
        opt.add_soft(z3.Not(z3.Bool(control_included)), weight=weight)

    for triple, changed in triples_changed:
        conjunction = []
        for i, phone in enumerate(triple):
            for feature in ipa_data.FEATURES:
                position = POSITIONS[i]
                if (feature, position) in shared:
                    control_included = z3.Bool(to_ident(feature, position))
                    control_positive = shared[(feature, position)] == '+'
                    input_included = phone[
                        feature] != '0' if feature in phone else False
                    input_positive = phone[
                        feature] == '+' if feature in phone else False
                    conjunction.append(
                        z3.Implies(
                            control_included,
                            z3.And(input_included,
                                   control_positive == input_positive)))
        formula = z3.And(*conjunction) == changed
        opt.assert_exprs(formula)
        name = z3.Bool(get_ident())
        formulas[name] = (formula, triple, changed)
        solver.assert_and_track(formula, name)

    if opt.check() == z3.sat:
        rule = ({}, {}, {})
        model = opt.model()
        for ident in model:
            if model[ident]:
                feature, position = idents_to_features[str(ident)]
                rule[POSITIONS.index(position)][feature] = shared[(feature,
                                                                   position)]
        return rule
    else:
        solver.check()
        unsat_core = solver.unsat_core()
        print('Unsat core:')
        for name in unsat_core:
            formula, (l, c, r), changed = formulas[name]
            print('Formula:')
            print(formula)
            print('Left:')
            print(ipa_data.FEATURES_TO_SYMBOLS.get(frozenset(l.items()), l))
            print('Center:')
            print(ipa_data.FEATURES_TO_SYMBOLS.get(frozenset(c.items()), c))
            print('Right:')
            print(ipa_data.FEATURES_TO_SYMBOLS.get(frozenset(r.items()), r))
            print('Changed:')
            print(changed)
            print(formulas[name])
        print('Shared:')
        print(shared)
        return None