def direct_check(weights, biases, perm, input_cond_hook): """ Given a dnn via a list of `weights` and `biases`, and a permutation `perm`, check using a single z3 call if the DNN is invariant under the permutation of inputs. `perm` is a list where each element represent where that element goes to under the permutation. If invariance holds, returns True, else returns False and a counterexample. `input_cond_hook` is a function that enforces the constraints on the input by taking the z3 variables corresponding to the inputs, and a solver and adds constraints corresponding to the inputs to the solver, arguments: (z3_vars, solver) """ z3_vars = [z3.Real('v_%d' % i) for i in range(len(perm))] z3_vars_perm = [z3.Real('p_v_%d' % i) for i in range(len(perm))] solver = z3.Solver() solver.add(encode_perm_props.encode_perm(z3_vars, z3_vars_perm, perm)) solver.add( z3.Not( encode_dnn.encode_network(weights, biases, z3_vars) == encode_dnn.encode_network(weights, biases, z3_vars_perm))) input_cond_hook(z3_vars, solver) if solver.check() == z3.unsat: return (True, []) else: mdl = solver.model() return (False, ([mdl.eval(z3.Real('v_%d' % i)) for i in range(len(perm))], [mdl.eval(z3.Real('p_v_%d' % i)) for i in range(len(perm))]))
def __init__(self, left_space, right_space, is_affine): """ Construct to pull back the `right_space`. Bool `is_affine` states if the given space represents an affine space, in which case the returned points will always have the last coordinate 1. """ assert(len(left_space[0]) == len(right_space[0])) # Fields self.affine = is_affine self.r_space = right_space[:] self.l_space = left_space[:] self.rd = len(right_space) self.ld = len(left_space) self.n = len(right_space[0]) self.rr = min(self.rd, pb_nbasis_r) self.lr = min(self.ld, pb_nbasis_l) self.k = (factorial(self.rd) // (factorial(self.rr) * factorial(self.rd-self.rr))) * \ (factorial(self.ld) // (factorial(self.lr) * factorial(self.ld-self.lr))) # Set up solver self.solver = z3.SolverFor("LRA") self.z3_rc = [ z3.Real('rc_%d'%i) for i in range(self.rd) ] # Coefficients in right_space self.z3_lc = [ z3.Real('lc_%d'%i) for i in range(self.ld) ] # Coefficients in left # Set up combination iterator self.subb_cmb = itr.product(itr.combinations(zip(self.z3_lc, self.l_space), self.lr), itr.combinations(zip(self.z3_rc, self.r_space), self.rr)) self.sbn = 0 # Number of queries we have done. By this, we signal that we have not done any queries yet self.qn = pb_nqueries
def symbolic_states(self): try: return self._symbolic_states except AttributeError: ss = [] prev_nodes = self.symbolic_inps for lid, layer in enumerate(self.model.layers): weights, biases = layer.get_weights() vs = np.array([prev_nodes]).dot(weights) + biases vs = vs[0] nnodes = layer.output_shape[1] # number of nodes in layer assert nnodes == len(vs) activation = layer.get_config()['activation'] cur_nodes = [] for i in range(nnodes): v = vs[i] if activation == 'relu': v = z3.If(0 >= v, 0, v) v = z3.simplify(v) if lid < self.nlayers - 1: node = z3.Real(f"n{lid}_{i}") else: node = z3.Real(f"o{i}") cur_nodes.append(node) ss.append(node == v) prev_nodes = cur_nodes f = z3.simplify(z3.And(ss)) self._symbolic_states = f return f
def label(boundary, should_invert=False, param_boundaries=[[0.0, 20.0], [0, 1.0]], epsilon=0.01, num_points=200, lipschitz_param=0.05): """ Takes a boundary, and returns its proper label, which is True or False. Correct implementation will depend on context, and in the extreme case will require computation done by the human. """ # TODO: add type assertions if should_invert: my_boundary = utils.invert(boundary, param_boundaries) else: my_boundary = boundary # print("endpoints of labelled boundary:", [my_boundary[0], my_boundary[-1]]) utils.plot(my_boundary, 'tab:orange', param_boundaries) print("in the label function") # print("in the label function, should_invert is", should_invert) # print("boundary that label is synthesising", my_boundary) # print(num_points) xs = [z3.Real('x%d' % i) for i in range(num_points)] us = [z3.Real('u%d' % i) for i in range(num_points)] def make_phi(xs, us): # this basically makes a formula encoding dynamics of a system xs # controlled by us formula = True for i in range(num_points - 1): formula = z3.And(formula, xs[i+1] == xs[i] + us[i], # xs[i+1] - xs[i] <= lipschitz_param, # xs[i] - xs[i+1] <= lipschitz_param, xs[i] >= 0, xs[i+1] >= 0, xs[i] <= 1, xs[i+1] <= 1) return formula trace = bt.trace(my_boundary, epsilon, num_points, xs, param_boundaries[0][1], make_phi(xs, us)) # print("trace that is being labelled is", trace) utils.plot(trace, 'b-', param_boundaries) # in this labelling function, we demand that the trace's velocity be below # the lines connecting the points (0,1), (8, 0.9), (14, 0.6), (20, 0.2), # i.e. those points should be the polygon that the boundary has to be below below_top = True for point in trace: if point[0] <= 8: below_top = below_top and (point[1] <= point[0]/(-80.0) + 1.0) if point[0] <= 14 and point[0] >= 8: below_top = below_top and (point[1] <= point[0]/(-20.0) + 13.0/10) if point[0] >= 14: below_top = below_top and (point[1] <= point[0]/(-15.0) + 23.0/15) # print("below top?", below_top) return below_top
def inputSpaceVariables(): # see the function _state_to_relative in ./envs/circle_env.py , line 113. return [ z3.Real("inputDx"), z3.Real("inputTheta"), z3.Real("inputDxDot"), z3.Real("inputThetaDot") ]
def find_max_satisfiable_rule(self): """ Build a model that satisfies as many soft clauses as possible using MAX-SMT """ self.threshold_open = z3.Real('t') self.threshold_listen = z3.Real('u') t = self.threshold_open u = self.threshold_listen self.solver.add(0.0 < t) self.solver.add(t <= 1.0) self.solver.add(0.0 < u) self.solver.add(u <= 1.0) for run in range(len(self.belief_in_runs)): for bel, belief in enumerate(self.belief_in_runs[run]): soft = z3.Bool('b_{}_{}'.format(run, bel)) self.soft_constr_open.append(DummyVar(soft, run, bel, 1)) formula = z3.If(belief[0] > belief[1], belief[0] >= t, belief[1] >= t) if self.actions_in_runs[run][bel] != 0 : self.solver.add(z3.Or(soft, formula)) else: self.solver.add(z3.Or(soft, z3.Not(formula))) soft = z3.Bool('c_{}_{}'.format(run, bel)) self.soft_constr_listen.append(DummyVar(soft, run, bel, 2)) formula = z3.If(belief[0] > belief[1], belief[0] <= u, belief[1] <= u) if self.actions_in_runs[run][bel] == 0 : self.solver.add(z3.Or(soft, formula)) else: self.solver.add(z3.Or(soft, z3.Not(formula))) self.solver.add(self.threshold_open > 0.9) low_threshold = 0 total_soft_constr = len(self.soft_constr_open) + len(self.soft_constr_listen) high_threshold = len(self.soft_constr_open) + len(self.soft_constr_listen) final_threshold = -1 best_model = [] while low_threshold <= high_threshold: self.solver.push() threshold = (low_threshold + high_threshold) // 2 self.solver.add(z3.PbLe([(soft.literal, 1) for soft in (self.soft_constr_open+self.soft_constr_listen)], threshold)) result = self.solver.check() if result == z3.sat: final_threshold = threshold best_model = self.solver.model() high_threshold = threshold - 1 else: low_threshold = threshold + 1 self.solver.pop() return best_model
def z3_problem(constraints, solver: z3.Solver): for con in constraints: break n = con.n x = np.array([z3.Real('x_%s' % (i + 1)) for i in range(n)]) x = sympy.Matrix([z3.Real('x_%s' % (i + 1)) for i in range(n)]) for con in constraints: solver.add(con.z3_expression(x)) return x, solver
def mk_vars(num_dims, num_comments, num_voters, ctx=None): """Creates and returns variables for the comments and the voters.""" com_vars = [[ z3.Real('x_%d_%d' % (ii, jj), ctx=ctx) for jj in range(num_dims) ] for ii in range(num_comments)] voter_vars = [[ z3.Real('v_%d_%d' % (ii, jj), ctx=ctx) for jj in range(num_dims) ] for ii in range(num_voters)] return com_vars, voter_vars
def __parse_by_name__(self, name: str, data_type: jcbase.CType): """ :param name: :param data_type: :return: it creates a z3-sexpr by using name and data-type to create refereces """ if data_type is None: return self.__new_bool_ref__(name) elif (data_type.get_key() == "bool") or (data_type.get_key() == "void"): return self.__new_bool_ref__(name) elif (data_type.get_key() == "char") or (data_type.get_key() == "uchar"): return self.__new_char_ref__(name) elif (data_type.get_key() == "short") or (data_type.get_key() == "ushort"): return self.__new_short_ref__(name, data_type.get_key() == "ushort") elif (data_type.get_key() == "int") or (data_type.get_key() == "uint"): return self.__new_int_ref__(name, data_type.get_key() == "uint") elif (data_type.get_key() == "long") or (data_type.get_key() == "ulong"): return self.__new_long_ref__(name, data_type.get_key() == "ulong") elif (data_type.get_key() == "llong") or (data_type.get_key() == "ullong"): return self.__new_long_ref__(name, data_type.get_key() == "ullong") elif (data_type.get_key() == "float") or (data_type.get_key() == "double") or (data_type.get_key() == "ldouble"): return z3.Real(name) elif (data_type.get_key() == "float_x") or (data_type.get_key() == "double_x") or (data_type.get_key() == "ldouble_x"): return self.__new_complex_ref__(name) elif (data_type.get_key() == "float_i") or (data_type.get_key() == "double_i") or (data_type.get_key() == "ldouble_i"): return z3.Real(name) elif (data_type.get_key() == "array") or (data_type.get_key() == "point"): return self.__new_address_ref__(name) elif data_type.get_key() == "function": return z3.Function(name) else: return self.__new_otherwise_ref__(name)
def create_z3_var(name, type): if type[1] == "Int": return z3.Int(name) elif type[1] == "Float": return z3.Real(name) else: raise NotImplementedError
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 check_infinite_loop(self, n, cond, prime,tr=True): #print("check infinite loop") #x = [z3.Real('xr_%s' % i) for i in range(n)] x = [z3.Real('xr_%s' % i) if tr else z3.Int('xi_%s' % i) for i in range(n)] #print(x) # xp = [z3.Real('xrp_%s' % i) for i in range(n)] x_ = prime(x) #print(x_) a = cond(x) s = z3.Solver() s.add(cond(x)) # condition s.push() for i in range(n): s.add(x[i] == x_[i]) #s.add(x = x_) s.push() #print('constraint system: ', s) result = s.check() if result == z3.sat: #print('found one infinite loop: ') m = s.model() model = [str(v)+"="+m[v].__str__() for v in x] for var in x: print(var, ' = ', m[var]) return True, str(model) else: return False,''
def get_var(name): if name in vars: return vars[name] else: v = z3.Real(name) vars[name] = v return v
def create_param_map_for_query(thread_ctx, query): params = [] if isinstance(query, ReadQuery): if query.pred: params += query.pred.get_all_params() for v, f in query.aggrs: params += f.get_all_params() else: params += query.get_all_params() for i, p in enumerate(params): if is_int_type(p.tipe) or is_unsigned_int_type(p.tipe): v = z3.Int('param-{}-{}'.format(p.symbol, i)) elif is_bool_type(p.tipe): v = z3.Bool('param-{}-{}'.format(p.symbol, i)) elif is_float_type(p.tipe): v = z3.Real('param-{}-{}'.format(p.symbol, i)) elif is_string_type(p.tipe): v = z3.Int('param-{}-{}'.format(p.symbol, i)) else: assert (False) if not is_bool_type(p.tipe): thread_ctx.get_symbs().solver.add(v < INVALID_VALUE) thread_ctx.get_symbs().param_symbol_map[p] = v if isinstance(query, ReadQuery): for k, v in query.includes.items(): create_param_map_for_query(thread_ctx, v)
def helper(x): if (x is None): return x elif (self.is_uninterpreted_fun(x)): match = [f[1] for f in funQ if f[0] is x] if (len(match) == 1): # found a match return match[0] else: rangeSort = x.decl().range() varName = '|$' + str(x) + '|' if (rangeSort == z3.RealSort()): newVar = z3.Real(varName) elif (rangeSort == z3.IntSort()): newVar = z3.Int(varName) elif (rangeSort == z3.BoolSort()): newVar = z3.Bool(varName) else: raise ExptRewriteFailure( 'unknown sort for range of uninterpreted function -- ' + varName + ' returns a ' + rangeSort + ' ?') funQ.append((x, newVar)) return newVar else: ch = x.children() newch = self.fun_to_var(ch, report) if (len(ch) != len(newch)): raise ExptRewriteFailure('Internal error') elif (len(newch) == x.decl().arity()): return x.decl().__call__(*newch) elif ((x.decl().arity() == 2) and (len(newch) > 2)): return reduce(x.decl(), newch) else: raise ExptRewriteFailure('Internal error')
def get_random_P(dim=3): """ P = [[P0 P1 ..] .. [..]] full, non-symmetric :param dim: dimension of P :return: SymPy P with Z3 symbols """ return sp.Matrix([[z3.Real('P%d' % (r * dim + c)) for r in range(dim)] for c in range(dim)])
def _verify(P, A): # eg. for dReal import z3 from src.sympy_converter import sympy_converter from src.linear import f0, f1 from src.common import OrNotZero eigvals = sp.Matrix(P).eigenvals() #log("eig %s" % eigvals) try: if all(sp.re(l) > 0 for (l, m) in eigvals.items()): # eig P > 0 return True else: return False except: pass x = sp.Matrix([sp.Symbol('x%s' % i) for i in range(P.shape[0])]) x3 = [z3.Real('x%s' % i) for i in range(P.shape[0])] _, _, V = sympy_converter(f0(x, x.T, P)) _, _, Vd = sympy_converter(f1(x, x.T, P, A)) s = z3.Solver() s.add(z3.Not(z3.Implies(OrNotZero(x3), z3.And(V > 0, Vd < 0)))) r = s.check() #if r == z3.sat: #log("_verify has model %s\n\t against V = %s ; Vd = %s" % (s.model(), V, Vd)) return r == z3.unsat
def __init__(cls, name: str, bases: tuple[type, ...], ns: Namespace): sorts = {bool: z3.BoolSort(), int: z3.IntSort(), float: z3.RealSort()} vars = {} try: for var, ann in cls.__annotations__.items(): if isinstance(ann, str): ann = eval(ann) if ann is bool: vars[var] = z3.Bool(var) elif ann is int: vars[var] = z3.Int(var) elif ann is float: vars[var] = z3.Real(var) elif isinstance(ann, dict): in_sort, out_sort = next(iter(ann.items())) out_sort = sorts[out_sort] if isinstance(in_sort, tuple): in_sort = (sorts[x] for x in in_sort) vars[var] = z3.Function(var, *in_sort, out_sort) else: in_sort = sorts[in_sort] vars[var] = z3.Function(var, in_sort, out_sort) except: pass solver = z3.Solver() for term in ns.assertions: solver.add(traverse(term, vars)) assert solver.check(), "Unsatisfiable constraints!" cls.__model = solver.model() cls.__vars = vars
def find_optimum_z3(func, var, timeout=5000): logging.debug("Checking {}".format(func)) solver = z3.Solver() solver.set("timeout", timeout) # Set variable z3_var = z3.Real(str(var)) solver.add(z3_var > 0) solver.add(z3_var < 1) # Set function constraint_str = "(assert ( = 0 {}))".format(func.to_smt2()) z3_constraint = z3.parse_smt2_string(constraint_str, decls={str(var): z3_var}) solver.add(z3_constraint) # Solve result = "sat" optima = [] while result == "sat": result = str(solver.check()) logging.debug("Result: {}".format(result)) if result == "sat": opt = solver.model()[z3_var] logging.debug("Model: {}".format(opt)) optima.append(opt) add_constraint = z3_var != opt logging.debug(add_constraint) solver.add(add_constraint) # return optima if result == "unsat": return optima else: assert result == "unknown" logging.warning("Result of finding optimum for '{}' is 'unknown'".format(func)) return optima
def get_minimum_dt_of_several_anonymous(comparators, timeunit, epsilon=config.epsilon): raise DeprecatedWarning( "get_minimum_dt_of_several_anonymous is deprecated") comparators = [comp for comp in comparators if (comp is not None)] if len(comparators) == 0: # Early exit... we should probably check this before we get into this function return None solver = z3.Solver() eps = z3.Real("epsilon") solver.add( eps == epsilon ) # FIXME: remove epsilon, z3 can deal with uninterpreted variables min_dt = get_z3_var(timeunit, 'min_dt') [solver.add(min_dt <= dt) for dt in comparators ] # min_dt should be maximum this size (trying to find the smallest) logger.debug(f"comparators: {comparators}") solver.add(z3.Or([min_dt == dt for dt in comparators])) # but it has to be one of them! assert solver.check( ) == z3.sat, "the constraint to find the minimum dt is not solvable... that's weird" model = solver.model() return model[min_dt]
def getTauValues(self): result = list() if self.model is not None: for i in range(self.bound + 1): time_value = None if self._solver == 'z3': time_var = z3.Real("time" + str(i)) if self.model[time_var] is not None: time_value = float( self.model[time_var].as_decimal(6).replace( "?", "")) elif self._solver == 'yices': all_terms = self.model.collect_defined_terms() var_val = dict() for term in all_terms: var_val[str( Terms.get_name(term))] = self.model.get_value(term) time_id = "time" + str(i) if time_id in var_val.keys(): time_value = var_val[time_id] else: raise ValueError( "Can't support the given solver, please use z3 or yices solvers" ) if time_value is not None: result.append(time_value) return result
def label(boundary, should_invert=False, param_boundaries=[[0.0, 20.0], [0,1.0]], epsilon=0.01, num_points=200, lipschitz_param=0.05): """ Takes a boundary, and returns its proper label, which is True or False. Correct implementation will depend on context, and in the extreme case will require computation done by the human. """ # TODO: add type assertions if should_invert: my_boundary = utils.invert(boundary, param_boundaries) else: my_boundary = boundary utils.plot(my_boundary, 'tab:orange', param_boundaries) print("in the label function") # print("in the label function, should_invert is", should_invert) # print("boundary that label is synthesising", my_boundary) # print(num_points) xs = [z3.Real('x%d' % i) for i in range(num_points)] us = [z3.Real('u%d' % i) for i in range(num_points)] def make_phi(xs, us): # this basically makes a formula encoding dynamics of a system xs # controlled by us formula = True for i in range(num_points - 1): formula = z3.And(formula, xs[i+1] == xs[i] + us[i], # xs[i+1] - xs[i] <= lipschitz_param, # xs[i] - xs[i+1] <= lipschitz_param, xs[i] >= 0, xs[i+1] >= 0, xs[i] <= 1, xs[i+1] <= 1) return formula trace = bt.trace(my_boundary, epsilon, num_points, xs, param_boundaries[0][1], make_phi(xs, us)) # print("trace that is being labelled is", trace) # utils.plot(trace) class_val = True for point in trace: if point[0] >= 10: class_val = class_val and (point[1] <= (-0.08)*point[0] + 1.8) return class_val
def get_var(self, frame: Frame, frame_seq_in_peroid, link: Link): name = self.get_var_name(frame, frame_seq_in_peroid, link) if name not in self._var_name_map: var = z3.Real(name) self._var_name_map[name] = var self._solver.add(var >= frame_seq_in_peroid * frame.peroid) self._solver.add(var < (frame_seq_in_peroid + 1) * frame.peroid) return var else: return self._var_name_map[name]
def __build_vars(self, model): '''build solver vars''' # obj self._vars["min"] = z3.Real("min") # task start time and assinger vars for _, task in model.tasks.items(): _var_name = "{}_start".format(task.name) self._vars[_var_name] = z3.Int(_var_name) _var_name = "{}_assigner".format(task.name) self._vars[_var_name] = z3.Int(_var_name)
def walk_symbol(self, formula, args): symbol_type = formula.symbol_type() if symbol_type == types.BOOL: res = z3.Bool(formula.symbol_name()) elif symbol_type == types.REAL: res = z3.Real(formula.symbol_name()) elif symbol_type == types.INT: res = z3.Int(formula.symbol_name()) else: assert False return res
def decl(self, typ, var): if typ == SMTEnv.Type.REAL: v = z3.Real(var) elif typ == SMTEnv.Type.BOOL: v = z3.Bool(var) elif typ == SMTEnv.Type.INT: v = z3.Int(var) else: raise Exception("????") self._z3vars[var] = v self._smtvars[v] = var
def check_safe_reachability(traj, obs, goal): s = smt.Solver() # convert 2d traj to 1d array #convert 2d obstacle to 1d array # convert 2d goal to 1d array # x_i != o_j # x_n == g for i, x in enumerate(traj): x_i = smt.Real("x_%d" % i) s.add(x_i == x) for j, o in enumerate(obs): o_j = smt.Real("o_%d" % j) s.add(o_j == o) s.add(x_i != o_j) #STEP - is last node in the goal location? x_n = smt.Real("x_%d" % i) for g in goal: s.add(x_n == g) result = s.check() return result == smt.sat
def walk_symbol(self, formula, **kwargs): symbol_type = formula.symbol_type() if symbol_type.is_bool_type(): res = z3.Bool(formula.symbol_name()) elif symbol_type.is_real_type(): res = z3.Real(formula.symbol_name()) elif symbol_type.is_int_type(): res = z3.Int(formula.symbol_name()) else: assert symbol_type.is_bv_type() res = z3.BitVec(formula.symbol_name(), formula.bv_width()) return res
def _convert(exp): a, b = symath.wilds('a b') vals = symath.WildResults() if exp.match(a < b, vals): return _convert(vals.a) < _convert(vals.b) elif exp.match(a > b, vals): return _convert(vals.a) > _convert(vals.b) elif exp.match(symath.stdops.Equal(a, b), vals): return _convert(vals.a) == _convert(vals.b) elif exp.match(a <= b, vals): return _cnvert(vals.a) <= _convert(vals.b) elif exp.match(a >= b, vals): return _convert(vals.a) >= _convert(vals.b) elif exp.match(a + b, vals): return _convert(vals.a) + _convert(vals.b) elif exp.match(a - b, vals): return _convert(vals.a) - _convert(vals.b) elif exp.match(a * b, vals): return _convert(vals.a) * _convert(vals.b) elif exp.match(a / b, vals): return _convert(vals.a) / _convert(vals.b) elif exp.match(a ^ b, vals): return _convert(vals.a) ^ _convert(vals.b) elif exp.match(a & b, vals): return _convert(vals.a) & _convert(vals.b) elif exp.match(a | b, vals): return _convert(vals.a) | _convert(vals.b) elif exp.match(a**b, vals): return _convert(vals.a)**_convert(vals.b) elif exp.match(symath.stdops.LogicalAnd(a, b), vals): return z3.And(_convert(vals.a), _convert(vals.b)) elif exp.match(symath.stdops.LogicalOr(a, b), vals): return z3.Or(_convert(vals.a), _convert(vals.b)) elif exp.match(symath.stdops.LogicalXor(a, b), vals): return z3.Or(z3.And(_convert(vals.a), z3.Not(_convert(vals.b))), z3.And(_convert(vals.b), z3.Not(_convert(vals.a)))) elif isinstance(exp, symath.Symbol) and exp.is_integer: return z3.Int(exp.name) elif isinstance(exp, symath.Symbol) and exp.is_bool: return z3.Bool(exp.name) elif isinstance(exp, symath.Symbol) and exp.is_bitvector > 0: return z3.BitVec(exp.name, exp.is_bitvector) elif isinstance(exp, symath.Symbol): return z3.Real(exp.name) elif isinstance(exp, symath.core._KnownValue): return exp.value() else: raise BaseException( "Invalid argument (%s) (type: %s) passed to z3 solver" % (exp, type(exp)))
def symbol(self, tree, node_id): idx = tree.feature[node_id] if idx < 0: idx += tree.n_features if self.feature_names is None: name = 'x%d' % (idx + 1) else: name = self.feature_names[idx] if not name in self.symtab: self.symtab[name] = z3.Real(name) return self.symtab[name]