def _convert(self, obj): if isinstance(obj, FSort): return z3.FPSort(obj.exp, obj.mantissa, ctx=self._context) elif isinstance(obj, RM): if obj == RM_RNE: return z3.RNE(ctx=self._context) elif obj == RM_RNA: return z3.RNA(ctx=self._context) elif obj == RM_RTP: return z3.RTP(ctx=self._context) elif obj == RM_RTN: return z3.RTN(ctx=self._context) elif obj == RM_RTZ: return z3.RTZ(ctx=self._context) else: raise BackendError("unrecognized rounding mode") elif obj is True: return z3.BoolVal(True, ctx=self._context) elif obj is False: return z3.BoolVal(False, ctx=self._context) elif isinstance(obj, (numbers.Number, str)): return obj elif hasattr(obj, '__module__') and obj.__module__ in ('z3', 'z3.z3'): return obj else: l.debug("BackendZ3 encountered unexpected type %s", type(obj)) raise BackendError("unexpected type %s encountered in BackendZ3" % type(obj))
def toZ3(f: Union[Formula, Term], env: Environment) -> z3.ExprRef: def R(f: Union[Formula, Term]) -> z3.ExprRef: return toZ3(f, env) if isinstance(f, And): if len(f.c) == 0: return z3.BoolVal(True) return z3.And(*[R(x) for x in f.c]) elif isinstance(f, Or): if len(f.c) == 0: return z3.BoolVal(False) return z3.Or(*[R(x) for x in f.c]) elif isinstance(f, Not): return z3.Not(R(f.f)) elif isinstance(f, Relation): return z3_rel_func[f.rel](*[R(x) for x in f.args]) elif isinstance(f, Func): return z3_rel_func[f.f](*[R(x) for x in f.args]) elif isinstance(f, Equal): return R(f.args[0]) == R(f.args[1]) elif isinstance(f, Var): v = env.lookup_var(f.var) if v is None: raise RuntimeError("Cannot convert invalid formula to z3") return z3.Const(f.var, sorts_to_z3[v]) elif isinstance(f, Forall) or isinstance(f, Exists): env.bind(f.var, f.sort) sub_f = toZ3(f.f, env) env.pop() bv = z3.Const(f.var, sorts_to_z3[f.sort]) return z3.ForAll(bv, sub_f) if isinstance(f, Forall) else z3.Exists( bv, sub_f) else: print("Can't translate", f) assert False
def _comparison_helper( a: "BitVecFunc", b: Union[BitVec, int], operation: Callable, default_value: bool, inputs_equal: bool, ) -> Bool: """ Helper function for comparison operations with BitVecFuncs. :param a: The BitVecFunc to compare. :param b: A BitVec or int to compare to. :param operation: The comparison operation to perform. :return: The resulting Bool """ # Is there some hack for gt/lt comparisons? if isinstance(b, int): b = BitVec(z3.BitVecVal(b, a.size())) union = a.annotations.union(b.annotations) if not a.symbolic and not b.symbolic: return Bool(z3.BoolVal(operation(a.value, b.value)), annotations=union) if (not isinstance(b, BitVecFunc) or not a.func_name or not a.input_ or not a.func_name == b.func_name): return Bool(z3.BoolVal(default_value), annotations=union) return And( Bool(cast(z3.BoolRef, operation(a.raw, b.raw)), annotations=union), a.input_ == b.input_ if inputs_equal else a.input_ != b.input_, ) return a.input_ == b.input_
def merge_queries_new_pred(clauses, queries, decls): if len(queries) > 1: false1 = z3.Bool("CHC_COMP_FALSE") decls.add(false1.decl()) for query in queries: assert (z3.is_quantifier(query) and query.is_forall()) qvars = [ z3.Const(query.var_name(n), query.var_sort(n)) for n in range(0, query.num_vars()) ] body = query.body() assert (body.decl().kind() == z3.Z3_OP_IMPLIES) kids = body.children() assert (kids[1] == z3.BoolVal(False)) newBody = z3.Implies(kids[0], false1) newClause = z3.ForAll(qvars, newBody) clauses.append(newClause) queries.clear() queries.append( z3.ForAll(z3.Bool("CHC_COMP_UNUSED"), z3.Implies(z3.And(false1), z3.BoolVal(False))))
def test_one(self): prg1 = """{a := 1; b := -1; c := a + b; d := b - a; e := a * b; f := a / b}; if a > 1 and a >= b then b := 3; if a <= 1 or b < 3 then a := 1; if false and not a = 1 then a := 1 else print_state; skip; print_state; while (a < 3) or (b = 1) and true do {a := a + 1}; assume b = -1; havoc c,d; assert a = 3; assert a = 2""" ast1 = ast.parse_string(prg1) sym = wlang.sym.SymExec() st = wlang.sym.SymState() st.pick_concerete() st.is_error() st.mk_error() st.to_smt2() repr(st) out = [s for s in sym.run(ast1, st)] # self.assertEquals (len(out), 1) st2 = wlang.sym.SymState() st2.add_pc(z3.BoolVal(True)) st2.add_pc(z3.BoolVal(False)) st2.pick_concerete()
def assume_properties(stat_var_map, assumptions: Dict[str, str], solver): global assumptions_to_properties, alpha assumed_props = [] # Go through all assumptions for a in assumptions: if a in alpha_keywords: alpha = float(assumptions[a]) elif a in assumptions_to_properties: # Apply corresponding properties to all variables for which the property is assumed for prop in all_props(): if prop.name in assumptions_to_properties[a]: # Convert assumptions to use correct statistical variable names. stat_vars = [] for var in assumptions[a]: # This is really hacky -- should probably change the # incoming assumptions data structure before calling this method if isinstance(var, str): assert var in stat_var_map # stat_vars.append(stat_var_map[var]) ap = prop(stat_var_map[var]) assumed_props.append(ap) solver.add(ap.__z3__ == z3.BoolVal(True)) else: assert isinstance(var, list) stat_vars = [stat_var_map[v] for v in var] ap = prop(*stat_vars) assumed_props.append(ap) solver.add(ap.__z3__ == z3.BoolVal(True)) else: pass return assumed_props
def sys_reap(old, pid): cond = z3.And( is_pid_valid(pid), # Only the owner can reap a child old.procs[pid].ppid == old.current, # The pid to reap is a zombie old.procs[pid].state == dt.proc_state.PROC_ZOMBIE, # The proc has no children/open fds/pages/devices/ports old.procs[pid].nr_devs() == z3.BitVecVal(0, dt.size_t), old.procs[pid].nr_children() == z3.BitVecVal(0, dt.size_t), old.procs[pid].nr_fds() == z3.BitVecVal(0, dt.size_t), old.procs[pid].nr_pages() == z3.BitVecVal(0, dt.size_t), old.procs[pid].nr_dmapages() == z3.BitVecVal(0, dt.size_t), old.procs[pid].nr_ports() == z3.BitVecVal(0, dt.size_t), old.procs[pid].nr_vectors() == z3.BitVecVal(0, dt.size_t), old.procs[pid].nr_intremaps() == z3.BitVecVal(0, dt.size_t), ) new = old.copy() new.procs[old.current].nr_children[pid] -= 1 new.procs[pid].state = dt.proc_state.PROC_UNUSED new.procs[pid].ppid = z3.BitVecVal(0, dt.pid_t) new.procs[pid].page_table_root = z3.BitVecVal(0, dt.pn_t) new.procs[pid].stack = z3.BitVecVal(0, dt.pn_t) new.procs[pid].killed = z3.BoolVal(False) new.procs[pid].hvm = z3.BitVecVal(0, dt.pn_t) new.procs[pid].use_io_bitmap = z3.BoolVal(False) new.procs[pid].io_bitmap_a = z3.BitVecVal(0, dt.pn_t) new.procs[pid].io_bitmap_b = z3.BitVecVal(0, dt.pn_t) return cond, util.If(cond, new, old)
def visit_MLIL_SET_VAR_SSA(self, expr): dest = CreateBitVec(expr.dest) src = self.visit(expr.src) if isinstance(src, z3.BoolRef): assert (expr.size == 1) # Replace z3 boolean with bit vector. src = z3.If(src, z3.BitVecVal(1, 32), z3.BitVecVal(0, 32)) else: assert (isinstance(src, z3.BitVecRef)) if expr.branch_dependence: assert (len(expr.branch_dependence) == 1) branch_idx, branch_type = next(iter( expr.branch_dependence.items())) branch = self.func[branch_idx] if branch not in self.visited: self.to_visit.append(branch) canon_var = CanonicalVarForBranch(branch_idx) if branch_type == binja.ILBranchDependence.TrueBranchDependent: self.solver.add( z3.If(canon_var, (dest == src), z3.BoolVal(True))) else: self.solver.add( z3.If(z3.Not(canon_var), (dest == src), z3.BoolVal(True))) else: # No control flow dependencies. self.solver.add(dest == src) self.visited.add(expr.dest)
def __init__(self): # self.solver = z3.Solver() self.TRUE = z3.BoolVal(True) self.FALSE = z3.BoolVal(False) return
def simplify(self): super(Bool, self).simplify() if proved(Bool(self)): self.symbol = z3.BoolVal(True) elif proved(Bool(self.symbol == False)): self.symbol = z3.BoolVal(False) self._simplified = True return self
def __init__(self): Backend.__init__(self) self._make_raw_ops(set(backend_operations) - {'BitVec', 'If'}, op_module=bv) self._make_raw_ops(backend_fp_operations, op_module=fp) self._op_raw_result['BitVec'] = self._BitVec self._op_raw_result['If'] = self._If self._z_true = z3.BoolVal(True) self._z_false = z3.BoolVal(False)
def gebin(bits, n): if n == 0: return z3.BoolVal(True) if n >= 2**len(bits): return z3.BoolVal(False) hval = 2**(len(bits) - 1) if hval <= n: return z3.And(bits[0], gebin(bits[1:], n - hval)) return z3.Or(bits[0], gebin(bits[1:], n))
def __differ__(self, orig_value, muta_value): self.timeout = self.timeout try: return orig_value != muta_value except z3.z3types.Z3Exception: return z3.BoolVal(True) except AttributeError: return z3.BoolVal(True) except TypeError: return z3.BoolVal(True)
def test_candidate(self, synth_func, candidate): # candidate = expr_string_to_z3(candidate_word, self.spec, synth_func['inputs']) goal = substitute_function_for_expression(self.spec.goal, synth_func["decl"], synth_func["z3_inputs"], candidate) while True: macro_decl = contains_funcs(goal, self._macros_decls) if macro_decl is None: break macro_name = macro_decl.name() macro = self.spec.macros[macro_name] macro_def = expr_string_to_z3(macro["definition"], self.spec, macro["inputs"]) macro_params = macro["z3_inputs"] goal = substitute_function_for_expression(goal, macro_decl, macro_params, macro_def) if self.universally_quantified: counter_example_constraints = [z3.BoolVal(True)] for counter_example in self.counter_examples: counter_example_constraints.append( z3.simplify( z3.substitute( goal, list(zip(self.spec.z3_variables, counter_example))))) counter_example_constraint = z3.simplify( z3.And(*counter_example_constraints)) if counter_example_constraint.eq(z3.BoolVal(False)): return "sat" if not counter_example_constraint.eq(z3.BoolVal(True)): goal = z3.And(goal, counter_example_constraint) else: if goal.eq(z3.BoolVal(True)): return "unsat" if goal.eq(z3.BoolVal(False)): return "sat" goal = z3.simplify(z3.Not(goal)) s = z3.Solver() s.add(goal) validity = str(s.check()) if validity == "sat": counter_example = [] model = s.model() for var in self.spec.z3_variables: counter_example.append(model.eval(var)) self.counter_examples.append(counter_example) return validity
def activate(self, label="undefined"): for member_name in self.members: member_val = self.resolve_reference(member_name) if isinstance(member_val, P4ComplexInstance): member_val.activate() else: # only if the header was invalid, reallocate all variables if self.valid == z3.BoolVal(False): allocated_var = z3.Const(label, member_val.sort()) self.set_or_add_var(member_name, allocated_var) self.valid = z3.BoolVal(True)
def _(term, smt): arg = term._args[0] if isinstance(arg, Constant): return z3.BoolVal(True) if isinstance(arg, Instruction): return z3.BoolVal(False) assert isinstance(arg, Input) # if this is in input, we can return true or false, but we # need to do so consistently return smt._get_attr_var('is_const', arg)
def convert(t): """Convert term t to Z3 input.""" if t.is_var(): T = t.get_type() if T == nat.natT: return z3.Int(t.name) elif T == TFun(nat.natT, nat.natT): return z3.Function(t.name, z3.IntSort(), z3.IntSort()) elif T == TFun(nat.natT, boolT): return z3.Function(t.name, z3.IntSort(), z3.BoolSort()) elif T == boolT: return z3.Bool(t.name) else: print("convert: unsupported type " + repr(T)) raise NotImplementedError elif t.is_all(): if t.arg.var_T == nat.natT: v = Var(t.arg.var_name, nat.natT) z3_v = z3.Int(t.arg.var_name) return z3.ForAll([z3_v], convert(t.arg.subst_bound(v))) else: raise NotImplementedError elif t.is_implies(): return z3.Implies(convert(t.arg1), convert(t.arg)) elif t.is_equals(): return convert(t.arg1) == convert(t.arg) elif logic.is_conj(t): return z3.And(convert(t.arg1), convert(t.arg)) elif logic.is_disj(t): return z3.Or(convert(t.arg1), convert(t.arg)) elif logic.is_neg(t): return z3.Not(convert(t.arg)) elif nat.is_plus(t): return convert(t.arg1) + convert(t.arg) elif nat.is_times(t): return convert(t.arg1) * convert(t.arg) elif nat.is_binary(t): return nat.from_binary(t) elif t.is_comb(): return convert(t.fun)(convert(t.arg)) elif t.is_const(): if t == logic.true: return z3.BoolVal(True) elif t == logic.false: return z3.BoolVal(False) else: print("convert: unsupported constant " + repr(t)) raise NotImplementedError else: print("convert: unsupported operation " + repr(t)) raise NotImplementedError
def _(term, smt): arg = term._args[0] if isinstance(arg, Constant): return z3.BoolVal(True) if isinstance(arg, Instruction): return z3.BoolVal(False) assert isinstance(arg, Input) try: return smt.get_analysis('isconstant', term) except KeyError: return smt.new_analysis('isconstant', term)
def get_varying_knowns(self): """ Builds a list of constraints based on the game state that can change during the game """ return [ # People that were murdered were murdered *[ self.murdered[pid] == z3.BoolVal(pid in self.murdered_pids) for pid in range(self.n_players) ] # People that were ejected were ejected , *[ self.ejected[pid] == z3.BoolVal(pid in self.ejected_pids) for pid in range(self.n_players) ] ]
def glean_unknown_symbol(sym): sym = str(sym) # sys.stderr.write("trying to glean unknown symbol: \"%s\"\n" % (sym)) if int_pattern.match(sym): num = int(sym) if num == 0: return z3.BoolVal(False) else: return z3.BoolVal(True) elif hex_pattern.match(sym): return z3.Bool("\"%s\"" % (sym)) # elif identifier_pattern.match(sym): # return z3.Bool("CONFIG_%s" % (sym)) else: return z3.StringVal(sym)
def visitNot(self, node): # sys.stderr.write("not %s\n" % (str(node))) operand = self.visit(node.expr) if z3.is_bool(operand): return z3.Not(operand) else: return z3.BoolVal(True)
def recover_value(value, uct_sort): """ Inverse of _extract_value. Given a pythonic value, returns a z3 embedding of it depending on its uct sort. The explicit embedding scheme is as follows: fgsort -> z3.ArithRef fgsetsort -> z3.ArrayRef intsort -> z3.ArithRef intsetsort -> z3.ArrayRef boolsort -> z3.BoolRef :param value: any :param uct_sort: naturalproofs.uct.UCTSort :return: z3.ExprRef """ # TODO: typecheck all the arguments if uct_sort in {fgsort, intsort}: return z3.IntVal(value) elif uct_sort == boolsort: return z3.BoolVal(value) elif uct_sort in {fgsetsort, intsetsort}: expr = z3.EmptySet(z3.IntSort()) for elem in value: expr = z3.SetAdd(expr, z3.IntVal(elem)) else: raise ValueError( 'Sort not supported. Check for a list of available sorts in the naturalproofs.uct module.' )
def __init__(self, name, p4z3_type, parent_const=None): self.p4_attrs = {} self.name = name self.z3_type = p4z3_type.z3_type self.p4z3_type = p4z3_type self.const = z3.Const(f"{name}", self.z3_type) if parent_const is not None: bind_const = parent_const else: bind_const = self.const self.members = OrderedDict() # set the members of this class for type_index, z3_arg in enumerate(p4z3_type.z3_args): z3_arg_name = z3_arg[0] z3_arg_type = z3_arg[1] var_name = f"{name}.{z3_arg_name}" member_constructor = self.z3_type.accessor(0, type_index) z3_member = member_constructor(bind_const) if isinstance(z3_arg_type, P4ComplexType): # this is a complex datatype, create a P4ComplexType member_cls = z3_arg_type.instantiate(var_name, z3_member) self.p4_attrs[z3_arg_name] = member_cls else: # use the default z3 constructor self.p4_attrs[z3_arg_name] = z3_member self.members[z3_arg_name] = member_constructor self.valid = z3.BoolVal(True)
def _initialise_goal(self, text_spec): constraints = [] funcs = {**self.synth_funcs, **self.uninterpreted_funcs, **self.macros} for original_constraint in text_spec.constraints: constraint_lexer = TermLexer( antlr4.InputStream(original_constraint)) constraint_stream = antlr4.CommonTokenStream(constraint_lexer) constraint_parser = TermParser(constraint_stream) constraint_tree = constraint_parser.term() constraint_extractor = Constraint_Extractor( self.logic, self.variables, funcs) constraint = constraint_extractor.visit(constraint_tree) constraints.append(constraint) goal = z3.BoolVal(True) for constraint in constraints: goal = z3.And(goal, constraint) goal = z3.simplify(goal) return z3.simplify(goal)
def __init__(self, name, p4z3_type, parent_const=None): super(HeaderInstance, self).__init__(name, p4z3_type, parent_const) self.valid = z3.BoolVal(True) self.p4_attrs["isValid"] = self.isValid self.p4_attrs["setValid"] = self.setValid self.p4_attrs["setInvalid"] = self.setInvalid self.union_parent = None
def test_pick_concrete2(self): # prg1 = "if 1 > 2 then x := 1" # ast1 = ast.parse_string (prg1) sym = wlang.sym.SymExec() st = wlang.sym.SymState(z3.Solver()) st.add_pc(z3.BoolVal(False)) self.assertIsNone(st.pick_concrete())
def test(self, data): # data = 'a != (int[])null&&a[2] + a[3] < 4&&-51 < a[0]&&a[0] < 51&&-51 < a[1]&&a[1] < 51&&-51 < a[2]&&a[2] < 51&&a.Length == 3&&a[1] >= a[0]&&a[0] >= a[1]&&a[2] >= a[0]&&a[0] >= a[2]&&a[0] + a[2] * a[1]&&int s = a[0] - a[2]&&s > a[2] - a[1]&&(a[2]!=1 || a[2]!=4)&&4u < (uint)(1 + a[4])&&a[5] == \'c\'&&Math.floor(a[0])&&a[2] < a[1] ? a[0] % a[1] : a[1] % a[0]&&double s0 = 0.98&&s1 = 0.6&&s1 + -(double)((int)s0) != 0.49'.split('&&') # data = 'a != (int[])null&&-51 < a[0]&&a[0] < 51&&1 < a.Length&&-51 < a[1]&&a[1] < 51&&a[1] < a[0]&&a.Length == 2&&a[0] >= a[1]'.split('&&') # data = data.replace('\\r\\n', '') # data = data.split('&&') models = [] errors = [] toAdd = False # Don't add the preamble for d in data: if not d: continue # print(d) try: # print(d) ret = self.parse(d) # print(ret) if type(ret) == z3.z3.ArithRef: ret = z3.If(ret == 0, True, False) except (ValueError, KeyError) as e: ret = None except z3.z3types.Z3Exception as e: ret = None print('Z3 error', e) # Changed 'ret == False' -> 'ret is False' to avoid triggering int 0 if ret is False or ret == None: errors.append(d) else: models.append(ret) # self.parser.clear_context() # Checks if all eles in `models` eval to True retVal = '&&'.join(sorted(errors)), z3.simplify( reduce(z3.And, models, True)) if len(models) > 0 else z3.BoolVal(True) return retVal
def rec_get_z3_gen(node): if isinstance(node, FormulaMonadic): if node.type == 'PROP': if int(node.child[1:]) >= n_bits: raise 'ERROR: Index of variable must not be more than n_bits' if node.child[0] == 'u': return lambda z3_l, z3_r: z3_l[int(node.child[1:])] elif node.child[0] == 'v': return lambda z3_l, z3_r: z3_r[int(node.child[1:])] else: raise 'ERROR: Variable must be `ui` or `vi`' elif node.type == 'LITERAL': return lambda z3_l, z3_r: z3.BoolVal(True if node.child == 'tru' else False) elif node.type == 'NOT': return lambda z3_l, z3_r: z3.Not( rec_get_z3_gen(node.child)(z3_l, z3_r)) else: raise 'ERROR: Transition uses disallowed unary token' elif isinstance(node, FormulaDyadic): if node.type == 'OR': return lambda z3_l, z3_r: z3.Or( rec_get_z3_gen(node.left)(z3_l, z3_r), rec_get_z3_gen(node.right)(z3_l, z3_r)) elif node.type == 'AND': return lambda z3_l, z3_r: z3.And( rec_get_z3_gen(node.left)(z3_l, z3_r), rec_get_z3_gen(node.right)(z3_l, z3_r)) else: raise 'ERROR: Transition uses disallowed binary connective' else: raise 'ERROR: Ast node is not monadic or dyadic'
def rec_get_z3_gen(node): if isinstance(node, FormulaMonadic): if node.type == 'PROP': if node.child[0] != 'v' or int(node.child[1:]) >= n_bits: raise 'ERROR: Variable in predicate must be of form vi, i < n_bits' return lambda z3_vars: z3_vars[int(node.child[1:])] elif node.type == 'LITERAL': return lambda z3_vars: z3.BoolVal(True if node.child == 'tru' else False) elif node.type == 'NOT': return lambda z3_vars: z3.Not( rec_get_z3_gen(node.child)(z3_vars)) else: raise 'ERROR: Predicate uses disallowed unary token' elif isinstance(node, FormulaDyadic): if node.type == 'OR': return lambda z3_vars: z3.Or( rec_get_z3_gen(node.left)(z3_vars), rec_get_z3_gen(node.right)(z3_vars)) elif node.type == 'AND': return lambda z3_vars: z3.And( rec_get_z3_gen(node.left)(z3_vars), rec_get_z3_gen(node.right)(z3_vars)) else: raise 'ERROR: Predicate uses disallowed binary connective' else: raise "ERROR: Ast node is not monadic or dyadic"
def _get_trans (self, expr): if expr is not None and z3.is_and (expr): if expr.num_args () > 1: return z3.And (*expr.children () [1:]) else: return z3.BoolVal (True) return None