def existVars(self, v1, v2): """ create a list of variables to be bound """ v1_str = [str(v) for v in v1] v2_filtered = list() for v in v2: if z3.is_not(v): v2_filtered.append(v.children()[0]) elif z3.is_app(v) and not z3.is_not(v): v2_filtered.append(v) for v in v2_filtered: if str(v) not in v1_str : v1.append(v) return v1
def existVars(self, v1, v2): """ create a list of variables to be bound """ v1_str = [str(v) for v in v1] v2_filtered = list() for v in v2: if z3.is_not(v): v2_filtered.append(v.children()[0]) elif z3.is_app(v) and not z3.is_not(v): v2_filtered.append(v) for v in v2_filtered: if str(v) not in v1_str: v1.append(v) return v1
def getDimacsMap(goal): d = DimacsConverter() t = Tactic("tseitin-cnf") cnf = t(goal) #print cnf clauses = [] #print(cnf) for i in cnf: for j in i: variables = [] #print (j) #print j.__class__ if len(j.children()) == 0: variables.append(str(d.getVarIndex(str(j)))) for k in j.children(): #print k if is_not(k): neg="-" newk = (simplify(Not(k))) else: neg="" newk = k variables.append(neg + str(d.getVarIndex(str(newk)))) clauses.append(variables) inv_map = {v:k for k, v in d.vars.items()} return inv_map
def convertToDimacs(goal, file): #f_n = open(Options.DIMACS_FILE, 'w') d = DimacsConverter() t = Tactic("tseitin-cnf") cnf = t(goal) #print cnf clauses = [] #print(cnf) for i in cnf: for j in i: variables = [] #print (j) #print j.__class__ if len(j.children()) == 0: variables.append(str(d.getVarIndex(str(j)))) for k in j.children(): #print k if is_not(k): neg="-" newk = (simplify(Not(k))) else: neg="" newk = k variables.append(neg + str(d.getVarIndex(str(newk)))) clauses.append(variables) inv_map = {v:k for k, v in d.vars.items()} #print(inv_map) f = open(file, 'r') for line in f: [var, val] = split(line) print("\"" + str(inv_map[int(var)])+"\",")
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 saveToDemacs(self, file): #self._logger.test("SAVING KB TO DEMACS: {}".format(file)) formula = self.toCnf() f = open('{}.cnf'.format(file), 'w') f.write('c this the Abstacted SMT Formalu in CNF (DEMACS)\n') f.write('p cnf {} {}\n'.format(len(self._predicates), len(formula))) for disj in formula: for var in disj: if z3.is_not(var): f.write('-{} '.format(str(var.children()[0]))) else: f.write('{} '.format(str(var))) f.write('0\n') f.close()
def toDimacs(self, clause, neg=False): variables = [] #print(clause) if z3.is_const(clause): if not isinstance(clause, IntNumRef): variables.append(self.getVarIndex(str(clause))) else: sys.exit("shouldn't get here") for c in clause.children(): if is_not(c): print("AAAA"); variables = variables + self.toDimacs(c) return variables
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 translate2(lit, seen_literals): or_clause = '' if z3.is_not(lit): or_clause = '-' lit = lit.children()[0] if str(lit)[0] == 'k': or_clause += str(lit)[2:] + ' ' if not lit in seen_literals: seen_literals[lit] = str(lit) else: or_clause += str(lit)[1:] + ' ' return or_clause
def encode_literal(var_mapping, Tseitin_vars, max_var, l): var = None if is_not(l): var = l.children()[0] lit_str = '-' else: var = l lit_str = '' assert is_const(var) # will fail if var.get_id() not in var_mapping: max_var += 1 Tseitin_vars.append(max_var) var_mapping[var.get_id()] = max_var lit_str += str(var_mapping[var.get_id()]) + ' ' return max_var, lit_str
def flatten_quantifier(expr): boundvariables = [] quantifiers = [] es = flatten_and_tree(expr) assert (len(filter(is_quant, es)) <= 1) for idx, e in enumerate(es): negated = False if is_not(e): e = e.children()[0] negated = True if is_quant(e): while is_quant(e): variables = [] for i in range(e.num_vars()): # variables += [[expr.var_name(i), expr.var_sort(i)]] if str(e.var_sort(i)).startswith('BitVec'): var = BitVec(e.var_name(i), e.var_sort(i).size()) else: assert (str(e.var_sort(i)) == ('Bool')) var = Bool(e.var_name(i)) variables.append(var) # if var in boundvariables: # log('ERROR: Currently require all variable names to be unique.') # exit() if e.is_forall(): negated = not negated if negated: new_quant = 'a' else: new_quant = 'e' quantifiers += [[new_quant, variables]] boundvariables += variables e = e.body() es[idx] = e break # only supports the case that at most one of the conjuncts is a quantiifer return And(es), boundvariables, quantifiers
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 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 translate(start_var, lit, seen_literals): or_clause = '' if z3.is_not(lit): or_clause = '-' lit = lit.children()[0] if str(lit)[0] == 'k': or_clause += str(int(str(lit)[2:]) + start_var) + ' ' if not lit in seen_literals: seen_literals[str(lit)] = int(str(lit)[2:]) + start_var elif str(lit)[0] == 'x': or_clause += str(lit)[1:] + ' ' if not lit in seen_literals: seen_literals[str(lit)] = int(str(lit)[1:]) else: if not lit in seen_literals: seen_literals[str(lit)] = int(str(lit)) or_clause += str(lit) + ' ' return or_clause
def is_neg_lit(a): """ Check if the input formula is a negative literal EXAMPLES: >>> from z3 import * >>> is_term(3) False >>> is_neg_lit(Not(Bool('x'))) True >>> is_neg_lit(Not(FALSE)) False >>> is_neg_lit(TRUE) False >>> is_neg_lit(FALSE) False >>> is_neg_lit(Not(Int('x') + Int('y') > 3)) True >>> is_neg_lit(Not(Bool('x') == TRUE)) True >>> is_neg_lit(Not(Int('x') == 3)) True >>> is_neg_lit(Not(TRUE)) False """ return is_not(a) and is_pos_lit(a.children()[0])
def negate(self): new_q_list = [(-_q, _v) for (_q, _v) in self._q_list] return QBF(self._prop.children()[0] if is_not(self._prop) else Not(self._prop), new_q_list)
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 _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 _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 writeQDIMACS(filename, constraint, quantifiers, bitmap=None): # filename: String # constraints: list of BV constraints # quantifiers: list of tuples (['a','e','max','count'], list of vars) assert_consistent_quantifiers(quantifiers) log('Bit blasting') bitmap = {} for q in quantifiers: bitvecs = filter(is_bv, q[1]) localBitmap, localBitmapConstraints = create_bitmap(bitvecs) bitmap.update(localBitmap) constraint = And(localBitmapConstraints, constraint) newQuantifiedVars = filter(lambda v: not is_bv(v), q[1]) for (_, boolvar) in localBitmap.iteritems(): newQuantifiedVars.append(boolvar) q[1] = newQuantifiedVars g = Goal() g.add(constraint) matrix = [] t = Then('simplify', 'bit-blast', 'tseitin-cnf') subgoal = t(g) # print(subgoal[0][0].children()[1].children()[0] == bitmap()) assert len(subgoal) == 1 # print('Printing quantifier') # print(quantifiers) # print('Printing goal') # print(g) # exit() max_var = 0 var_mapping = {} # maps to qdimacs variables textFile = open(filename, "w") log('Creating and writing symbol table') textFile.write('c Symbol table for bitvectors\n') symbol_table = [] for ((bv, i), boolvar) in bitmap.iteritems(): max_var += 1 var_mapping[boolvar.get_id()] = max_var # symbol_table.append('c ' + str(boolvar) + ' --> ' + str(max_var)) textFile.write('c ' + str(boolvar) + ' --> ' + str(max_var) + '\n') log('Reserving variable names for quantified variables') for i, q in enumerate(quantifiers): for var in q[1]: if var.get_id() not in var_mapping: max_var += 1 var_mapping[var.get_id()] = max_var # minTseitin = max_var + 1 Tseitin_vars = [] log('Generating clauses ... (this may take a while)') clause_num = 0 for c in subgoal[0]: clause_num += 1 if clause_num % 10000 == 0: log(' {} clauses'.format(clause_num)) if is_or(c): clause = '' for l in c.children(): # literals max_var, lit_str = encode_literal(var_mapping, Tseitin_vars, max_var, l) clause += lit_str matrix.append(clause) elif is_const(c) or is_not(c): max_var, lit_str = encode_literal(var_mapping, Tseitin_vars, max_var, c) matrix.append(lit_str) else: log('Error: Unknown element ' + str(c)) assert false matrix.append('') log(' Generated ' + str(clause_num) + ' clauses') log('Writing header') textFile.write('p cnf {} {}\n'.format(max_var, clause_num)) # Extending quantifiers by innermost existential if necessary if quantifiers[-1][0] == 'a' and len( Tseitin_vars) > 0: # max_var + 1 - minTseitin > 0 quantifiers.append(['e', []]) # empty existential log('Writing quantifiers') for i, q in enumerate(quantifiers): textFile.write(q[0]) for v in q[1]: # try: v_id = v.get_id() textFile.write(' ' + str(var_mapping[v_id])) # except Exception as ex: # log(' Error when writing var {} to file ({})'.format(str(v), str(ex))) # # template = "An exception of type {0} occurred. Arguments:\n{1!r}" # message = template.format(type(ex).__name__, ex.args) # print message # # exit() if i == len(quantifiers) - 1: log('Adding {} Tseitin variables'.format(len(Tseitin_vars))) for varID in Tseitin_vars: textFile.write(' ' + str(varID)) # for varID in range(minTseitin,max_var+1): # # log('Adding var {}'.format(varID)) # textFile.write(' '+str(varID)) # # quantifiers[-1][1].append(varID) # log(' OK (added {} Tseitin vars)'.format(len(range(minTseitin,max_var+1)))) textFile.write(' 0\n') log('Writing clauses') textFile.write('0\n'.join(matrix)) textFile.close() return var_mapping
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