def test_sub(self) -> None: self.assertEqual( Sub(Number(6), Number(4)).z3expr(), z3.IntVal(6) - z3.IntVal(4)) self.assertEqual( Sub(Number(12), Number(20)).z3expr(), z3.IntVal(12) - z3.IntVal(20))
def basic_constraints(self): """ Returns a list of constraints representing basic facts about the possible game states """ return [ # Number of impostors is number of impostors self.n_impostors == sumbools(self.impostor) # A number of impostors can be alive , self.n_alive_impostors == sumbools( z3.And(self.alive[i], self.impostor[i]) for i in range(self.n_players)) # People that were murdered cannot be impostors , *[ z3.Implies(self.murdered[i], z3.Not(self.impostor[i])) for i in range(self.n_players) ] # Alive people have not been murdered and have not been ejected , *[ z3.And(z3.Not(self.murdered[i]), z3.Not(self.ejected[i])) == self.alive[i] for i in range(self.n_players) ] # There is at least one not-dead impostor , self.n_alive_impostors > z3.IntVal(0) # Twice the number of alive impostors is less than the number of alive crewmates , sumbools(self.alive) > (self.n_alive_impostors * z3.IntVal(2)) ]
def recover_value(value, uct_sort): """ Inverse of _extract_value. Given a pythonic value, returns a z3 embedding of it depending on its uct sort. The explicit embedding scheme is as follows: fgsort -> z3.ArithRef fgsetsort -> z3.ArrayRef intsort -> z3.ArithRef intsetsort -> z3.ArrayRef boolsort -> z3.BoolRef :param value: any :param uct_sort: naturalproofs.uct.UCTSort :return: z3.ExprRef """ # TODO: typecheck all the arguments if uct_sort in {fgsort, intsort}: return z3.IntVal(value) elif uct_sort == boolsort: return z3.BoolVal(value) elif uct_sort in {fgsetsort, intsetsort}: expr = z3.EmptySet(z3.IntSort()) for elem in value: expr = z3.SetAdd(expr, z3.IntVal(elem)) else: raise ValueError( 'Sort not supported. Check for a list of available sorts in the naturalproofs.uct module.' )
def test_mul(self) -> None: self.assertEqual( Mul(Number(6), Number(4)).z3expr(), z3.IntVal(6) * z3.IntVal(4)) self.assertEqual( Mul(Number(2), Number(4), Number(8)).z3expr(), z3.IntVal(2) * z3.IntVal(4) * z3.IntVal(8), )
def test_case() -> None: assert_equal( Case(Variable("x"), [(Number(5), Number(1)), (Number(10), Number(2))]).z3expr(), z3.If( z3.Int("x") == z3.IntVal(5), z3.IntVal(1), z3.If(z3.Int("x") == z3.IntVal(10), z3.IntVal(2), z3.BoolVal(False)), ), )
def rename(self, srcname, dstname): oldstate = self src_ino = oldstate.fname_inode(srcname) srcexists = src_ino != z3.IntVal(0) dst_ino = oldstate.fname_inode(dstname) dstexists = dst_ino != z3.IntVal(0) return If( z3.Not(srcexists), Result(z3.IntVal(-1), oldstate), If( srcname == dstname, Result(z3.IntVal(0), oldstate), If( dstexists, Result( z3.IntVal(0), oldstate.write_nlink( dst_ino, self.inode_nlink(dst_ino) - z3.IntVal(1)).write_dir(dstname, src_ino).write_dir( srcname, z3.IntVal(0))), Result( z3.IntVal(0), oldstate.write_dir(dstname, src_ino).write_dir( srcname, z3.IntVal(0))))))
def generate(): for i, j in itertools.combinations(self.slots, 2): ii, jj = z3.IntVal(i.id), z3.IntVal(j.id) if fn(i, j): yield z3fn(ii, jj) yield z3fn(jj, ii) else: yield z3.Not(z3fn(ii, jj)) yield z3.Not(z3fn(jj, ii)) for i in self.slots: ii = z3.IntVal(i.id) yield z3fn(ii, ii)
def z3ify_time_constraint(name: str, fn): constraints = [] z3fn = z3.Function(name, z3.IntSort(), z3.IntSort(), z3.BoolSort()) for i, j in itertools.combinations(ALL_SLOTS, 2): ii, jj = z3.IntVal(i.id), z3.IntVal(j.id) if fn(i, j): constraints += [z3fn(ii, jj), z3fn(jj, ii)] else: constraints += [z3.Not(z3fn(ii, jj)), z3.Not(z3fn(jj, ii))] for i in ALL_SLOTS: ii = z3.IntVal(i.id) constraints += [z3fn(ii, ii)] return z3fn, constraints
def test_if() -> None: assert_equal( If( [ (Greater(Variable("a"), Number(5)), Number(1)), (Greater(Variable("b"), Number(100)), Number(10)), ], Number(100), ).z3expr(), z3.If( z3.Int("a") > z3.IntVal(5), z3.IntVal(1), z3.If(z3.Int("b") > z3.IntVal(100), z3.IntVal(10), z3.IntVal(100)), ), )
def get_pred(self): if self.is_ninf(): return copy.deepcopy(self) if self.is_pzero(): return Float('-0',ne=self.ne,ns=self.ns).get_pred() bv_str = self.get_bv_str() #print(bv_str) sign = bv_str[0] if sign == '0': succ = int(bv_str[1:],2) - 1 return Float(val=z3.simplify(z3.fpBVToFP(z3.Int2BV(z3.IntVal(succ),num_bits = self.ns + self.ne),z3.FPSort(self.ne,self.ns))),ne=self.ne, ns=self.ns) else: succ = int(bv_str[1:],2) + 1 return -Float(val=z3.simplify(z3.fpBVToFP(z3.Int2BV(z3.IntVal(succ),num_bits = self.ns + self.ne),z3.FPSort(self.ne,self.ns))),ne=self.ne, ns=self.ns)
def solve(s1, s2, s3): global vars vars = dict() list1 = list(s1) #list=[s,e,n,d] list2 = list(s2) list3 = list(s3) #initial list in z3 for i in list1: mk_var(i) for i in list2: mk_var(i) for i in list3: mk_var(i) #equation lhs1 = reduce(lambda a, b: 10 * a + vars[b], list1, 0) lhs2 = reduce(lambda a, b: 10 * a + vars[b], list2, 0) rhs1 = reduce(lambda a, b: 10 * a + vars[b], list3, 0) solver = z3.Solver() #distinct solver.add(z3.Distinct(get_vars())) #equation solver.add(lhs1 + lhs2 == rhs1) solver.add(vars[list1[0]] != 0) solver.add(vars[list2[0]] != 0) solver.add(vars[list3[0]] != 0) #digital range for x in vars: solver.add(vars[x] >= z3.IntVal(0)) solver.add(vars[x] <= z3.IntVal(9)) res = solver.check() if res == z3.sat: model = solver.model() result = [] result.append( int(reduce(lambda a, b: "%s%s" % (a, model[vars[b]]), list1, ''))) result.append( int(reduce(lambda a, b: "%s%s" % (a, model[vars[b]]), list2, ''))) result.append( int(reduce(lambda a, b: "%s%s" % (a, model[vars[b]]), list3, ''))) return result else: return None
def from_symmetries2programs(self, model, m_aux): for t in range(len(self.typeVars) - 1): k = self.typeVars[t] m_aux[k] = self.model[k] # NEW root_num = t + 1 type = int(str(self.model[k])) new_node = int(str(model[z3.Int('x_' + str(root_num))])) old_prod = self.line_productions[root_num - 1][type].id new_prod = self.line_productions[new_node - 1][type].id start = root_num * self.max_children for i in range(start, len(self.leafs)): n = self.leafs[i] if self.model[n.var] == old_prod: m_aux[n.var] = z3.IntVal(new_prod) break m_aux[self.typeVars[-1]] = self.model[self.typeVars[-1]] n_model = dict(m_aux) for v in model: var, new_node_pos = v, int(str(model[v])) node_pos = int(str(var).split("_")[1]) n_model[self.roots[new_node_pos - 1].var] = self.model[self.roots[node_pos - 1].var] self.change_node(node_pos, new_node_pos, n_model, m_aux) n_model[self.roots[-1].var] = self.model[self.roots[-1].var] self.change_node(0, 0, n_model, m_aux) return n_model
def incidence_sums(petrinet, variables, subnet_transitions="all", reverse=False): if subnet_transitions == "all": subnet_transitions = set(range(petrinet.num_transitions)) sums = [] for p in range(petrinet.num_places()): nonzero = petrinet.transitions_set({p}, reverse) incidence_row = [(petrinet.get_post(p, t) - petrinet.get_pre(p, t), variables[t]) for t in nonzero if t in subnet_transitions] sum_elements = [ expression(coeff, var) for coeff, var in incidence_row if coeff != 0 ] curr_sum = z3.Sum( sum_elements) if len(sum_elements) > 0 else z3.IntVal(0) sums.append(curr_sum) return sums
def pyval2z3val(val): if type(val) is float: return z3.RealVal(val) elif type(val) is int: return z3.IntVal(val) else: raise err.Fatal('unhandled python val type!')
def translate(self, term): """Translate a Maude term into an SMT formula""" symbol = term.symbol() # Variable if str(symbol) == str(term.getSort()): return smt.Const(str(term), self._smt_sort(term.getSort())) # Integer constant elif symbol == self.intlit_symb: return smt.IntVal(int(term)) # Real constant elif symbol == self.reallit_symb: return smt.RealVal(float(term)) # Other symbols else: symb = self.ops_table.get(symbol) # If the symbol is not in the table, it may be a # polymorph for a custom type... if symb is None: symb = self._make_polymorph(symbol) # ...or an uninterpreted function if symb is None: symb = self._make_function(symbol) return symb(*[self.translate(arg) for arg in term.arguments()])
def bv_value_to_int_value(bv_value, bv_type, force_big_endian=False): if bv_type == "intle:32" and not force_big_endian: f = [ x for x in bitstring.BitArray(uint=bv_value.as_long(), length=32).cut(8) ] return z3.IntVal( bitstring.pack('int:8, int:8, int:8, int:8', f[3].int, f[2].int, f[1].int, f[0].int).int) elif bv_type == "intbe:32" or (bv_type == "intle:32" and force_big_endian): return z3.IntVal(bv_value.as_signed_long()) elif bv_type == "uintbe:32" or (bv_type == "uintle:32" and force_big_endian): return z3.IntVal(bv_value.as_long()) else: raise NotImplementedError("unrecognized type: " + bv_type)
def _create_union_constraints(self): """ Prevent union of twice the same subtree: (A|B) """ for node in self.nodes: if node.children is None or len(node.children) == 0: continue test2 = node.children[0].children is None or len( node.children[0].children) == 0 test3 = node.children[1].children is None or len( node.children[1].children) == 0 if test2 or test3: continue node_var = self.variables[node] if self.dsl.get_function_production("union") is None: return union_id = self.dsl.get_function_production("union").id node_is_union = node_var == z3.IntVal(union_id) subtree0, subtree1 = node.children[0].get_subtree(), \ node.children[1].get_subtree() bigOr = [] for i in range(len(subtree0)): var_i0 = self.variables[subtree0[i]] var_i1 = self.variables[subtree1[i]] bigOr.append(var_i0 != var_i1) self.z3_solver.add(z3.Implies(node_is_union, z3.Or(bigOr)))
def get_transaction_info(test): env_translate = dict(currentCoinbase='coinbase', currentDifficulty='difficulty', currentGasLimit='gaslimit', currentNumber='number', currentTimestamp='timestamp') tstate = {} for k, v in test['env'].items(): tstate[env_translate[k]] = z3.BitVecVal(int(v, 0), 256) exec_translate = dict(gasPrice='gasprice', value='callvalue', caller='caller', gas='initial_gas') for k, v in test['exec'].items(): if k in exec_translate: if k == 'gas': v = z3.IntVal(int(v, 0)) else: v = z3.BitVecVal(int(v, 0), 256) tstate[exec_translate[k]] = v code = symevm.code.Code(test['exec']['code']) tstate['calldata'], tstate['calldatasize'] = mem_from_str( test['exec']['data']) return code, tstate
def z3_val(val, ctx): if isinstance(val, int): return z3.IntVal(val, ctx) elif isinstance(val, str): return z3.StringVal(val, ctx) else: raise ValueError(f'z3_val: unsupported typ ({type(val)})')
def _py2expr(a, ctx=None): if isinstance(a, bool): return z3.BoolVal(a, ctx) if isinstance(a, int): return z3.IntVal(a, ctx) if isinstance(a, float): return z3.RealVal(a, ctx)
def generate(): for i in self.slots: ii = z3.IntVal(i.id) if fn(i): yield z3fn(ii) else: yield z3.Not(z3fn(ii))
def get_model_constraint(self): block = [] for x in self.variables: block.append(x != z3.Int('val_' + str(x))) self.modelConstraint = z3.Or(block) for m in self.model: self.cleanedModel[m()] = z3.IntVal(0)
def enum(self, t): res = term_to_z3(t) if isinstance(t, Constant) and t.rep not in self.numbering: num = z3.IntVal(self.next_number) self.next_number += 1 self.numbering[t.rep] = num cnst = self.enum_func(res) == num self.temp_solver.add(cnst) return res
def visit_IntConst(self, node, *args, **kwargs): #print ("visiting int_const") #print ("node.val=", node.val, "type(node.val)=", type(node.val)) #if type(node.val)!=int: # print ("wtf...") # return node.val #else: # print ("a classic int") return z3.IntVal(node.val)
def get_z3_val(valtype, value, name, datatype_name=None, ctx=None): val = None if isinstance(valtype, z3.z3.DatatypeSortRef): # discrete values datatype val = getattr(valtype, value) elif valtype is Types.INT: try: val = z3.BitVecVal(value, 32, ctx=ctx) except Exception as exc: raise ValueError( f"Error during INT conversion. Cannot convert value: {value}, type: {type(value)}, name: {name}" ) elif valtype is Types.INTEGER: try: val = z3.IntVal(value, ctx=ctx) except Exception as exc: raise ValueError( f"Error during INTEGER conversion. Cannot convert value: {value}, type: {type(value)}, name: {name}" ) elif valtype is Types.FLOAT: try: val = z3.FPVal(value, z3.Float32(), ctx=ctx) except Exception as exc: raise ValueError( f"Error during FLOAT conversion. Cannot convert value: {value}, type: {type(value)}, name: {name}" ) elif valtype is Types.REAL: try: val = z3.RealVal(value, ctx=ctx) except Exception as exc: raise ValueError( f"Error during REAL conversion. Cannot convert value: {value}, type: {type(value)}, name: {name}" ) elif valtype is Types.BOOL: try: val = z3.BoolVal(value, ctx=ctx) except Exception as exc: raise ValueError( f"Error during BOOL conversion of value to INT. value: {value}, type: {type(value)}, name: {name}" ) elif valtype is Types.STRING: try: val = z3.StringVal(value, ctx=ctx) except Exception as exc: raise ValueError( f"Error during STRING conversion of value to INT. value: {value}, type: {type(value)}, name: {name}" ) elif isinstance(valtype, list): datatype = _get_datatype_from_list(valtype, datatype_name) val = getattr(datatype, value) valtype = datatype else: raise ValueError( f"I do not know how to create a z3-value for type {valtype}") assert val is not None, f"Value wasn't converted: valtype: {valtype}, value: {value}, name: {name}" val.type = valtype return val
def expression(coeff, var): if coeff == 1: return var elif coeff == -1: return -var elif coeff != 0: return coeff * var else: return z3.IntVal(0)
def test_add(self) -> None: self.assertEqual( Add(Number(42), Number(1)).z3expr(), z3.IntVal(0) + z3.IntVal(42) + z3.IntVal(1)) self.assertEqual( Add(Number(42), Number(1), Number(10)).z3expr(), z3.IntVal(0) + z3.IntVal(42) + z3.IntVal(1) + z3.IntVal(10), )
def _resolve_char_must_occur_predicate(self, pred): self._check_arg_types(pred, [Node, int]) program = pred.args[0] big_or = [] for node in self.nodes_until_depth(self.depth - program.depth() + 1): big_or.append( self.variables[node] == z3.IntVal(program.production.id)) self.z3_solver.add(z3.Or(big_or))
def getZ3ValFromJSVal(val): if type(val) == str: return z3.StringVal(val) if type(val) == bool: return z3.BoolVal(val) if type(val) == int: return z3.IntVal(val) if type(val) == int: return z3.IntVal(val) if type(val) == list: arr = z3.Array('ignore_helper_constant_array_' + randomString(), z3.IntSort(), z3.StringSort()) for i, arg in enumerate(val): GLOBAL_CONSTRAINTS.append(z3.Select(arr, i) == createZ3ExpressionFromConstraint(arg, {})) ARRAY_LENGTHS[str(arr.decl())] = len(val) return arr if type(val) == dict: raise NotSupportedException('Complex Objects as base for operations with proxy strings are not yet supported!') raise Exception('Could not transform Js val to Z3 Val' + repr(val))
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