def query(self, *query, **kwargs): if 'max_solutions' in kwargs: max_solutions = kwargs['max_solutions'] else: max_solutions = -1 body_atms = [x.as_muz() for x in query] self._solver.query(*body_atms) ans = self._solver.get_answer() query_vars = [x.get_variables() for x in query] query_vars = reduce(lambda x, y: x + [v for v in y if v not in x], query_vars, []) if is_false(ans): # no solution return [] elif not (is_and(ans) or is_or(ans)): # single solution, value of a single variable val = int(ans.children()[1].as_long()) #varb = query.get_variables()[0] varb = query_vars[0] return [{varb: c_id_to_const(val, varb.get_type())}] elif is_or(ans) and not (is_and(ans.children()[0]) or is_or(ans.children()[0])): # multiple solutions of single variable vals = [int(x.children()[1].as_long()) for x in ans.children()] #varbs = query.get_variables()[0] varbs = query_vars[0] varbs = [varbs] * len(vals) return [{ k: c_id_to_const(v, varbs[0].get_type()) } for k, v in zip(varbs, vals)] elif is_and(ans): # single solution of more than 1 variable ans = [int(x.children()[1].as_long()) for x in ans.children()] ans = [ans] elif is_or(ans): # multiple solutions of more than 1 variable ans = ans.children() ans = [[int(y.children()[1].as_long()) for y in x.children()] for x in ans] else: raise Exception(f"don't know how to parse {ans}") tmp_args = [v for x in query for v in x.get_variables()] args = reduce(lambda x, y: x + [y] if y not in x else x, tmp_args, []) answer = [ dict([(v, c_id_to_const(c, v.get_type().name)) for v, c in zip(args, x)]) for x in ans ] if max_solutions > 0: return answer[:max_solutions] else: return answer
def _update(self): if not self.has_formula(): return rels = list() find_all_uninterp_consts(self._formula, rels) self._rels = frozenset(rels) body = self._formula if z3.is_quantifier(body): body, self._bound_constants = ground_quantifier(body) if z3.is_implies(body): self._head = body.arg(1) body = body.arg(0) if z3.is_and(body): body = body.children() else: body = [body] else: self._head = body body = [] if len(body) > 0: self._body = body for i in range(len(body)): f = body[i] if z3.is_app(f) and f.decl() in self._rels: self._uninterp_sz += 1 else: break assert (self._head is not None)
def transformNonBooleanLazyEvaluations(var): if z3.is_or(var): # in this case it needs to be the first child since we are using it as a first child when coercing any expression to bool left = var.children()[0].children()[0] if len(var.children()[1].children()) == 0: if str(var.children()[1]) == 'False': return left else: raise Exception('Why would the lazy side of the or be a truthy value?') else: right = var.children()[1].children()[0] sub = z3.String('__ignore({}||{})'.format(str(left), str(right))) GLOBAL_CONSTRAINTS.append(z3.Or(left == sub, right == sub)) return sub if z3.is_and(var): # FIXME what about the first child # in this case it needs to be the first child since we are using it as a first child when coercing any expression to bool right = var.children()[1].children()[0] # this is by construction the not null of the first GLOBAL_CONSTRAINTS.append(var.children()[0]) return right return var
def main(argv): args = parseArgs(argv[1:]) # get the names of inductive assumps first iass = set() cf = open(args.cert_mis_file) for line in cf: r = re.match("\s*\(\s*assert\s+(pre![^\)|^\s]+)", line) if r is not None: iass.add(r.group(1)) # now the invariants ctx = z3.Context() fmla = z3.parse_smt2_file(args.ass_inv_file, ctx=ctx) lemmas = [] assert z3.is_and(fmla), \ "invariant file should be a set of assertions" for l in fmla.children(): assert z3u.isZ3Implies(l), \ "assertions in the invariant file should be implications" name = str(l.arg(0).decl()) assert name.startswith("pre!"), \ "implicants in the invariant should start with pre!" if name in iass: lemmas.append(l.arg(1)) # dump the collected lemmas out = sys.stdout if args.out == '-' else open(args.out, 'w') z3u.to_smtlib(lemmas, out)
def elim_bool_ite(exp): if z3.is_quantifier(exp): (qvars, matrix) = strip_qblock(exp) matrix = elim_bool_ite(matrix) if exp.is_forall(): e = z3.ForAll(qvars, matrix) else: e = z3.Exists(qvars, matrix) return e if not z3.is_bool(exp): return exp if z3.is_true(exp) or z3.is_false(exp): return exp assert z3.is_app(exp) decl = exp.decl() args = map(elim_bool_ite, exp.children()) # need to worry about And and Or because they can take >2 args and # decl(*args) doesn't seem to work with the py interface if z3.is_and(exp): return z3.And(*args) elif z3.is_or(exp): return z3.Or(*args) elif is_ite(exp): impl1 = z3.Implies(args[0], args[1]) impl2 = z3.Implies(z3.Not(args[0]), args[2]) return z3.And(impl1, impl2) else: return decl(*args)
def conjuncts(exp): assert z3.is_bool(exp) if z3.is_and(exp): for i in range(exp.num_args()): yield exp.arg(i) else: yield exp
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
def main (argv): args = parseArgs (argv[1:]) # get the names of inductive assumps first iass = set() cf = open(args.cert_mis_file) for line in cf: r = re.match("\s*\(\s*assert\s+(pre![^\)|^\s]+)", line) if r is not None: iass.add(r.group(1)) # now the invariants ctx = z3.Context() fmla = z3.parse_smt2_file(args.ass_inv_file, ctx=ctx) lemmas = [] assert z3.is_and(fmla), \ "invariant file should be a set of assertions" for l in fmla.children(): assert z3u.isZ3Implies(l), \ "assertions in the invariant file should be implications" name = str(l.arg(0).decl()) assert name.startswith("pre!"), \ "implicants in the invariant should start with pre!" if name in iass: lemmas.append(l.arg(1)) # dump the collected lemmas out = sys.stdout if args.out == '-' else open (args.out, 'w') z3u.to_smtlib(lemmas, out)
def num_clauses(formula): if z3.is_and(formula): return len(formula.children()) elif formula == True or z3.is_true(formula) or \ formula == False or z3.is_false(formula): return 0 else: return 1
def coerceTypesIfPossible(var, other_var): if z3.is_or(other_var) and not z3.is_bool(var): other_var = transformNonBooleanLazyEvaluations(other_var) if z3.is_or(var) and not z3.is_bool(other_var): var = transformNonBooleanLazyEvaluations(var) if z3.is_and(other_var) and not z3.is_bool(var): other_var = transformNonBooleanLazyEvaluations(other_var) if z3.is_and(var) and not z3.is_bool(other_var): var = transformNonBooleanLazyEvaluations(var) if var.decl().kind() == z3.Z3_OP_UNINTERPRETED: if z3.is_bool(other_var) and not z3.is_bool(var): infered_types[str(var)] = 'boolean' return z3.Bool(str(var)), other_var if z3.is_string(other_var) and not z3.is_string(var): if other_var.as_string() == '': # we probably dont want to coerce in this specific case as this is merely a non empty check if z3.is_bool(var): return var, z3.BoolVal(False) if z3.is_int(var): return var, z3.IntVal(0) else: infered_types[str(var)] = 'string' return z3.String(str(var)), other_var if z3.is_int(other_var) and not z3.is_int(var): infered_types[str(var)] = 'number' return z3.Int(str(var)), other_var elif var.decl().kind() == z3.Z3_OP_UNINTERPRETED: if z3.is_bool(var): infered_types[str(var)] = 'boolean' if z3.is_string(var): infered_types[str(var)] = 'string' if z3.is_int(var): infered_types[str(var)] = 'number' else: # this means that it is non-interpreted and we need to coerce other var to the type of var if z3.is_string(var) and z3.is_int_value(other_var): other_var = z3.StringVal(str(other_var)) if z3.is_arith(var) and z3.is_string(other_var): other_var = z3.IntVal(int(other_var.as_string())) return var, other_var
def num_univ_clauses(formula): if z3.is_and(formula): fs = formula.children() n = 0 for f in fs: if z3.is_quantifier(f) and f.is_forall(): n += 1 return n elif z3.is_quantifier(formula) and formula.is_forall(): return 1 else: return 0
def encodeAndSolve(self): """Generate horn formulas and solve""" self.setSolver() hornFormulas = self.args.file if self.args.smt2 else self.mk_horn() cex = None if not hornFormulas: self.log.error('Problem generating Horn formulae') return with utils.stats.timer('Parse'): self.log.info('Successful Horn Generation ... ' + str(hornFormulas)) q = self.fp.parse_file(hornFormulas) preds = utils.fp_get_preds( self.fp) # get the predicates before z3 starts playing with them if self.args.invs: lemmas = z3.parse_smt2_file(args.invs, sorts={}, decls={}, ctx=ctx) if z3.is_and(lemmas): lemmas = lemmas.children() for l in lemmas: if self.args.verbose: print l fp_add_cover(self.fp, l.arg(0), l.arg(1)) contract_file, emf_file = None, None with utils.stats.timer('Query'): res = self.fp.query(q[0]) if res == z3.sat: utils.stat('Result', 'CEX') cex = self.mk_cex(preds) elif res == z3.unsat: utils.stat('Result', 'SAFE') if self.args.ri: self.get_raw_invs(preds) if self.args.cg: contract_file, emf_file = self.mk_contract(preds) # try: # except Exception as e: # print e # self.log.warning('Failed to generate CoCoSpec') if not self.args.save: self.log.debug("Cleaning up temp files ...") try: os.remove(self.smt2_file) os.remove(self.trace_file) except: self.log.info('No Cleaning of temp files ...') if self.args.xml: utils.stats.xml_print(self.args.node, cex, contract_file, emf_file) else: utils.stats.brunch_print()
def _prove(self, cond, pre=None, return_model=False, minimize=True): if minimize: self.solver.push() print "\n ×××××××××××××××" print "\n cond:{}".format(cond) print "\n ×××××××××××××××" self.solver.add(z3.Not(cond)) res = self.solver.check() if res != z3.unsat: print "main.py.HV6Base._prove: Fail! Fail! Fail!" if not minimize and not return_model: self.assertEquals(res, z3.unsat) model = self.solver.model() if return_model: return model print "Could not prove, trying to find a minimal ce" assert res != z3.unknown if z3.is_and(cond): self.solver.pop() # Condition is a conjunction of some child clauses. # See if we can find something smaller that is sat. if pre is not None: ccond = sorted( zip(cond.children(), pre.children()), key=lambda x: len(str(x[0]))) else: ccond = sorted(cond.children(), key=lambda x: len(str(x))) for i in ccond: self.solver.push() if isinstance(i, tuple): self._prove(i[0], pre=i[1]) else: self._prove(i) self.solver.pop() print "Can not minimize condition further" if pre is not None: print "Precondition" print pre print "does not imply" print cond print "HV6" self.assertEquals(model, [])
def find_all_uninterp_consts(formula, res): if z3.is_quantifier(formula): formula = formula.body() worklist = [] if z3.is_implies(formula): worklist.append(formula.arg(1)) arg0 = formula.arg(0) if z3.is_and(arg0): worklist.extend(arg0.children()) else: worklist.append(arg0) else: worklist.append(formula) for t in worklist: if z3.is_app(t) and t.decl().kind() == z3.Z3_OP_UNINTERPRETED: res.append(t.decl())
def _parseSmt2String(self, formula): try: if z3.is_or(formula): return z3.Or(self._parseSmt2String(formula.children())) elif z3.is_and(formula): return z3.And(self._parseSmt2String(formula.children())) elif isinstance(formula, list): # and len(formula) > 1: tmp = [] for elem in formula: tmp.append(self._parseSmt2String(elem)) return tmp elif z3.is_not(formula): return z3.Not(self._parseSmt2String(formula.children()[0])) else: return self._abstraction(formula) except: self._logger.writeToLog( "Some Error Occured parsing formula: {}".format(formula)) raise Exception
def split_bool_and(constraint): """ Recursively split boolean and into separate constraints """ final_constraints = [] work_list = deque([constraint]) while len(work_list) > 0: item = work_list.popleft() if not z3.is_and(item): final_constraints.append(item) continue # Have and And node, append children to the work list # right to left so args get processed left to right. assert item.num_args() >= 2 indices = list(range(0, item.num_args())) indices.reverse() for i in indices: work_list.appendleft(item.arg(i)) return final_constraints
def _dfs(self, lit_hash, to_calc, lines, first_and_lit): if to_calc in lit_hash.keys(): return lit_hash[to_calc] if to_calc % 2 == 1: self._dfs(lit_hash, to_calc - 1, lines, first_and_lit) if is_and(lit_hash[to_calc - 1]): and_line = lines[(to_calc - first_and_lit) / 2].split() l, r = int(and_line[1]), int(and_line[2]) if is_not(lit_hash[l]) and is_not(lit_hash[r]): lit_hash[to_calc] = Or(lit_hash[l - 1], lit_hash[r - 1]) return lit_hash[to_calc] = Not(lit_hash[to_calc - 1]) return and_line = lines[(to_calc - first_and_lit) / 2].split() l, r = int(and_line[1]), int(and_line[2]) self._dfs(lit_hash, l, lines, first_and_lit) self._dfs(lit_hash, r, lines, first_and_lit) lit_hash[to_calc] = And(lit_hash[l], lit_hash[r]) return
def mk_app(self, f, args): if z3.is_eq(f): return args[0] == args[1] elif z3.is_and(f): return And(*args) elif z3.is_or(f): return Or(*args) elif z3.is_not(f): return Not(*args) elif z3.is_add(f): return reduce(operator.add, args[1:], args[0]) elif z3.is_mul(f): return reduce(operator.mul, args[1:], args[0]) elif z3.is_sub(f): return args[0] - args[1] elif z3.is_div(f): return args[0] / args[1] elif z3.is_lt(f): return args[0] < args[1] elif z3.is_le(f): return args[0] <= args[1] elif z3.is_gt(f): return args[0] > args[1] elif z3.is_ge(f): return args[0] >= args[1] elif z3.is_to_real(f): # TODO: ignore coercions? return args[0] elif z3.is_to_int(f): return args[0] elif f.name() == '=>': return implies(args[0], args[1]) else: dom_types = [self.mk_sort(f.domain(i))\ for i in range(0, f.arity())] cod_type = self.mk_sort(f.range()) dom_types.reverse() fun_type = reduce((lambda X, Y: type_arrow(Y, X)), \ dom_types, cod_type) func = self.mk_fun(f) return func(*args)
def _update(self): if not self.has_formula(): return rels = list() find_all_uninterp_consts(self._formula, rels) self._rels = frozenset(rels) body = self._formula if z3.is_quantifier(body): body, self._bound_constants = ground_quantifier(body) if z3.is_implies(body): self._head = body.arg(1) body = body.arg(0) if z3.is_and(body): body = body.children() else: body = [body] else: self._head = body body = [] # remove all true constants body = [x for x in body if not z3.is_true(x)] if len(body) > 0: self._body = body for i in range(len(body)): f = body[i] if z3.is_app(f) and f.decl() in self._rels: self._uninterp_sz += 1 else: break # reset _formula, it can be re-computed using mk_formula() # this ensures that any simplifications that are done during _update() are # also reflected in the formula view self._formula = None assert self._head is not None
def toCnf(self): #t = Then('simplify','nnf') #subgoal = t(simplify(self._kb)) #self._logger.writeToLog("subgoal",subgoal) cnf = z3.simplify(self._toCnf(self._kb)) cnflist = [] if z3.is_and(cnf): for i in cnf.children(): tmp = [] if z3.is_or(i): for ii in i.children(): if z3.is_const(ii) or z3.is_not(ii) and z3.is_const( ii.children()[0]): tmp.append(ii) else: self._logger.writeToLog("Wrongly formulated CNF") raise Exception elif z3.is_not(i) and z3.is_const(i.children()[0]): tmp.append(i) elif z3.is_const(i): tmp.append(i) else: self._logger.writeToLog("Wonrgly formulated CNF") cnflist.append(tmp) elif z3.is_or(cnf): tmp = [] for i in cnf.children(): if z3.is_const(i) or z3.is_not(i) and z3.is_const( i.children()[0]): tmp.append(i) else: self._logger.writeToLog("Wonrgly formulated CNF") cnflist.append(tmp) self._logger.writeToLog( "Full Propositional KB in CNF: {}".format(cnflist)) return cnflist
def _toCnf(self, formula): if z3.is_or(formula): tmp = [] ground = [] for i in formula.children(): tmp.append(self._toCnf(i)) for i in tmp: if z3.is_and(i): ground.append(i.children()) elif z3.is_const(i): ground.append([i]) elif z3.is_not(i) and z3.is_const(i.children()[0]): ground.append([i]) elif z3.is_or(i) and all( z3.is_const(elem) or z3.is_not(elem) and z3.is_const(elem.children()[0]) for elem in i.children()): for j in i.children(): ground.append([j]) else: self._logger.writeToLog("is_or, {},{}".format(formula, i)) raise Exception result = [] self._logger.writeToLog("CROSS: {}".format(ground)) for i in itertools.product(*ground): self._logger.writeToLog('Writing to rsults: {},{}'.format( i, list(i))) result.append(z3.Or(i)) self._logger.writeToLog('Resutl: {}'.format(result)) result = z3.And(result) self._logger.writeToLog('ResutAnd: {}'.format(result)) resultS = z3.simplify(result) self._logger.writeToLog("Result simplified: {}".format(resultS)) return resultS elif z3.is_and(formula): tmp = [] ground = [] for i in formula.children(): tmp.append(self._toCnf(i)) for i in tmp: if z3.is_and(i): ground.extend(i.children()) elif z3.is_const(i): ground.append(i) elif z3.is_not(i) and z3.is_const(i.children()[0]): ground.append(i) elif z3.is_or(i) and all( z3.is_const(elem) or z3.is_not(elem) and z3.is_const(elem.children()[0]) for elem in i.children()): ground.append(i) # SHoueld be ----> (1 v 2) and 3 --> (1 and 3 or 2 and 3) not just adding them to the and statement.... right ? else: self._logger.error("is_and, {}, {}".format(formula, i)) raise Exception return z3.simplify(z3.And(ground)) elif z3.is_not(formula): if z3.is_const(formula.children()[0]): return formula elif z3.is_not(formula.children()[0]): return self._toCnf(formula.children()[0]) elif z3.is_and(formula.children()[0]): return self._toCnf( z3.Or([ z3.Not(elem) for elem in formula.children()[0].children() ])) elif z3.is_or(formula.children()[0]): return self._toCnf( z3.And([ z3.Not(elem) for elem in formula.children()[0].children() ])) else: self._logger.writeToLog("is_not({}) problem".formula(formula)) raise Exception elif z3.is_const(formula): return formula else: self._logger.writeToLog("is_nothing problem", formula)
def getFirstConjunct (exp) : assert z3.is_app (exp) if z3.is_and (exp) : return exp.arg (0) else : return exp
def _back_single_term(self, expr, args, model=None): assert z3.is_expr(expr) if z3.is_quantifier(expr): raise NotImplementedError( "Quantified back conversion is currently not supported") res = None if z3.is_and(expr): res = self.mgr.And(args) elif z3.is_or(expr): res = self.mgr.Or(args) elif z3.is_add(expr): res = self.mgr.Plus(args) elif z3.is_div(expr): res = self.mgr.Div(args[0], args[1]) elif z3.is_eq(expr): if self._get_type(args[0]).is_bool_type(): res = self.mgr.Iff(args[0], args[1]) else: res = self.mgr.Equals(args[0], args[1]) elif z3.is_iff(expr): res = self.mgr.Iff(args[0], args[1]) elif z3.is_xor(expr): res = self.mgr.Xor(args[0], args[1]) elif z3.is_false(expr): res = self.mgr.FALSE() elif z3.is_true(expr): res = self.mgr.TRUE() elif z3.is_gt(expr): res = self.mgr.GT(args[0], args[1]) elif z3.is_ge(expr): res = self.mgr.GE(args[0], args[1]) elif z3.is_lt(expr): res = self.mgr.LT(args[0], args[1]) elif z3.is_le(expr): res = self.mgr.LE(args[0], args[1]) elif z3.is_mul(expr): res = self.mgr.Times(args[0], args[1]) elif z3.is_uminus(expr): tp = self._get_type(args[0]) if tp.is_real_type(): minus_one = self.mgr.Real(-1) else: assert tp.is_int_type() minus_one = self.mgr.Int(-1) res = self.mgr.Times(args[0], minus_one) elif z3.is_sub(expr): res = self.mgr.Minus(args[0], args[1]) elif z3.is_not(expr): res = self.mgr.Not(args[0]) elif z3.is_implies(expr): res = self.mgr.Implies(args[0], args[1]) elif z3.is_quantifier(expr): raise NotImplementedError elif z3.is_const(expr): if z3.is_rational_value(expr): n = expr.numerator_as_long() d = expr.denominator_as_long() f = Fraction(n, d) res = self.mgr.Real(f) elif z3.is_int_value(expr): n = expr.as_long() res = self.mgr.Int(n) elif z3.is_bv_value(expr): n = expr.as_long() w = expr.size() res = self.mgr.BV(n, w) elif z3.is_as_array(expr): if model is None: raise NotImplementedError("As-array expressions cannot be" \ " handled as they are not " \ "self-contained") else: interp_decl = z3.get_as_array_func(expr) interp = model[interp_decl] default = self.back(interp.else_value(), model=model) assign = {} for i in xrange(interp.num_entries()): e = interp.entry(i) assert e.num_args() == 1 idx = self.back(e.arg_value(0), model=model) val = self.back(e.value(), model=model) assign[idx] = val arr_type = self._z3_to_type(expr.sort()) res = self.mgr.Array(arr_type.index_type, default, assign) elif z3.is_algebraic_value(expr): # Algebraic value return self.mgr._Algebraic(Numeral(expr)) else: # it must be a symbol res = self.mgr.get_symbol(str(expr)) elif z3.is_ite(expr): res = self.mgr.Ite(args[0], args[1], args[2]) elif z3.is_function(expr): res = self.mgr.Function(self.mgr.get_symbol(expr.decl().name()), args) elif z3.is_to_real(expr): res = self.mgr.ToReal(args[0]) elif z3.is_bv_and(expr): res = self.mgr.BVAnd(args[0], args[1]) elif z3.is_bv_or(expr): res = self.mgr.BVOr(args[0], args[1]) elif z3.is_bv_xor(expr): res = self.mgr.BVXor(args[0], args[1]) elif z3.is_bv_not(expr): res = self.mgr.BVNot(args[0]) elif z3.is_bv_neg(expr): res = self.mgr.BVNeg(args[0]) elif z3.is_bv_concat(expr): res = self.mgr.BVConcat(args[0], args[1]) elif z3.is_bv_ult(expr): res = self.mgr.BVULT(args[0], args[1]) elif z3.is_bv_uleq(expr): res = self.mgr.BVULE(args[0], args[1]) elif z3.is_bv_slt(expr): res = self.mgr.BVSLT(args[0], args[1]) elif z3.is_bv_sleq(expr): res = self.mgr.BVSLE(args[0], args[1]) elif z3.is_bv_ugt(expr): res = self.mgr.BVUGT(args[0], args[1]) elif z3.is_bv_ugeq(expr): res = self.mgr.BVUGE(args[0], args[1]) elif z3.is_bv_sgt(expr): res = self.mgr.BVSGT(args[0], args[1]) elif z3.is_bv_sgeq(expr): res = self.mgr.BVSGE(args[0], args[1]) elif z3.is_bv_extract(expr): end = z3.get_payload(expr, 0) start = z3.get_payload(expr, 1) res = self.mgr.BVExtract(args[0], start, end) elif z3.is_bv_add(expr): res = self.mgr.BVAdd(args[0], args[1]) elif z3.is_bv_mul(expr): res = self.mgr.BVMul(args[0], args[1]) elif z3.is_bv_udiv(expr): res = self.mgr.BVUDiv(args[0], args[1]) elif z3.is_bv_sdiv(expr): res = self.mgr.BVSDiv(args[0], args[1]) elif z3.is_bv_urem(expr): res = self.mgr.BVURem(args[0], args[1]) elif z3.is_bv_srem(expr): res = self.mgr.BVSRem(args[0], args[1]) elif z3.is_bv_lshl(expr): res = self.mgr.BVLShl(args[0], args[1]) elif z3.is_bv_lshr(expr): res = self.mgr.BVLShr(args[0], args[1]) elif z3.is_bv_ashr(expr): res = self.mgr.BVAShr(args[0], args[1]) elif z3.is_bv_sub(expr): res = self.mgr.BVSub(args[0], args[1]) elif z3.is_bv_rol(expr): amount = z3.get_payload(expr, 0) res = self.mgr.BVRol(args[0], amount) elif z3.is_bv_ror(expr): amount = z3.get_payload(expr, 0) res = self.mgr.BVRor(args[0], amount) elif z3.is_bv_ext_rol(expr): amount = args[1].bv_unsigned_value() res = self.mgr.BVRol(args[0], amount) elif z3.is_bv_ext_ror(expr): amount = args[1].bv_unsigned_value() res = self.mgr.BVRor(args[0], amount) elif z3.is_bv_sext(expr): amount = z3.get_payload(expr, 0) res = self.mgr.BVSExt(args[0], amount) elif z3.is_bv_zext(expr): amount = z3.get_payload(expr, 0) res = self.mgr.BVZExt(args[0], amount) elif z3.is_array_select(expr): res = self.mgr.Select(args[0], args[1]) elif z3.is_array_store(expr): res = self.mgr.Store(args[0], args[1], args[2]) elif z3.is_const_array(expr): arr_ty = self._z3_to_type(expr.sort()) k = args[0] res = self.mgr.Array(arr_ty.index_type, k) elif z3.is_power(expr): res = self.mgr.Pow(args[0], args[1]) if res is None: raise ConvertExpressionError(message=("Unsupported expression: %s" % str(expr)), expression=expr) return res
def get_conjuncts (exp) : assert z3.is_bool (exp) if z3.is_and (exp) : return exp.children () else : return [exp]
def _back_single_term(self, expr, args, model=None): assert z3.is_expr(expr) if z3.is_quantifier(expr): raise NotImplementedError( "Quantified back conversion is currently not supported") assert not len(args) > 2 or \ (z3.is_and(expr) or z3.is_or(expr) or z3.is_add(expr) or z3.is_mul(expr) or (len(args) == 3 and (z3.is_ite(expr) or z3.is_array_store(expr)))),\ "Unexpected n-ary term: %s" % expr res = None try: decl = z3.Z3_get_app_decl(expr.ctx_ref(), expr.as_ast()) kind = z3.Z3_get_decl_kind(expr.ctx.ref(), decl) # Try to get the back-conversion function for the given Kind fun = self._back_fun[kind] return fun(args, expr) except KeyError as ex: pass if z3.is_const(expr): # Const or Symbol if z3.is_rational_value(expr): n = expr.numerator_as_long() d = expr.denominator_as_long() f = Fraction(n, d) return self.mgr.Real(f) elif z3.is_int_value(expr): n = expr.as_long() return self.mgr.Int(n) elif z3.is_bv_value(expr): n = expr.as_long() w = expr.size() return self.mgr.BV(n, w) elif z3.is_as_array(expr): if model is None: raise NotImplementedError("As-array expressions cannot be" \ " handled as they are not " \ "self-contained") else: interp_decl = z3.get_as_array_func(expr) interp = model[interp_decl] default = self.back(interp.else_value(), model=model) assign = {} for i in xrange(interp.num_entries()): e = interp.entry(i) assert e.num_args() == 1 idx = self.back(e.arg_value(0), model=model) val = self.back(e.value(), model=model) assign[idx] = val arr_type = self._z3_to_type(expr.sort()) return self.mgr.Array(arr_type.index_type, default, assign) elif z3.is_algebraic_value(expr): # Algebraic value return self.mgr._Algebraic(Numeral(expr)) else: # it must be a symbol try: return self.mgr.get_symbol(str(expr)) except UndefinedSymbolError: import warnings symb_type = self._z3_to_type(expr.sort()) warnings.warn("Defining new symbol: %s" % str(expr)) return self.mgr.FreshSymbol(symb_type, template="__z3_%d") elif z3.is_function(expr): # This needs to be after we try to convert regular Symbols fsymbol = self.mgr.get_symbol(expr.decl().name()) return self.mgr.Function(fsymbol, args) # If we reach this point, we did not manage to translate the expression raise ConvertExpressionError(message=("Unsupported expression: %s" % (str(expr))), expression=expr)
def _get_first_pred_inst (self, expr): if expr is not None and z3.is_and (expr): return expr.arg (0) return None
def back(self, expr): assert z3.is_expr(expr) if askey(expr) in self.backconversion: return self.backconversion[askey(expr)] if z3.is_quantifier(expr): raise NotImplementedError( "Quantified back conversion is currently not supported") args = [self.back(x) for x in expr.children()] res = None if z3.is_and(expr): res = self.mgr.And(args) elif z3.is_or(expr): res = self.mgr.Or(args) elif z3.is_add(expr): res = self.mgr.Plus(args) elif z3.is_div(expr): res = self.mgr.Div(args[0], args[1]) elif z3.is_eq(expr): if self._get_type(args[0]) == types.BOOL: res = self.mgr.Iff(args[0], args[1]) else: res = self.mgr.Equals(args[0], args[1]) elif z3.is_false(expr): res = self.mgr.FALSE() elif z3.is_true(expr): res = self.mgr.TRUE() elif z3.is_gt(expr): res = self.mgr.GT(args[0], args[1]) elif z3.is_ge(expr): res = self.mgr.GE(args[0], args[1]) elif z3.is_lt(expr): res = self.mgr.LT(args[0], args[1]) elif z3.is_le(expr): res = self.mgr.LE(args[0], args[1]) elif z3.is_mul(expr): res = self.mgr.Times(args[0], args[1]) elif z3.is_sub(expr): res = self.mgr.Minus(args[0], args[1]) elif z3.is_not(expr): res = self.mgr.Not(args[0]) elif z3.is_quantifier(expr): if expr.is_forall(): pass else: pass raise NotImplementedError elif z3.is_const(expr): if z3.is_rational_value(expr): n = expr.numerator_as_long() d = expr.denominator_as_long() f = Fraction(n, d) res = self.mgr.Real(f) elif z3.is_int_value(expr): n = expr.as_long() res = self.mgr.Int(n) else: # it must be a symbol res = self.mgr.get_symbol(str(expr)) elif z3.is_ite(expr): res = self.mgr.Ite(args[0], args[1], args[2]) else: raise TypeError("Unsupported expression:", expr) if res is None: raise TypeError("Unsupported expression:", expr) self.backconversion[askey(expr)] = res return res
def _back_single_term(self, expr, args): assert z3.is_expr(expr) if z3.is_quantifier(expr): raise NotImplementedError( "Quantified back conversion is currently not supported") res = None if z3.is_and(expr): res = self.mgr.And(args) elif z3.is_or(expr): res = self.mgr.Or(args) elif z3.is_add(expr): res = self.mgr.Plus(args) elif z3.is_div(expr): res = self.mgr.Div(args[0], args[1]) elif z3.is_eq(expr): if self._get_type(args[0]).is_bool_type(): res = self.mgr.Iff(args[0], args[1]) else: res = self.mgr.Equals(args[0], args[1]) elif z3.is_iff(expr): res = self.mgr.Iff(args[0], args[1]) elif z3.is_xor(expr): res = self.mgr.Xor(args[0], args[1]) elif z3.is_false(expr): res = self.mgr.FALSE() elif z3.is_true(expr): res = self.mgr.TRUE() elif z3.is_gt(expr): res = self.mgr.GT(args[0], args[1]) elif z3.is_ge(expr): res = self.mgr.GE(args[0], args[1]) elif z3.is_lt(expr): res = self.mgr.LT(args[0], args[1]) elif z3.is_le(expr): res = self.mgr.LE(args[0], args[1]) elif z3.is_mul(expr): res = self.mgr.Times(args[0], args[1]) elif z3.is_uminus(expr): tp = self._get_type(args[0]) if tp.is_real_type(): minus_one = self.mgr.Real(-1) else: assert tp.is_int_type() minus_one = self.mgr.Int(-1) res = self.mgr.Times(args[0], minus_one) elif z3.is_sub(expr): res = self.mgr.Minus(args[0], args[1]) elif z3.is_not(expr): res = self.mgr.Not(args[0]) elif z3.is_implies(expr): res = self.mgr.Implies(args[0], args[1]) elif z3.is_quantifier(expr): raise NotImplementedError elif z3.is_const(expr): if z3.is_rational_value(expr): n = expr.numerator_as_long() d = expr.denominator_as_long() f = Fraction(n, d) res = self.mgr.Real(f) elif z3.is_int_value(expr): n = expr.as_long() res = self.mgr.Int(n) elif z3.is_bv_value(expr): n = expr.as_long() w = expr.size() res = self.mgr.BV(n, w) else: # it must be a symbol res = self.mgr.get_symbol(str(expr)) elif z3.is_ite(expr): res = self.mgr.Ite(args[0], args[1], args[2]) elif z3.is_function(expr): res = self.mgr.Function(self.mgr.get_symbol(expr.decl().name()), args) elif z3.is_to_real(expr): res = self.mgr.ToReal(args[0]) elif z3.is_bv_and(expr): res = self.mgr.BVAnd(args[0], args[1]) elif z3.is_bv_or(expr): res = self.mgr.BVOr(args[0], args[1]) elif z3.is_bv_xor(expr): res = self.mgr.BVXor(args[0], args[1]) elif z3.is_bv_not(expr): res = self.mgr.BVNot(args[0]) elif z3.is_bv_neg(expr): res = self.mgr.BVNeg(args[0]) elif z3.is_bv_concat(expr): res = self.mgr.BVConcat(args[0], args[1]) elif z3.is_bv_ult(expr): res = self.mgr.BVULT(args[0], args[1]) elif z3.is_bv_uleq(expr): res = self.mgr.BVULE(args[0], args[1]) elif z3.is_bv_slt(expr): res = self.mgr.BVSLT(args[0], args[1]) elif z3.is_bv_sleq(expr): res = self.mgr.BVSLE(args[0], args[1]) elif z3.is_bv_ugt(expr): res = self.mgr.BVUGT(args[0], args[1]) elif z3.is_bv_ugeq(expr): res = self.mgr.BVUGE(args[0], args[1]) elif z3.is_bv_sgt(expr): res = self.mgr.BVSGT(args[0], args[1]) elif z3.is_bv_sgeq(expr): res = self.mgr.BVSGE(args[0], args[1]) elif z3.is_bv_extract(expr): end = z3.get_payload(expr, 0) start = z3.get_payload(expr, 1) res = self.mgr.BVExtract(args[0], start, end) elif z3.is_bv_add(expr): res = self.mgr.BVAdd(args[0], args[1]) elif z3.is_bv_mul(expr): res = self.mgr.BVMul(args[0], args[1]) elif z3.is_bv_udiv(expr): res = self.mgr.BVUDiv(args[0], args[1]) elif z3.is_bv_sdiv(expr): res = self.mgr.BVSDiv(args[0], args[1]) elif z3.is_bv_urem(expr): res = self.mgr.BVURem(args[0], args[1]) elif z3.is_bv_srem(expr): res = self.mgr.BVSRem(args[0], args[1]) elif z3.is_bv_lshl(expr): res = self.mgr.BVLShl(args[0], args[1]) elif z3.is_bv_lshr(expr): res = self.mgr.BVLShr(args[0], args[1]) elif z3.is_bv_ashr(expr): res = self.mgr.BVAShr(args[0], args[1]) elif z3.is_bv_sub(expr): res = self.mgr.BVSub(args[0], args[1]) elif z3.is_bv_rol(expr): amount = z3.get_payload(expr, 0) res = self.mgr.BVRol(args[0], amount) elif z3.is_bv_ror(expr): amount = z3.get_payload(expr, 0) res = self.mgr.BVRor(args[0], amount) elif z3.is_bv_ext_rol(expr): amount = args[1].bv_unsigned_value() res = self.mgr.BVRol(args[0], amount) elif z3.is_bv_ext_ror(expr): amount = args[1].bv_unsigned_value() res = self.mgr.BVRor(args[0], amount) elif z3.is_bv_sext(expr): amount = z3.get_payload(expr, 0) res = self.mgr.BVSExt(args[0], amount) elif z3.is_bv_zext(expr): amount = z3.get_payload(expr, 0) res = self.mgr.BVZExt(args[0], amount) if res is None: raise ConvertExpressionError(message=("Unsupported expression: %s" % str(expr)), expression=expr) return res
def flatten_and_tree(expr): if is_and(expr): return sum(map(flatten_and_tree, expr.children()), []) else: return [expr]
def _gen(expr_z3, symbolTable, cache, result): ###Leaf: var if _is_variable(expr_z3): if DEBUG: print "-- Branch _is_variable with ", expr_z3 symVar = expr_z3.decl().name() symVar = rename_var(symVar) if z3.is_int(expr_z3): symType = Sort.Int elif z3.is_fp(expr_z3): if expr_z3.sort() == z3.Float64(): symType = Sort.Float64 elif expr_z3.sort() == z3.Float32(): symType = Sort.Float32 else: raise NotImplementedError("Unexpected sort.", expr_z3.sort()) elif z3.is_real(expr_z3): symType = Sort.Float warnings.warn( "****WARNING****: Real variable '%s' treated as floating point" % symVar) else: raise NotImplementedError("Unexpected type for %s" % symbolName) if (symVar in symbolTable.keys()): assert symType == symbolTable[symVar] else: symbolTable[symVar] = symType if expr_z3.sort() == z3.Float32(): symVar = "TR32(%s)" % symVar # do the same ting for verify !!!!!!!! return symVar ###Leaf: val if _is_value(expr_z3): if DEBUG: print "-- Branch _is_value" if z3.is_fp(expr_z3) or z3.is_real(expr_z3): if DEBUG: print "---- Sub-Branch FP or Real" if isinstance(expr_z3, z3.FPNumRef): if DEBUG: print "------- Sub-Sub-Branch _is_FPNumRef" try: str_ret = str(sympy.Float(str(expr_z3), 17)) except ValueError: if expr_z3.isInf() and expr_z3.decl().kind( ) == z3.Z3_OP_FPA_PLUS_INF: str_ret = "INFINITY" elif expr_z3.isInf() and expr_z3.decl().kind( ) == z3.Z3_OP_FPA_MINUS_INF: str_ret = "- INFINITY" elif expr_z3.isNaN(): str_ret = "NAN" else: offset = 127 if expr_z3.sort() == z3.Float32( ) else 1023 #Z3 new version needs the offset to be taken into consideration expr_z3_exponent = expr_z3.exponent_as_long() - offset str_ret = str( sympy.Float((-1)**float(expr_z3.sign()) * float(str(expr_z3.significand())) * 2**(expr_z3_exponent), 17)) else: if DEBUG: print "------- Sub-Sub-Branch other than FPNumRef, probably FPRef" str_ret = str(sympy.Float(str((expr_z3)), 17)) elif z3.is_int(expr_z3): if DEBUG: print "---- Sub-Branch Integer" str_ret = str(sympy.Integer(str(expr_z3))) elif _is_true(expr_z3): str_ret = "0" elif _is_false(expr_z3): str_ret = "1" else: raise NotImplementedError( "[XSat: Coral Benchmarking] type not considered ") if expr_z3.sort() == z3.Float32(): str_ret = str_ret + "f" return str_ret #if (expr_z3 in cache): return cache[expr_z3] #cache will be a set of defined IDs #if (var_name(expr_z3) in cache): return cache[expr_z3] if (expr_z3.get_id() in cache): return var_name(expr_z3) cache.add(expr_z3.get_id()) #cache[expr_z3]=var_name(expr_z3) sort_z3 = expr_z3.decl().kind() expr_type = 'double' if expr_z3.sort() == z3.FPSort(8, 24): expr_type = 'float' ### if sort_z3 == z3.Z3_OP_FPA_LE: if DEBUG: print "-- Branch _is_le" lhs = _gen(expr_z3.arg(0), symbolTable, cache, result) rhs = _gen(expr_z3.arg(1), symbolTable, cache, result) toAppend= "double %s = DLE(%s,%s); " \ %( var_name(expr_z3), \ lhs,\ rhs,\ ) result.append(toAppend) return var_name(expr_z3) #########!!!!!!!!!!!! need to do something if sort_z3 == z3.Z3_OP_FPA_TO_FP: if DEBUG: print "-- Branch _is_fpFP" assert expr_z3.num_args() == 2 if not (_is_RNE(expr_z3.arg(0))): warnings.warn( "WARNING!!! I expect the first argument of fpFP is RNE, but it is ", expr_z3.arg(0)) x = _gen(expr_z3.arg(1), symbolTable, cache, result) if expr_z3.sort() == z3.FPSort(8, 24): x = "TR32(%s)" % x #else if expr_z3.sort()==z3.FPSort(8,24): # x = "TR(%s)" %x toAppend= "%s %s = %s; " \ %( expr_type, var_name(expr_z3), \ x,\ ) result.append(toAppend) return var_name(expr_z3) if sort_z3 == z3.Z3_OP_FPA_LT: if DEBUG: print "-- Branch _is_lt" lhs = _gen(expr_z3.arg(0), symbolTable, cache, result) rhs = _gen(expr_z3.arg(1), symbolTable, cache, result) toAppend= "double %s = DLT(%s,%s);" \ %( var_name(expr_z3), \ lhs,\ rhs,\ ) result.append(toAppend) return var_name(expr_z3) if _is_eq(expr_z3): if DEBUG: print "-- Branch _is_eq" lhs = _gen(expr_z3.arg(0), symbolTable, cache, result) rhs = _gen(expr_z3.arg(1), symbolTable, cache, result) toAppend= "double %s = DEQ(%s,%s);" \ %( var_name(expr_z3), \ lhs,\ rhs,\ ) result.append(toAppend) return var_name(expr_z3) if _is_fpMul(expr_z3): if DEBUG: print "-- Branch _is_fpMul" if not _is_RNE(expr_z3.arg(0)): warnings.warn( "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ", expr_z3.arg(0)) assert expr_z3.num_args() == 3 lhs = _gen(expr_z3.arg(1), symbolTable, cache, result) rhs = _gen(expr_z3.arg(2), symbolTable, cache, result) toAppend= "%s %s = %s*%s; " \ %( expr_type, var_name(expr_z3), \ lhs,\ rhs,\ ) result.append(toAppend) return var_name(expr_z3) if _is_fpDiv(expr_z3): if DEBUG: print "-- Branch _is_fpDiv" if not _is_RNE(expr_z3.arg(0)): warnings.warn( "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ", expr_z3.arg(0)) assert expr_z3.num_args() == 3 lhs = _gen(expr_z3.arg(1), symbolTable, cache, result) rhs = _gen(expr_z3.arg(2), symbolTable, cache, result) toAppend= "%s %s = %s/%s; " \ %(expr_type, var_name(expr_z3), \ lhs,\ rhs,\ ) result.append(toAppend) return var_name(expr_z3) if _is_fpAdd(expr_z3): if DEBUG: print "-- Branch _is_fpAdd" if not _is_RNE(expr_z3.arg(0)): warnings.warn( "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ", expr_z3.arg(0)) assert expr_z3.num_args() == 3 lhs = _gen(expr_z3.arg(1), symbolTable, cache, result) rhs = _gen(expr_z3.arg(2), symbolTable, cache, result) toAppend= "%s %s = %s+%s;" \ %( expr_type, var_name(expr_z3), \ lhs,\ rhs,\ ) result.append(toAppend) return var_name(expr_z3) if z3.is_and(expr_z3): if DEBUG: print "-- Branch _is_and" ##TODO Not sure if symbolTable will be treated in a multi-threaded way toAppendExpr = _gen(expr_z3.arg(0), symbolTable, cache, result) for i in range(1, expr_z3.num_args()): toAppendExpr = 'BAND( %s,%s )' % ( toAppendExpr, _gen(expr_z3.arg(i), symbolTable, cache, result)) toAppend= "double %s = %s; " \ %( var_name(expr_z3), \ toAppendExpr,\ ) result.append(toAppend) return var_name(expr_z3) if z3.is_not(expr_z3): if DEBUG: print "-- Branch _is_not" assert expr_z3.num_args() == 1 if not (expr_z3.arg(0).num_args() == 2): warnings.warn( "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ", expr_z3.arg(0)) op1 = _gen(expr_z3.arg(0).arg(0), symbolTable, cache, result) op2 = _gen(expr_z3.arg(0).arg(1), symbolTable, cache, result) if _is_ge(expr_z3.arg(0)): a = "DLT(%s,%s)" % (op1, op2) elif _is_gt(expr_z3.arg(0)): a = "DLE(%s,%s)" % (op1, op2) elif _is_le(expr_z3.arg(0)): a = "DGT(%s,%s)" % (op1, op2) elif _is_lt(expr_z3.arg(0)): a = "DGE(%s,%s)" % (op1, op2) elif _is_eq(expr_z3.arg(0)): a = "DNE(%s,%s)" % (op1, op2) elif _is_distinct(expr_z3.arg(0)): a = "DEQ(%s,%s)" % (op1, op2) else: raise NotImplementedError( "Not implemented case 004 for expr_z3 = %s. 'Not(or... )' is not handled yet" % expr_z3) toAppend= "%s %s = %s; " \ %( expr_type, var_name(expr_z3), \ a,\ ) result.append(toAppend) return var_name(expr_z3) if _is_fpNeg(expr_z3): if DEBUG: print "-- Branch _is_fpNeg" assert expr_z3.num_args() == 1 op1 = _gen(expr_z3.arg(0), symbolTable, cache, result) toAppend = "%s %s = - %s ;" \ %(expr_type, var_name(expr_z3), \ op1,\ ) result.append(toAppend) return var_name(expr_z3) raise NotImplementedError( "Not implemented case 002 for expr_z3 = %s, kind(%s)" % (expr_z3, expr_z3.decl().kind()))
def conjuncts (exp) : assert z3.is_bool (exp) if z3.is_and (exp) : for i in range (exp.num_args ()) : yield exp.arg (i) else : yield exp