def verify_solution(ez, X_star,symbolTable,printModel=False): assert isinstance(symbolTable, collections.OrderedDict) assert isinstance(ez, z3.ExprRef) assert len(symbolTable)==X_star.size model=[] # (sympy.Symbol('x'), for (s,val) in zip(symbolTable.items(), X_star): var, sort = s[0],s[1] var=rename_var(var) # if ("!" in varr) or ("@" in var): # symVar="x_"+str(expr_z3.hash()) STOP HERE if sort == Sort.Float32: var_z3=z3.FP(str(var),z3.Float32()) val_z3=z3.FPVal(val,z3.Float32()) elif sort == Sort.Float64: var_z3=z3.FP(str(var),z3.Float64()) val_z3=z3.FPVal(val,z3.Float64()) else: raise NotImplementedError("Unexpected type %s" %sort) model.append((var_z3,val_z3)) if printModel: print "model: " print model ##Nice for debugging. #print "p"*90 #print z3.substitute(ez, *model) return _is_true(z3.simplify(z3.substitute(ez, *model)))
def gen_symbolic_value(var_type, name): if var_type == bin_format.i32: return z3.BitVec(name, 32) if var_type == bin_format.i64: return z3.BitVec(name, 64) if var_type == bin_format.f32: return z3.FP(f'f32_{i}', z3.Float32()) if var_type == bin_format.f64: return z3.FP(name, z3.Float64()) raise TypeError('Unsupported variable type')
def get_z3_var(vartype, name, datatype_name=None, ctx=None): var = None if isinstance(vartype, z3.z3.DatatypeSortRef): # discrete values datatype var = z3.Const(name, vartype) elif vartype is Types.INT: var = z3.BitVec(name, 32, ctx=ctx) elif vartype is Types.INTEGER: var = z3.Int(name, ctx=ctx) elif vartype is Types.FLOAT: var = z3.FP(name, z3.Float32(), ctx=ctx) elif vartype is Types.REAL: var = z3.Real(name, ctx=ctx) elif vartype is Types.BOOL: var = z3.Bool(name, ctx=ctx) elif vartype is Types.STRING: var = z3.String(name, ctx=ctx) elif isinstance(vartype, list): datatype = _get_datatype_from_list(vartype, datatype_name) var = z3.Const(name, datatype) vartype = datatype else: raise ValueError( f"I do not know how to create a z3-variable for type {vartype} (name: {name})" ) assert var is not None, f"Var wasn't converted: vartype: {vartype}, name: {name}" var.type = vartype return var
def gen_symbolic_args(func: 'instance.FunctionInstance'): symbolic_params = [] for i, e in enumerate(func.functype.args): if e == bin_format.i32: symbolic_params.append(z3.BitVec(f'i32_bv_{i}', 32)) elif e == bin_format.i64: symbolic_params.append(z3.BitVec(f'i64_bv_{i}', 64)) elif e == bin_format.f32: # f32_bv = z3.BitVec(f'f32_bv_{i}', 32) # symbolic_params.append(z3.fpBVToFP(f32_bv, z3.Float32())) # another approach symbolic_params.append(z3.FP(f'f32_{i}', z3.Float32())) else: # f64_bv = z3.BitVec(f'f64_bv_{i}', 64) # symbolic_params.append(z3.fpBVToFP(f64_bv, z3.Float64())) # another approach symbolic_params.append(z3.FP(f'f64_{i}', z3.Float64())) return symbolic_params
def do_I2F(op, stack, state): val, = pop_values(stack, state) if z3.is_bv_value(val): fp = z3.FPVal(val.as_long(), FSIZE) else: fp = z3.FP("fp%d" % float_data["count"], FSIZE) state.solver.add(z3.fpToUBV(FPM, fp, z3.BitVecSort(SIZE)) == val) float_data["count"] += 1 stack.append(fp)
def gen_symbolic_args(func: 'instance.FunctionInstance'): symbolic_params = list() for i, e in enumerate(func.functype.args): if e == bin_format.i32: symbolic_params.append(z3.BitVec(f'i32_bv_{i}', 32)) elif e == bin_format.i64: symbolic_params.append(z3.BitVec(f'i64_bv_{i}', 64)) elif e == bin_format.f32: # The first approach is bit-vector based # f32_bv = z3.BitVec(f'f32_bv_{i}', 32) # symbolic_params.append(z3.fpBVToFP(f32_bv, z3.Float32())) # The second approach is float-point based symbolic_params.append(z3.FP(f'f32_{i}', z3.Float32())) else: # The first approach is bit-vector based # f64_bv = z3.BitVec(f'f64_bv_{i}', 64) # symbolic_params.append(z3.fpBVToFP(f64_bv, z3.Float64())) # The second approach is float-point based symbolic_params.append(z3.FP(f'f64_{i}', z3.Float64())) return symbolic_params
def verify_solution(ez, X_star, symbolTable, printModel=False): assert isinstance(symbolTable, collections.OrderedDict) assert isinstance(ez, z3.ExprRef) assert isinstance(res, op.OptimizeResult) assert len(symbolTable) == X_star.size model = [] # (sympy.Symbol('x'), for (s, val) in zip(symbolTable.items(), X_star): var, sort = s[0], s[1] if sort == Sort.Float32: var_z3 = z3.FP(str(var), z3.Float32()) val_z3 = z3.FPVal(val, z3.Float32()) elif sort == Sort.Float64: var_z3 = z3.FP(str(var), z3.Float64()) val_z3 = z3.FPVal(val, z3.Float64()) else: raise NotImplementedError("Unexpected type %s" % sort) model.append((var_z3, val_z3)) if printModel: print "model: " print model return _is_true(z3.simplify(z3.substitute(ez, *model)))
def makeZ3Var(v): t = v.varType name = v.varName if t.startswith('INSTANCE:'): s = t[9:] if s == 'BYTE': return z3.Array(name, BitVecSort(32), z3.BitVecSort(8)) elif s == 'SHORT': return z3.Array(name, BitVecSort(32), z3.BitVecSort(16)) elif s == 'INT': return z3.Array(name, BitVecSort(32), z3.BitVecSort(32)) elif s == 'LONG': return z3.Array(name, BitVecSort(32), z3.BitVecSort(64)) elif s == 'FLOAT': return z3.Array(name, BitVecSort(32), Float) elif s == 'DOUBLE': return z3.Array(name, BitVecSort(32), Double) elif s == 'CHAR': return z3.Array(name, BitVecSort(32), z3.BitVecSort(16)) else: raise Exception("unsupported type {}".format(t)) elif t == 'BYTE': return z3.BitVec(name, 8) elif t == 'SHORT': return z3.BitVec(name, 16) elif t == 'INT': return z3.BitVec(name, 32) elif t == 'LONG': return z3.BitVec(name, 64) elif t == 'FLOAT': return z3.FP(name, Float) elif t == 'DOUBLE': return z3.FP(name, Double) elif t == 'CHAR': return z3.BitVec(name, 16) else: raise Exception("unsupported type {}".format(t))
def FPS(self, ast): #pylint:disable=unused-argument name, sort_claripy = ast.args sort_z3 = self._convert(sort_claripy) return z3.FP(name, sort_z3, ctx=self._context)
(A*C) + (B*C) == (A+B) * C (computed with rounding mode rm). Informally, this means that the equivalence holds for powers of 2 C, modulo flushing to zero or inf, and modulo rounding of intermediate results. Requires z3 python bindings; try `pip install z3-solver`. """ import z3 # We do float16 because it lets the solver run much faster. These results # should generalize to fp32 and fp64, and you can verify this by changing the # value of FLOAT_TY (and then waiting a while). FLOAT_TY = z3.Float16 a = z3.FP("a", FLOAT_TY()) b = z3.FP("b", FLOAT_TY()) c = z3.FP("c", FLOAT_TY()) s = z3.Solver() # C must be a power of 2, i.e. significand bits must all be 0. s.add(z3.Extract(FLOAT_TY().sbits() - 1, 0, z3.fpToIEEEBV(c)) == 0) for rm in [z3.RTZ(), z3.RNE()]: z3.set_default_rounding_mode(rm) before = a * c + b * c after = (a + b) * c # Check that before == after, allowing that 0 == -0. s.add(
def FPS(self, ast): sort_z3 = self._convert(ast.args[1]) return z3.FP(ast._encoded_name, sort_z3, ctx=self._context)
def generateFiniteLenFloats(name, count, tp, ctx): tp = np.dtype(tp) fpSort = floatTypes[tp.itemsize] if isinstance(fpSort, tuple): fpSort = z3.FPSort(*fpSort) return [z3.FP(name + "__" + str(i), fpSort) for i in range(count)]