def model_value_to_python(value: z3.ExprRef) -> object: if z3.is_string_value(value): return value.as_string() elif z3.is_real(value): return float(value.as_fraction()) else: return ast.literal_eval(repr(value))
def __k_bool__(self): if z3.is_int(self.value) or z3.is_real(self.value) or z3.is_bv( self.value): yield inference.InferenceResult(Z3Proxy.init_expr( self.value != 0, self.defaults), status=True) elif z3.is_string(self.value): yield inference.InferenceResult(Z3Proxy.init_expr( self.value != z3.StringVal(""), self.defaults), status=True) else: yield inference.InferenceResult(self, status=True)
def get_py_val_from_z3_val(z3_result): if z3_result is not None: if z3.is_int_value(z3_result): return z3_result.as_long() elif z3.is_real(z3_result): return float(z3_result.numerator_as_long()) / float( z3_result.denominator_as_long()) elif z3.is_true(z3_result): return True elif z3.is_false(z3_result): return False elif z3.is_string_value(z3_result): return z3_result.as_string() else: raise NotImplementedError( "Z3 model result other than int, real, bool, string is not supported yet!" )
def _enc_real_expr(self, c): if z3.is_real(c): return c elif isinstance(c, float): return c elif isinstance(c, int): return float(c) elif isinstance(c, VerifierVar): return c.get() elif isinstance(c, SumExpr): s = self._enc_real_expr(c.parts[0]) for p in c.parts[1:]: s += self._enc_real_expr(p) return s else: raise RuntimeError("unsupported VerifierRealExpr of type " + type(c).__qualname__)
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 walk_block(node, prev_g=None, cond=True): g = z3.Goal() g.add(cond) if prev_g is not None: for e in prev_g: if isinstance(e, z3.Goal): g.add(e.as_expr()) else: g.add(e) if isinstance(node, pycp.c_ast.Compound): if node.block_items is not None: for e in node.block_items: g_next = walk_block(e, g) g = g_next elif isinstance(node, pycp.c_ast.Decl): if "int" in node.type.type.names: vars[node.name] = z3.Int(node.name) if "float" in node.type.type.names: vars[node.name] = z3.Real(node.name) elif isinstance(node, pycp.c_ast.FuncCall): if node.name.name == "__ASSUME": for e_exp in node.args.exprs: g.add(gen_smt_expr(e_exp)) elif node.name.name == "__ASSERT": assertions = z3.Goal() for e_exp in node.args.exprs: assertions.add(gen_smt_expr(e_exp)) print("solving..") print("SP:", g.as_expr()) print("assert:", assertions) seen = set() def bv_length(e): li = [-1] if e in seen: return -1 if (z3.is_bv(e) and z3.is_const(e) and e.decl().kind() == z3.Z3_OP_UNINTERPRETED): li.append(e.size()) seen.add(e) if z3.is_app(e): for ch in e.children(): li.append(bv_length(ch)) elif z3.is_quantifier(e): for ch in e.body().children(): li.append(bv_length(ch)) return max(li) t = z3.Tactic('nla2bv') s = z3.Then(t, 'default').solver() fml = z3.And(g.as_expr(), z3.Not(assertions.as_expr())) print("solving using bitvector underapproximation..") s.add(fml) status = s.check() if status == z3.unknown: print("returned 'unknown'! trying again with bigger bit length..") print("getting highest bit length used in formula..") bv_l = bv_length(t(fml).as_expr()) print("highest bit length used:", bv_l) while True: bv_l += 1 print("trying with bit length:", bv_l) s = z3.Then(z3.With('nla2bv', nla2bv_bv_size=bv_l), 'default').solver() s.add(fml) status = s.check() if status != z3.unknown or bv_l >= 64: break if status == z3.sat: model = s.model() print("program is unsafe.\nlisting an unsafe assignments..") for e in vars: print(e, ':', model[vars[e]]) elif status == z3.unsat: print("program is safe.") elif status == z3.unknown: print("unknown") s.reset() else: print("found a func call") elif isinstance(node, pycp.c_ast.Assignment): rexp = gen_smt_expr(node.rvalue) if z3.is_int(vars[node.lvalue.name]): hand_ = z3.Int('__hand__') elif z3.is_real(vars[node.lvalue.name]): hand_ = z3.Real('__hand__') if node.op == "=": g.add(hand_ == rexp) elif node.op == "+=": g.add(hand_ == (vars[node.lvalue.name] + rexp)) elif node.op == "-=": g.add(hand_ == (vars[node.lvalue.name] - rexp)) elif node.op == "*=": g.add(hand_ == (vars[node.lvalue.name] * rexp)) elif node.op == "%=": g.add(hand_ == (vars[node.lvalue.name] % rexp)) g_ = z3.Goal() g_.add(z3.Exists(vars[node.lvalue.name], g.as_expr())) g_ = t_qe_(g_) g = z3.Goal() g.add(z3.substitute(g_.as_expr(), (hand_, vars[node.lvalue.name]))) # g = g.simplify() elif isinstance(node, pycp.c_ast.If): cond_exp = gen_smt_expr(node.cond) if node.iftrue is not None: true_expr = walk_block(node.iftrue, g, cond_exp).as_expr() else: true_expr = z3.And(cond_exp, g.as_expr()) if node.iffalse is not None: false_expr = walk_block( node.iffalse, g, z3.Not(cond_exp)).as_expr() else: false_expr = z3.And(z3.Not(cond_exp), g.as_expr()) g = z3.Goal() g.add(z3.Or(true_expr, false_expr)) g = t(g) # g.simplify() else: return prev_g # print(g.as_expr(), "\n") return g
def _parseSmt1String(self, string): #self._logger.setVerbose(True) stack = list() functionSymbols = '&|~<=*+-' try: string = string.replace('\n', '').split('(') idx = 0 for pos, elem in enumerate(string): self._logger.writeToLog('{} - reading :{}:'.format(pos, elem)) if elem == '': continue elemL = elem.split() # ALL lines should start with '(' if elemL[0] in functionSymbols: stack.append(elemL[0]) elif elemL[0] == 'var': varName = elemL[2].replace(')', '') if elemL[1] == 'bool': formula = z3.Bool(varName) stack.append(self._abstraction(formula)) elif elemL[1] == 'real': formula = z3.Real(varName) stack.append(formula) elif elemL[1] == 'int': formula = z3.Int(varName) stack.append(formula) else: raise Exception( 'Unknown Variable format: {}'.format(elemL)) elif elemL[0] == 'const': const = elemL[2].replace(')', '') if elemL[1] == 'real': stack.append(z3.RealVal(const)) elif elemL[1] == 'int': stack.append(z3.IntVal(const)) else: raise Exception( 'Unknown Constant format: {}'.format(elemL)) else: raise Exception('Unknown format : {}'.format(elemL)) closedBrackets = elem.count(')') - 1 self._logger.writeToLog( "{} - new element in stack: {}\t,cB {}".format( pos, stack[-1], closedBrackets)) if closedBrackets < 1: continue while closedBrackets > 0: self._logger.writeToLog('{} - stack: {},{}'.format( pos, stack, closedBrackets)) tmpPredi = [] pred = None while True: pred = stack.pop() #if isinstance(pred,Predicate) or isinstance(pred,z3.BoolRef) or str(pred).replace('.','',1).isdigit(): #if z3.is_rational_value(pred) or z3.is_int_value(pred) or z3.is_int(pred) or z3.is_real(pred) or z3.is_bool(pred): if isinstance(pred, float) or isinstance( pred, int) or z3.is_int(pred) or z3.is_real( pred) or z3.is_bool(pred): tmpPredi.append(pred) else: if len(tmpPredi) == 1: tmpPredi = tmpPredi[0] else: tmpPredi = tmpPredi[::-1] break self._logger.writeToLog('{} - {} is applied to {}'.format( pos, pred, tmpPredi)) newElem = self._mapFunctionSymbol(pred)(tmpPredi) # newElemSimplified = z3.simplify(newElem) stack.append(newElem) self._logger.writeToLog( "{} - new element in stack: {}\t,cB {}".format( pos, stack[-1], closedBrackets)) closedBrackets -= 1 self._logger.writeToLog('{} - finished :{}:'.format( pos, stack)) except Exception as e: self._logger.writeToLog( "Some Error : {}\n\t Occured parsing formula: {}".format( e, string)) raise e if len(stack) != 1: raise Exception("Parsing Error, stack != 1") return self._recusiveSimplification(stack[0])
def _handleNum(state,left,right,op): # Match our object types leftZ3Object,rightZ3Object = z3Helpers.z3_matchLeftAndRight(left,right,op) # Figure out what the op is and add constraint if type(op) == ast.Add: if type(left) is BitVec: # Check for over and underflows state.solver.add(z3Helpers.bvadd_safe(leftZ3Object,rightZ3Object)) # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() + right.getValue() else: ret = leftZ3Object + rightZ3Object elif type(op) == ast.Sub: if type(left) is BitVec: state.solver.add(z3Helpers.bvsub_safe(leftZ3Object,rightZ3Object)) # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() - right.getValue() else: ret = leftZ3Object - rightZ3Object elif type(op) == ast.Mult: if type(left) is BitVec: state.solver.add(z3Helpers.bvmul_safe(leftZ3Object,rightZ3Object)) # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() * right.getValue() else: ret = leftZ3Object * rightZ3Object elif type(op) == ast.Div: if type(left) is BitVec: state.solver.add(z3Helpers.bvdiv_safe(leftZ3Object,rightZ3Object)) # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() / right.getValue() else: ret = leftZ3Object / rightZ3Object elif type(op) == ast.Mod: # Z3 doesn't have native support for Real type modular arithmetic if z3.is_real(leftZ3Object): constraint = [] if z3.is_real(rightZ3Object): mod = z3.Function('mod', z3.RealSort(),z3.RealSort(), z3.RealSort()) quot = z3.Function('quot', z3.RealSort(),z3.RealSort(), z3.RealSort()) constraint += [z3Helpers.isInt(rightZ3Object)] else: mod = z3.Function('mod', z3.RealSort(),z3.IntSort(), z3.RealSort()) quot = z3.Function('quot', z3.RealSort(),z3.IntSort(), z3.RealSort()) constraint.append(0 <= mod(leftZ3Object,rightZ3Object)) constraint.append(mod(leftZ3Object,rightZ3Object) < rightZ3Object) constraint.append(rightZ3Object * quot(leftZ3Object,rightZ3Object) + mod(leftZ3Object,rightZ3Object) == leftZ3Object) constraint.append(z3Helpers.isInt(quot(leftZ3Object,rightZ3Object))) constraint.append(z3Helpers.isInt(leftZ3Object)) constraint.append(leftZ3Object >= 0) state.addConstraint(z3.And(constraint)) """ state.addConstraint(0 <= mod(leftZ3Object,rightZ3Object)) state.addConstraint(mod(leftZ3Object,rightZ3Object) < rightZ3Object) state.addConstraint(rightZ3Object * quot(leftZ3Object,rightZ3Object) + mod(leftZ3Object,rightZ3Object) == leftZ3Object) state.addConstraint(z3Helpers.isInt(quot(leftZ3Object,rightZ3Object))) state.addConstraint(z3Helpers.isInt(leftZ3Object)) state.addConstraint(leftZ3Object >= 0) """ ret = mod(leftZ3Object,rightZ3Object) else: # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() % right.getValue() else: ret = leftZ3Object % rightZ3Object elif type(op) == ast.BitXor: # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() ^ right.getValue() else: ret = leftZ3Object ^ rightZ3Object elif type(op) == ast.BitOr: # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() | right.getValue() else: ret = leftZ3Object | rightZ3Object elif type(op) == ast.BitAnd: # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() & right.getValue() else: ret = leftZ3Object & rightZ3Object elif type(op) == ast.LShift: # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() << right.getValue() else: ret = leftZ3Object << rightZ3Object elif type(op) == ast.RShift: # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() >> right.getValue() else: ret = leftZ3Object >> rightZ3Object # TODO: This one will fail if we use BitVecs.. Maybe think about check/convert? elif type(op) == ast.Pow: # Keep this out of the Z3 solver! if left.isStatic() and right.isStatic(): ret = left.getValue() ** right.getValue() # Z3 has some problems with forms of x ** 0.5, let's try to change it for Z3... elif type(rightZ3Object) is z3.RatNumRef and rightZ3Object.numerator().as_long() == 1 and rightZ3Object.denominator().as_long() > 1: tmp = state.getVar("tempRootVar",ctx=1,varType=Real) tmp.increment() # Rewrite as x ** 2 == y form state.addConstraint(tmp.getZ3Object() ** float(rightZ3Object.denominator().as_long()) == leftZ3Object) # Because we're dealing with square, let's make sure it's positive state.addConstraint(tmp.getZ3Object() >= 0) ret = tmp.getZ3Object() else: ret = leftZ3Object ** rightZ3Object #ret = leftZ3Object ** rightZ3Object else: err = "BinOP: Don't know how to handle op type {0} at line {1} col {2}".format(type(op),op.lineno,op.col_offset) logger.error(err) raise Exception(err) # TODO: Clean up code below... # Duplicate the object and create a pyObjectManager object left_t,left_args = pyState.duplicateSort(leftZ3Object) right_t,right_args = pyState.duplicateSort(rightZ3Object) if left_t in [Int,Real,BitVec] and right_t in [Int, Real, BitVec]: # Not handling this case well right now if left_t is Real or right_t is Real: args = left_args if left_t is Real else right_args # We want variables, not constants args.pop("value",None) if args is not None else None retVar = state.getVar(varName='BinOpTemp',varType=Real,kwargs = args) else: left_args.pop("value",None) if left_args is not None else None retVar = state.getVar(varName='BinOpTemp',varType=left_t,kwargs = left_args) retVar.increment() # Now that we have a clean variable to return, add constraints and return it logger.debug("Adding constraint {0} == {1}".format(retVar.getZ3Object(),ret)) # If it turns out we're dealing with constants, just set it directly. if type(ret) in [int,float]: retVar.setTo(ret) else: state.addConstraint(retVar.getZ3Object() == ret) #print([x for x in state.solver.assertions()]) return [retVar.copy()] else: err = "BinOP: Don't know how to handle variable type {0} at line {1} col {2}".format(t,op.lineno,op.col_offset) logger.error(err) raise Exception(err)
def check_value(self, val): assert val is not None, f"Setting a port's value to None is not allowed" # check that we only assign correct values to the ports if isinstance(self.domain, list): return val in self.domain elif self.domain is Types.INTEGER: return isinstance(val, int) or z3.is_int_value(val) or z3.is_int(val) elif self.domain is Types.REAL: # z3 types return (isinstance(val, numbers.Number) and not isinstance(val, bool)) or z3.is_real(val) elif self.domain is Types.INT: # TODO: check also for these types return isinstance(val, int) elif self.domain is Types.FLOAT: # TODO: check also for these types return (isinstance(val, numbers.Number) and not isinstance(val, bool)) elif self.domain is Types.STRING: # TODO: check also for these types return isinstance(val, str) elif self.domain is Types.BOOL: # TODO: check also for these types return isinstance(val, bool) else: return False