def run(self, query_index): self.fp.set(engine='spacer') if self.args.stat: self.fp.set('print_statistics', True) if self.args.z3_verbose: z3.set_option(verbose=1) if self.args.utvpi: self.fp.set('pdr.utvpi', False) self.fp.set('use_heavy_mev', True) self.fp.set('pdr.flexible_trace', True) self.fp.set('reset_obligation_queue', False) self.fp.set('spacer.elim_aux', False) if not self.args.pp: self.log.info("No pre-processing") self.fp.set('xform.slice', False) self.fp.set('xform.inline_linear', False) self.fp.set('xform.inline_eager', False) queries = self.fp.parse_file(self.smt2_file) self.preds = get_preds(self.fp) out = "" query = queries[query_index] if z3.is_quantifier(query): decl = query.body().decl() self.function_name = str(decl).split("@")[0] out = self.checkFeas(query) return out else: function_name = str(query.decl()).split("@")[0] out = out_message % (function_name, "FEASIBLE", "", "", "", "", "") out = bcolors.OKGREEN + out + bcolors.ENDC return out
def VerifyMayAlias(v1, v2, graph, addtlExprs): AddMetadataToSelfAndAllOperands(v1, "MRSG", True) AddMetadataToSelfAndAllOperands(v2, "MRSG", True) mrsgExpr = [] for v in graph.vertices: if "MRSG" in v.metadata: tempExpr = v.VertexOperationToSmt() if tempExpr != None: mrsgExpr.append(tempExpr) RemoveMetadataToSelfAndAllOperands(v1, "MRSG") RemoveMetadataToSelfAndAllOperands(v2, "MRSG") z3.set_option(timeout=config.smtTimeout) s = z3.Solver() s.add(addtlExprs) s.add(mrsgExpr) s.add(v1.VertexNameToSmt() == v2.VertexNameToSmt()) # 8, 1 # if config.readNodeNum == 8 and config.indexAliasNum == 1 : # print(s.sexpr()) # sys.exit("") return ExecuteZ3PyFromSolver(s)
def initialize_z3(self): self.predicate_expr = True z3.set_option(html_mode=False) if self.config.z3_parallel: z3.set_param("parallel.enable", True) if self.config.z3_parallel_max_threads: z3.set_param("parallel.threads.max", self.config.z3_parallel_max_threads)
def run(self, query_index): self.fp.set (engine='spacer') if self.args.stat: self.fp.set('print_statistics',True) if self.args.z3_verbose: z3.set_option (verbose=1) if self.args.utvpi: self.fp.set('pdr.utvpi', False) self.fp.set('use_heavy_mev',True) self.fp.set('pdr.flexible_trace',True) self.fp.set('reset_obligation_queue',False) self.fp.set('spacer.elim_aux',False) if not self.args.pp: self.log.info("No pre-processing") self.fp.set ('xform.slice', False) self.fp.set ('xform.inline_linear',False) self.fp.set ('xform.inline_eager',False) queries = self.fp.parse_file (self.smt2_file) self.preds = get_preds(self.fp) out = "" query = queries[query_index] if z3.is_quantifier(query): decl = query.body().decl() self.function_name = str(decl).split("@")[0] out = self.checkFeas(query) return out else: function_name = str(query.decl()).split("@")[0] out = out_message % (function_name, "FEASIBLE", "", "", "", "", "") out = bcolors.OKGREEN + out + bcolors.ENDC return out
def initZ3(): ''' first set the Z3 configs ''' assert z3.get_version() >= (4, 8, 6, 0) #set version z3.set_option('smt.string_solver', 'z3str3') # tell what string solver you will use z3.set_option('timeout', 120 * 1000 ) ### 120 seconds = 2 minutes
def setSolver(self): """Set the configuration for the solver""" self.fp.set(engine='spacer') #z3.set_option(rational_to_decimal=True) #self.fp.set('precision',30) if self.args.stat: self.fp.set('print_statistics', True) if self.args.spacer_verbose: z3.set_option(verbose=1) self.fp.set('use_heavy_mev', True) self.fp.set('pdr.flexible_trace', True) self.fp.set('reset_obligation_queue', False) self.fp.set('spacer.elim_aux', False) if self.args.eldarica: self.fp.set('print_fixedpoint_extensions', False) if self.args.utvpi: self.fp.set('pdr.utvpi', False) if self.args.tosmt: self.log.info("Setting low level printing") self.fp.set('print.low_level_smt2', True) if not self.args.pp: self.log.info("No pre-processing") self.fp.set('xform.slice', False) self.fp.set('xform.inline_linear', False) self.fp.set('xform.inline_eager', False) return
def solve(self): r = self._solver.check() if r == z3.unsat: z3.set_option(max_depth=10000, max_args=100, max_lines=10000) logger.debug(f"Unsat encountered: {self._solver}") raise SolutionNotFoundError( message=f'No satisfying solution could be found', labels=self._solver.unsat_core())
def _prove_bound_for_region(self, probability_dimension: int, cost_bound: float, region: ProbabilityRegion) -> bool: z3.set_option(rational_to_decimal=True) ps = [z3.Real(f"p{i}") for i in range(probability_dimension)] constraints = [self.lambdified_objective(*ps) >= cost_bound] constraints += [ ps[i] >= region.lower_bounds[i] for i in range(probability_dimension) ] constraints += [ ps[i] <= region.upper_bounds[i] for i in range(probability_dimension) ] s = z3.Solver() s.add(constraints) result = s.check() return str(result) == "unsat"
def get_rand_buf_size(cond): BIT_NUM = 12 if cond is None: return random.randint(0, 2**BIT_NUM - 1) z3.set_option('smt.phase_selection', 5) z3.set_option('smt.random_seed', random.randint(0, ctypes.c_uint(-1).value // 2)) x = z3.BitVec('x', BIT_NUM) s = z3.Solver() s.push() s.add(eval(cond)) s.check() return s.model()[x].as_long()
def setSolver(self): """Set the configuration for the solver""" self.fp.set(engine='spacer') self.fp.set('print_statistics', True) if self.args.spacer_verbose: z3.set_option(verbose=1) self.fp.set('use_heavy_mev', True) self.fp.set('pdr.flexible_trace', True) self.fp.set('reset_obligation_queue', False) self.fp.set('spacer.elim_aux', False) self.fp.set('print_fixedpoint_extensions', False) if self.args.utvpi: self.fp.set('pdr.utvpi', False) if not self.args.pp: self.log.info("No pre-processing") self.fp.set('xform.slice', False) self.fp.set('xform.inline_linear', False) self.fp.set('xform.inline_eager', False) return
def get_rand_buf_size(cond): if cond is None: return random.randint(0, 2**10 - 1) else: rand_seed = random.randint(0, ctypes.c_uint(-1).value // 2) z3.set_option('smt.phase_selection', 5) z3.set_option('smt.random_seed', rand_seed) x = z3.BitVec('x', 32) s = z3.Solver() s.push() s.add(eval(cond)) s.add(x < 2**16) s.check() return s.model()[x].as_long()
def solve(self, smt2_file): """ Start solving """ self.fp.set(engine='spacer') if self.args.stat: self.fp.set('print_statistics', True) if self.args.z3_verbose: z3.set_option(verbose=1) self.fp.set('use_heavy_mev', True) self.fp.set('pdr.flexible_trace', True) self.fp.set('reset_obligation_queue', False) self.fp.set('spacer.elim_aux', False) if self.args.utvpi: self.fp.set('pdr.utvpi', False) if not self.args.pp: self.fp.set('xform.slice', False) self.fp.set('xform.inline_linear', False) self.fp.set('xform.inline_eager', False) with stats.timer('Parse'): queries = self.fp.parse_file(smt2_file) stats.stop('Parse') self.preds = get_preds(self.fp) n_function = len(queries) stat("Function_Numbers", n_function) # TODO: Put them in a multithreading function all_results = "" for q in queries: if z3.is_quantifier(q): decl = q.body().decl() function_name = str(decl).split("@")[0] try: out = self.checkFeasibility(q, function_name) all_results += out + "\n-----------------------\n" except Exception as e: print "Solving " + function_name else: function_name = str(q.decl()).split("@")[0] out = out_message % (function_name, "CONSISTENT", "", "Trivial", "") all_results += bcolors.OKGREEN + out + bcolors.ENDC print "\n\t ========= SEAHORN INCONSISTENCY RESULTS ========" print all_results
def _fresh_init(self, config=None): super(CovManager, self)._fresh_init(config) if not self.__dict__ or "_cov_manager_status" not in self.__dict__ or not self._cov_manager_status: # a result cache when solving conditions for sym_nodes self.cov_cached = {} # explanation please refer to `_ast_manager_status` in manager.AstManager self._cov_manager_status = True # the rtb constraint read from rtb file. self.predicate_expr = True # the cache for z3 expression satisfiability checking self.z3_cache = {} z3.set_option("smt.arith.solver", 2) self.z3_solver = z3.SimpleSolver() self.z3_assumptions_cache = {} self.z3_assumptions_computed_cache = {} self._infer_wrapper = lambda x: x # caching of abutments cover calculation involving multiple inference results self.leaf_cells_dict = {} # list of function arguments that is z3 variables self._z3_func_args: List[nodes.Arg] = []
def solve(self, smt2_file): """ Start solving """ self.fp.set (engine='spacer') if self.args.stat: self.fp.set('print_statistics',True) if self.args.z3_verbose: z3.set_option (verbose=1) self.fp.set('use_heavy_mev',True) self.fp.set('pdr.flexible_trace',True) self.fp.set('reset_obligation_queue',False) self.fp.set('spacer.elim_aux',False) if self.args.utvpi: self.fp.set('pdr.utvpi', False) if not self.args.pp: self.fp.set ('xform.slice', False) self.fp.set ('xform.inline_linear',False) self.fp.set ('xform.inline_eager',False) with stats.timer ('Parse'): queries = self.fp.parse_file (smt2_file) stats.stop('Parse') self.preds = get_preds(self.fp) n_function = len(queries) stat("Function_Numbers", n_function) # TODO: Put them in a multithreading function all_results = "" for q in queries: if z3.is_quantifier(q): decl = q.body().decl() function_name = str(decl).split("@")[0] try: out = self.checkFeasibility(q, function_name) all_results += out + "\n-----------------------\n" except Exception as e: print "Solving " + function_name else: function_name = str(q.decl()).split("@")[0] out = out_message % (function_name, "CONSISTENT", "", "Trivial", "") all_results += bcolors.OKGREEN + out + bcolors.ENDC print "\n\t ========= SEAHORN INCONSISTENCY RESULTS ========" print all_results
def main(): base = 100 expected = [99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99] expected = base2integer(expected, 100) expected = integer2base(expected, base) size = len(expected) bits = 2 * (int(math.log(base, 2)) + 1) + 1 va = create_bit_vector('a', size, bits) vb = create_bit_vector('b', size, bits) expected = left_pad_with_zeros(expected, 2 * len(expected)) print(str(expected)) z3.set_option("parallel.enable", True) # 6 Threads ran on AMD Phenom II X6 z3.set_option("parallel.threads.max", 6) s = z3.SolverFor("QF_BV") multiply(s, base, va, vb, expected) time1 = datetime.now() if s.check() == z3.sat: print("sat") m = s.model() print(str(m)) f1 = vector_to_number(m, va, base) f2 = vector_to_number(m, vb, base) print("Factor 1 = " + str(f1)) print("Factor 2 = " + str(f2)) print("The number (Factor 1 * Factor 2) " + str(f1 * f2)) else: print("unsat") print(base2integer(expected, base)) print(str(s.unsat_core())) time2 = datetime.now() print("Base " + str(base)) print("Elapsed " + str(time2 - time1))
def VerifyEquivalentIntersectionMode(v1, v2, graph, addtlExprs): CalculateMinimalRelationalSubGraph(v1, v2) mrsgExpr = [] for v in graph.vertices: if not "MRSG" in v.metadata: continue isUnbound = False if v.operands == None: isUnbound = True else: for op in v.operands: if op.type == depgraph.VertexNode.VertexType.FUNC: continue if op.type == depgraph.VertexNode.VertexType.IMM: continue if not "MRSG" in op.metadata: isUnbound = True break if not isUnbound: tempExpr = v.VertexOperationToSmt() if tempExpr != None: mrsgExpr.append(tempExpr) RemoveMetadataToSelfAndAllOperands(v1, "MRSG") RemoveMetadataToSelfAndAllOperands(v1, "red") RemoveMetadataToSelfAndAllOperands(v1, "blue") RemoveMetadataToSelfAndAllOperands(v1, "MRSG_Analyzed") RemoveMetadataToSelfAndAllOperands(v2, "MRSG") RemoveMetadataToSelfAndAllOperands(v2, "red") RemoveMetadataToSelfAndAllOperands(v2, "blue") RemoveMetadataToSelfAndAllOperands(v2, "MRSG_Analyzed") z3.set_option(timeout=config.smtTimeout) s = z3.Solver() s.add(addtlExprs) s.add(mrsgExpr) s.add(v1.VertexNameToSmt() != v2.VertexNameToSmt()) # if config.equivNodeNum == 358 : # print(s.sexpr()) # sys.exit("") return ExecuteZ3PyFromSolver(s)
def VerifyEquivalentDefaultMode(v1, v2, graph, addtlExprs): AddMetadataToSelfAndAllOperands(v1, "MRSG", True) AddMetadataToSelfAndAllOperands(v2, "MRSG", True) mrsgExpr = [] for v in graph.vertices: if "MRSG" in v.metadata: tempExpr = v.VertexOperationToSmt() if tempExpr != None: mrsgExpr.append(tempExpr) RemoveMetadataToSelfAndAllOperands(v1, "MRSG") RemoveMetadataToSelfAndAllOperands(v2, "MRSG") z3.set_option(timeout=config.smtTimeout) s = z3.Solver() s.add(addtlExprs) s.add(mrsgExpr) s.add(v1.VertexNameToSmt() != v2.VertexNameToSmt()) return ExecuteZ3PyFromSolver(s)
def doZ3ForConcolicFuzzing(): ''' first set the Z3 configs ''' assert z3.get_version() >= (4, 8, 6, 0) #set version z3.set_option('smt.string_solver', 'z3str3') # tell what string solver you will use z3.set_option('timeout', 60 * 1000) ### 60 seconds = 1 minute ''' declare symbolic variables ''' z_inp = z3.Int('inp') ''' add constraints ''' z_inp < 0 # correpsonds to one branch of `inp < 0` z3.Not(z_inp < 0) # correpsonds to the other branch of `inp < 0` ''' solve() only gives a solution ''' soln = z3.solve(z_inp < 0) print(soln, dir(soln)) print('=' * 50) predicates = [z3.Not(z_inp < 0), z3.Not(z_inp == 0), z3.Not(z_inp == 1)] ''' As solve() only gives a solution , we need more using Solver() ''' solverObj = z3.Solver() # solverObj.add( z3.Not( z_inp < 0 ) , z3.Not( z_inp == 0 ), z3.Not( z_inp == 1 ) ) solverObj.add(predicates[0:-1] + [z3.Not(predicates[-1])]) print(solverObj.check()) if solverObj.check() == z3.sat and solverObj.check() != z3.unknown: m_ = solverObj.model() for decl_ in m_.decls(): print("Constraint variable(%s)=%s" % (decl_.name(), m_[decl_])) else: print("Solution not found. Oops!")
def __init__(self, info, cli, randomize=True): self.info = info self.cli = cli self.randomize = randomize self.agents = self.info.spawn.num_agents() self.attrs = [[] for _ in range(self.agents)] self.lstigs = [[] for _ in range(self.agents)] self.envs = [] self.sched = None self.picks = {} self.softs = set() self.is_setup = False self.s = Solver() if randomize: set_option(":auto_config", False) set_option(":smt.phase_selection", 5) set_option(":smt.random_seed", RND_SEED) random.seed(RND_SEED) log.debug(f"Concretization: random seed is {RND_SEED}")
def main(argv): args = parseArgs(argv[1:]) stat('Result', 'UNKNOWN') z3.set_option(verbose=args.verbose) ctx = z3.Context() fp = z3.Fixedpoint(ctx=ctx) if not args.slice: print 'No slicing' fp.set(slice=False) if not args.inline: print 'No inlining' fp.set(inline_linear=False) fp.set(inline_eager=False) print 'Engine: ', args.engine fp.set(validate_result=args.validate) fp.set(engine=args.engine, use_farkas=True, generate_proof_trace=False) fp.set(use_utvpi=args.use_utvpi) fp.set(eager_reach_check=args.eager_reach_check) fp.set(validate_theory_core=args.validate_theory_core) fp.set(print_statistics=args.print_stats) fp.set(bit_blast=args.bit_blast) if args.dfs: fp.set(bfs_model_search=False) fp.set(order_children=int(args.order_children)) if args.array_blast: fp.set(array_blast=True) if args.array_blast_full: fp.set(array_blast_full=True) if args.use_heavy_mev: fp.set(use_heavy_mev=True) with stats.timer('Parse'): q = fp.parse_file(args.file) if len(args.trace) > 0: print 'Enable trace: ', for t in args.trace.split(':'): print t, z3.enable_trace(t) print stats.put('Trace', args.trace) #print fp with stats.timer('Query'): res = fp.query_from_lvl(args.from_lvl, q[0]) if res == z3.sat: stat('Result', 'CEX') elif res == z3.unsat: stat('Result', 'SAFE') if args.answer: print 'The answer is:' print fp.get_answer() if res == z3.sat: if args.ground_answer: print 'A ground answer:' print fp.get_ground_sat_answer() if args.rules_along_trace: print 'Rules along trace:' print fp.get_rules_along_trace()
from synet.utils.common import PathReq from synet.utils.common import Protocols from synet.utils.common import Req from synet.utils.common import SynthesisComponent from synet.utils.common import path_exists from synet.utils.ospf_utils import extract_ospf_graph from synet.utils.ospf_utils import get_output_configs from synet.utils.ospf_utils import get_output_network_graph from synet.utils.ospf_utils import load_graph_constrains from synet.utils.ospf_utils import synthesize_ospf_announce from synet.utils.smt_context import is_symbolic __author__ = "Ahmed El-Hassany" __email__ = "*****@*****.**" z3.set_option('unsat-core', True) def get_path_key(src, dst): """ For a given path return a tuple of source and dst Useful for storing paths in dicts """ return src, dst def get_path_name(path): """Return a string name for the path (to used used in unsat core""" return '_'.join(path)
mbsQueryList = [] for mb in boundTuplePermutations : mbQueryList = [] for i in range(0, numP2Bounds-1) : mbQueryList.append(z3.ULT(mb[i][1], mb[i+1][0])) mbsQueryList.append(z3.And(mbQueryList)) preExpr.append(z3.Or(mbsQueryList)) for bt in P2BoundTuple : preExpr.append(z3.ULT(bt[0], bt[1])) programExpr = [x for x in map(lambda x : x.VertexOperationToSmt(), programGraph.vertices) if x != None] timeoutVal = 1000 * 60 * 60 * 12 z3.set_option(timeout=timeoutVal) s = z3.Solver() s.add(preExpr) s.add(programExpr) outEqList = [] for outEqVertex in postGraph.vertices : outEqList.append(outEqVertex.operands[0].VertexNameToSmt() == outEqVertex.operands[1].VertexNameToSmt()) s.add(z3.Not(z3.And(outEqList))) ansiCode.PrintOnThisLineBold("Running large query") check = s.check() print() config.analysisEndTime = time.time()
def setUp(self) -> None: """Set up parameters for how tests should be run and the precision.""" # z3.set_option(rational_to_decimal = True) z3.set_option(precision=QuadraticRootsTest.NUM_DECIMAL_PLACES)
def __init__( self, problem, debug: Optional[bool] = False, max_time: Optional[int] = 10, parallel: Optional[bool] = False, random_values: Optional[bool] = False, logics: Optional[str] = None, verbosity: Optional[int] = 0, ): """Scheduling Solver debug: True or False, False by default max_time: time in seconds, 60 by default parallel: True to enable mutlthreading, False by default """ self.problem = problem self.problem_context = problem.context self.debug = debug # objectives list self.objective = None # the list of all objectives defined in this problem self.current_solution = None # no solution until the problem is solved # set_option('smt.arith.auto_config_simplex', True) if debug: set_option("verbose", 2) else: set_option("verbose", verbosity) if random_values: set_option("sat.random_seed", random.randint(1, 1e3)) set_option("smt.random_seed", random.randint(1, 1e3)) set_option("smt.arith.random_initial_value", True) else: set_option("sat.random_seed", 0) set_option("smt.random_seed", 0) set_option("smt.arith.random_initial_value", False) # set timeout self.max_time = max_time # in seconds set_option("timeout", int(self.max_time * 1000)) # in milliseconds # create the solver print("Solver type:\n===========") # check if the problem is an optimization problem self.is_not_optimization_problem = len( self.problem_context.objectives) == 0 self.is_optimization_problem = len(self.problem_context.objectives) > 0 self.is_multi_objective_optimization_problem = (len( self.problem_context.objectives) > 1) # the Optimize() solver is used only in the case of a mutli-optimization # problem. This enables to choose the priority method. # in the case of a single objective optimization, the Optimize() solver # apperas to be less robust than the basic Solver(). The # incremental solver is then used. # see this url for a documentation about logics # http://smtlib.cs.uiowa.edu/logics.shtml if logics is None: self._solver = Solver() print("\t-> Standard SAT/SMT solver") else: self._solver = SolverFor(logics) print("\t-> SMT solver using logics", logics) if debug: set_option(unsat_core=True) if parallel: set_option("parallel.enable", True) # enable parallel computation # add all tasks assertions to the solver for task in self.problem_context.tasks: self.add_constraint(task.get_assertions()) self.add_constraint(task.end <= self.problem.horizon) # then process tasks constraints for constraint in self.problem_context.constraints: self.add_constraint(constraint) # process resources requirements for ress in self.problem_context.resources: self.add_constraint(ress.get_assertions()) # process resource intervals for ress in self.problem_context.resources: busy_intervals = ress.get_busy_intervals() nb_intervals = len(busy_intervals) for i in range(nb_intervals): start_task_i, end_task_i = busy_intervals[i] for k in range(i + 1, nb_intervals): start_task_k, end_task_k = busy_intervals[k] self.add_constraint( Or(start_task_k >= end_task_i, start_task_i >= end_task_k)) # process indicators for indic in self.problem_context.indicators: self.add_constraint(indic.get_assertions()) # work amounts # for each task, compute the total work for all required resources""" for task in self.problem_context.tasks: if task.work_amount > 0.0: work_total_for_all_resources = [] for required_resource in task.required_resources: # work contribution for the resource interv_low, interv_up = required_resource.busy_intervals[ task] work_contribution = required_resource.productivity * ( interv_up - interv_low) work_total_for_all_resources.append(work_contribution) self.add_constraint( Sum(work_total_for_all_resources) >= task.work_amount) # process buffers for buffer in self.problem_context.buffers: # # create an array that stores the mapping between start times and # quantities. For example, if a start T1 starts at 2 and consumes # 8, and T3 ends at 6 and consumes 5 then the mapping array # will look like : A[2]=8 and A[6]=-5 # SO far, no way to have the same start time at different inst buffer_mapping = Array("Buffer_%s_mapping" % buffer.name, IntSort(), IntSort()) for t in buffer.unloading_tasks: self.add_constraint(buffer_mapping == Store( buffer_mapping, t.start, -buffer.unloading_tasks[t])) for t in buffer.loading_tasks: self.add_constraint(buffer_mapping == Store( buffer_mapping, t.end, +buffer.loading_tasks[t])) # sort consume/feed times in asc order tasks_start_unload = [t.start for t in buffer.unloading_tasks] tasks_end_load = [t.end for t in buffer.loading_tasks] sorted_times, sort_assertions = sort_no_duplicates( tasks_start_unload + tasks_end_load) self.add_constraint(sort_assertions) # create as many buffer state changes as sorted_times buffer.state_changes_time = [ Int("%s_sc_time_%i" % (buffer.name, k)) for k in range(len(sorted_times)) ] # add the constraints that give the buffer state change times for st, bfst in zip(sorted_times, buffer.state_changes_time): self.add_constraint(st == bfst) # compute the different buffer states according to state changes buffer.buffer_states = [ Int("%s_state_%i" % (buffer.name, k)) for k in range(len(buffer.state_changes_time) + 1) ] # add constraints for buffer states # the first buffer state is equal to the buffer initial level if buffer.initial_state is not None: self.add_constraint( buffer.buffer_states[0] == buffer.initial_state) if buffer.final_state is not None: self.add_constraint( buffer.buffer_states[-1] == buffer.final_state) if buffer.lower_bound is not None: for st in buffer.buffer_states: self.add_constraint(st >= buffer.lower_bound) if buffer.upper_bound is not None: for st in buffer.buffer_states: self.add_constraint(st <= buffer.upper_bound) # and, for the other, the buffer state i+1 is the buffer state i +/- the buffer change for i in range(len(buffer.buffer_states) - 1): self.add_constraint( buffer.buffer_states[i + 1] == buffer.buffer_states[i] + buffer_mapping[buffer.state_changes_time[i]]) # optimization if self.is_optimization_problem: self.create_objective()
elif i == 5: return setup_config_5 def get_finalizer(i): if i == 1: return configure_setup_with_io_manager elif i == 2: return configure_setup_with_io_and_chaining elif i == 3: return configure_setup_with_io_and_sharing if __name__ == '__main__': set_option(max_args=10000000, max_lines=1000000, max_depth=10000000, max_visited=1000000) print("Enter setup selection (1 - 5):") setup = input() print("Enter shared memory selection (1 - 3):") finalizer = input() setup_function = get_setup(setup) finalizer_function = get_finalizer(finalizer) def config_generator(ram_size, complex_overlap_constraint): return finalizer_function( setup_function(ram_size, complex_overlap_constraint))
import z3 if __name__ == '__main__': x = z3.Real('x') const = z3.RealVal(1) / 3 z3.set_option(rational_to_decimal=True) z3.solve(x + const == 0)
import z3 z3.set_option( precision=15, rational_to_decimal=True, max_args=10000000, max_lines=1000000, max_depth=10000000, max_visited=1000000, ) # https://z3prover.github.io/api/html/classz3py_1_1_rat_num_ref.html#a1012d6314d35530c58f9c018269ec867 def num(r): """ Convert from Z3 to python float values. """ return float(r.numerator_as_long()) / float(r.denominator_as_long()) def get_value(r): # https://stackoverflow.com/questions/12598408/z3-python-getting-python-values-from-model/12600208 """ Convert from Z3 to python values. """ if z3.is_true(r): return z3.is_true(r) elif z3.is_false(r): return z3.is_false(r) elif z3.is_int_value(r): return r.as_long()
def find_mask_full_encoding(image, weights, biases, run_params, window_size, label_index, delta=0, timeout=600, num_unique_solutions=1): """Finds a binary mask for a given image and a trained Neural Network. Args: image: float numpy array with shape (image_edge_length, image_edge_length, image_channels), image to be masked. For MNIST, the pixel values are between [0, 1] and for Imagenet, the pixel values are between [-117, 138]. weights: list of num_layers float numpy arrays with shape (output_dim, input_dim), weights of the neural network. biases: list of num_layers float numpy arrays with shape (output_dim,), biases of the neural network. run_params: RunParams with model_type, model_path, image_placeholder_shape, activations, tensor_names. window_size: int, side length of the square mask. label_index: int, index of the label of the training image. delta: float, logit of the correct label is greater than the rest of the logit by an amount delta. Its value is always >= 0. It is only used when constrain_final_layer is True. timeout: int, solver timeout in seconds. num_unique_solutions: int, number of unique solutions you want to sample. Returns: result: dictionary, * image: float numpy array with shape (image_edge_length * image_edge_length * image_channels,) * combined_solver_runtime: float, time taken by the solver to find all the solutions. * unmasked_logits: float numpy array with shape (num_outputs,) * unmasked_first_layer: float numpy array with shape (num_hidden_nodes_first_layer,) * masked_first_layer: list with length num_sols, contains float numpy array with shape (num_hidden_nodes_first_layer,) * inv_masked_first_layer: list with length num_sols, contains float numpy array with shape (num_hidden_nodes_first_layer,) * masks: list with length num_sols, contains float numpy array with shape (image_edge_length ** 2,) * masked_images: list with length num_sols, contains float numpy array with shape (image_edge_length ** 2,) * inv_masked_images: list with length num_sols, contains float numpy array with shape (image_edge_length ** 2,) * masked_logits: list with length num_sols, contains float numpy array with shape (num_outputs,) * inv_masked_logits: list with length num_sols, contains float numpy array with shape (num_outputs,) * solver_outputs: list with length num_sols, contains strings corresponding to every sampled solution saying 'sat', 'unsat' or 'unknown'. """ _verify_image_dimensions(image) image_placeholder_shape = run_params.image_placeholder_shape tensor_names = run_params.tensor_names # z3's timeout is in milliseconds z3.set_option('timeout', timeout * 1000) image_edge_length, _, _ = image.shape num_masks_along_row = image_edge_length // window_size session = utils.restore_model(run_params.model_path) z3_mask = [z3.Int('mask_%d' % i) for i in range(num_masks_along_row ** 2)] unmasked_predictions = session.run( tensor_names, feed_dict={ tensor_names['input']: image.reshape(image_placeholder_shape)}) smt_output, _ = utils.smt_forward( features=utils.flatten_nested_lists(_encode_input( image=image, z3_mask=z3_mask, window_size=window_size)), weights=weights, biases=biases, activations=run_params.activations) z3_optimizer = _formulate_smt_constraints_final_layer( z3_optimizer=utils.ImageOptimizer( z3_mask=z3_mask, window_size=window_size, edge_length=image_edge_length), smt_output=smt_output, delta=delta, label_index=label_index) solver_start_time = time.time() result = collections.defaultdict(list) # All the masks found in each call of z3_optimizer.generator() is guarranteed # to be unique since duplicated solutions are blocked. For more details # refer z3_optimizer.generator(). for mask, solver_output in z3_optimizer.generator(num_unique_solutions): _record_solution(result=result, mask=mask, solver_output=solver_output, image=image, session=session, run_params=run_params) result.update({ 'image': image.reshape(-1), 'combined_solver_runtime': time.time() - solver_start_time, 'unmasked_logits': np.squeeze(unmasked_predictions['logits']), 'unmasked_first_layer': np.squeeze(unmasked_predictions['first_layer'])}) session.close() return result
def runAnalysis(doc): # step 1. init data ops = doc.ops print(len(ops)) return opMap = doc.opMap inputs = doc.input outputs = doc.output keyInput = doc.keyInput wire = doc.wire wireOut = doc.wireOut wireIn = doc.wireIn # step 1. assist func def traceOut(nodes, masks=False): result = set() def _traceOutMasked(now): result.add(now) for x in wireIn[now]: for y in opMap[x].outputs: if (not (y in result)) and (y in masks): _traceOutMasked(y) def _traceOut(now): result.add(now) for x in wireIn[now]: for y in opMap[x].outputs: if (not (y in result)): _traceOut(y) if masks: for i in nodes: _traceOutMasked(i) else: for i in nodes: _traceOut(i) return result def traceIn(nodes, masks=False): result = set() def _traceInMasked(now): result.add(now) if not now in wireOut: return x = wireOut[now] for y in opMap[x].inputs: if (not (y in result)) and (y in masks): _traceInMasked(y) def _traceIn(now): result.add(now) if not now in wireOut: return x = wireOut[now] for y in opMap[x].inputs: if (not (y in result)): _traceIn(y) if masks: for i in nodes: _traceInMasked(i) else: for i in nodes: _traceIn(i) return result def findRelatedInput(node, masks, n=1): for i in wireIn[node]: mOp = opMap[i] pi = traceIn(mOp.inputs, masks) pi &= inputs if n == 1: secondary = set() for j in mOp.outputs: secondary |= findRelatedInput(j, masks, 0) secondary &= inputs return pi, secondary return pi # step 2. find HD circuit myTimer.startTime("Finding Target SubCircuit") hdCircuit = traceOut(keyInput) # print(hdCircuit) thatOutput = hdCircuit & outputs if not thatOutput: eprint( 'Cannot find related key of keyinputs, please check the keyinputs.' ) sys.exit(2) assert len(thatOutput) == 1 thatOutput = thatOutput.pop() subCircuit = traceIn([thatOutput]) # hdCircuit = hdCircuit and subCircuit eprint('HD circuit detacted. That output node is \'' + thatOutput + '\', with a circuit size of ' + str(len(hdCircuit)) + '.') eprint('Sub circuit detacted, with a circuit size of ' + str(len(subCircuit)) + "\n") myTimer.endTime("Finding Target SubCircuit") myTimer.startTime("Finding Related Inputs") key2In = {k: findRelatedInput(k, subCircuit) for k in keyInput} determined = set() und = [] for k in key2In: if len(key2In[k][0]) == 1: key2In[k] = key2In[k][0].pop() determined.add(key2In[k]) else: und.append(k) if und: eprint( "Warning, strong related node detacted, should be hamming distance instead of key: " + str(und) + "\n") for k in und: del key2In[k] # unable to elimiate # I think they are H, not key criticalInput = set(key2In.values()) if VERBOSE: for i in key2In: eprint(i + ' xored with ' + key2In[i]) myTimer.endTime("Finding Related Inputs") myTimer.startTime("Finding Perturb") hdRef = set() for wire in hdCircuit: ops = wireIn[wire] for i in ops: if i in opMap: op = opMap[i] for j in op.inputs: if not (j in hdCircuit): hdRef.add(j) perturbs = [] for i in hdRef: relatedIn = traceIn([i], subCircuit) & criticalInput if len(relatedIn) == len(criticalInput): perturbs.append(i) if not perturbs: eprint( 'Cannot find output of FSC circuit, maybe you can specific one.') sys.exit(2) eprint('Find output(s) of FSC circuit(so called perturbs): ' + str(perturbs) + '. ') states = {} def getSP(I): if I in inputs: return 0.5 if not (I in states): op = wireOut[I] result = opMap[op].getPossible(getSP) for k in result: states[k] = result[k] return states[I] maxAP = 0 bestP = 0 perturb = '' backupP = [] for i in perturbs: states = {} sp = p = getSP(i) if VERBOSE: eprint(i + " " + str(p)) if p < 0.5: sp = 1 - p if sp > 0.9: backupP.append((i, p)) if sp > maxAP: maxAP = sp bestP = p perturb = i if len(backupP) > 1: for pp in backupP: xins = traceIn([pp[0]], subCircuit) usedGates = set() for i in xins: if i in wireOut: unit = wireOut[i] usedGates.add(opMap[unit].func) if 'ADDH' in usedGates and 'ADDH' in usedGates and 'INV' in usedGates and ( not 'AO' in usedGates) and (not 'OA' in usedGates) and ( not 'AOI' in usedGates) and (not 'OAI' in usedGates): perturb, bestP = pp break should_get = 1 if bestP > 0.5: should_get = 0 eprint('Possibility of [\'' + perturb + '\' = 1] is ' + str(bestP) + ', which means we need to solve \'' + perturb + '\' = ' + str(should_get)) myTimer.endTime("Finding Perturb") """ output sub circuit xins = traceIn([perturb], subCircuit) nowOp = [opMap[wireOut[perturb]]] f = open('sub_' + perturb + '.csv', 'w') traced = set() traced.add(wireOut[perturb]) while nowOp: now = nowOp.pop(0) #print(now.statement()) cur = [now.func + "___" + now.name] for i in now.inputs: if i in wireOut: cur.append(opMap[wireOut[i]].func + "___" + wireOut[i]) else: cur.append("INPUT___" + i) f.write(";".join(cur) + '\n') for i in now.inputs: if not i in traced: if i in xins: if i in wireOut: if not wireOut[i] in traced: traced.add(wireOut[i]) nowOp.append(opMap[wireOut[i]]) f.close() """ """ plan B xins = traceIn([perturb], subCircuit) usingOp = set() for i in xins: if i in wireOut: unit = wireOut[i] usingOp.add(opMap[unit]) pasKey = {} for ci in criticalInput: visInv = {} visADD = {} markedInv = set() def spTraceOut(node, target, marks, vis): if not node in xins: return False hasADD = False vis[node] = False if node in wireIn: for opi in wireIn[node]: nx = opMap[opi] if nx.func in target: vis[node] = True marks.add(nx) return True # print(nx.func) for o in nx.outputs: if o in vis: if vis[o]: vis[node] = True else: if spTraceOut(o, target, marks, vis): vis[node] = True return vis[node] spTraceOut(ci, ['INV'], markedInv, visInv) markedADD = set() spTraceOut(ci, ['ADDF', 'ADDH'], markedADD, visADD) pasKey[ci] = False for i in markedInv: if (i.outputs[0] in visADD): pasKey[ci] = True #print(markedADD) # pOps = list(usingOp) nowOp = [opMap[wireOut[perturb]]] while nowOp: now = nowOp.pop(0) if now.func.startswith('ADD'): continue print(now.statement()) for i in now.inputs: if i in xins: if i in wireOut: nowOp.append(opMap[wireOut[i]]) #print(pasKey[ci]) """ myTimer.startTime("SAT") sat = z3.Solver() z3Nodes = {} def getZ3(I): if not (I in z3Nodes): if not I in inputs: op = wireOut[I] vals = opMap[op].z3Interface(getZ3) for k in vals: if not (k in z3Nodes): z3Nodes[k] = z3.Bool(k) sat.add(z3Nodes[k] == vals[k]) else: z3Nodes[I] = z3.Bool(I) return z3Nodes[I] def rec2str(rec): sss = "" for i in range(0, len(keyInput)): if ("keyinput" + str(i)) in rec: if rec["keyinput" + str(i)]: sss = sss + "1" else: sss = sss + "0" else: sss += "0" return sss getZ3(perturb) sat.add(z3Nodes[perturb] == (should_get == 1)) eprint('Start sat solver...') sat_result = sat.check() eprint(' > result: ' + str(sat_result)) sat_inputs = {} if (str(sat_result) == 'unsat'): eprint('Something goes wrong when solving ' + perturb + ' = 1, cannot get an input') else: m = sat.model() sat_inputs = {i: bool(m.evaluate(z3Nodes[i])) for i in criticalInput} # print('n6069', not bool(m.evaluate(z3Nodes['n6069']))) # for i in 'n6072 n6071 n6068 n6067 n6065 n6064'.split(' '): # print(i, bool(m.evaluate(z3Nodes[i]))) eprint('Found ' + str(len(sat_inputs)), 'bits of input. ') myTimer.endTime("SAT") myTimer.startTime("Solve by One PIP") def eval_nochace(res, x): state_vals = {} def getVal(I): if not (I in state_vals): if not (I in inputs or I in keyInput): op = wireOut[I] result = opMap[op].eval(getVal) for k in result: state_vals[k] = result[k] else: if I in res: return res[I] else: return False # all other bits set to zero return state_vals[I] a = getVal(x) flip = False if state_vals[perturb] == (1 == should_get): flip = True # print('flip') # print('n6069', not bool(state_vals['n6069'])) # for i in 'n6072 n6071 n6068 n6067 n6065 n6064'.split(' '): # print(i, bool(state_vals[i])) return a, flip def getFlippedInput(inp, flip): res = {} for i in inp: if i in flip: res[i] = not inp[i] else: res[i] = inp[i] return res def attack_nooracle(res): icnt = 0 flips = [] keys = list(res.keys()) change = keys[0] others = keys[1:] equset = [] nequset = [] res[change] = not res[change] allTask = len(others) for i in others: icnt = icnt + 1 if VERBOSE or (icnt % 10 == 0) and not TIMING: eprint('Working on ' + str(icnt) + '/' + str(allTask)) res[i] = not res[i] r2, f = eval_nochace(res, thatOutput) if (f == True): flips.append(i) nequset.append(i) else: equset.append(i) if VERBOSE: eprint('Model returns ' + str(r2)) eprint('Flip returns ' + str(f)) res[i] = not res[i] equset.append(change) res[change] = not res[change] return (equset, nequset, flips) pip = {i: sat_inputs[i] for i in sat_inputs} equset, nequset, flips = attack_nooracle(pip) # type X # pasKey = {i:pasKey[key2In[i]] for i in key2In} # print(rec2str(pasKey)) # TypeA. flip on zero, nequset is all one numHA = len(nequset) inpA = getFlippedInput(sat_inputs, nequset) rec_keysA = {i: inpA[key2In[i]] for i in key2In} idStrA = rec2str(rec_keysA) eprint("Possible result A. H = " + str(numHA)) eprint("key = " + idStrA) if VERBOSE: eprint(nequset) eprint(rec_keysA) # TypeB, flip on one, equset + flipped is all one numHB = len(equset) inpB = getFlippedInput(sat_inputs, equset) rec_keysB = {i: inpB[key2In[i]] for i in key2In} idStrB = rec2str(rec_keysB) eprint("Possible result B. H = " + str(numHB)) eprint("key = " + idStrB) if VERBOSE: eprint(equset) eprint(rec_keysB) eprint("flips: ") eprint(flips) myTimer.writeAns(" > H1 = " + str(numHA) + " Key1 = " + idStrA + "\n" + " > H2 = " + str(numHB) + " Key2 = " + idStrB + '\n Gate = ' + str(len(ops)) + '\n') myTimer.endTime("Solve by One PIP") minH = min(numHA, numHB) if (minH >= 4): # only run gaussian for h >= 4 # len(criticalInput) is required for solve the system pips = [] myTimer.startTime("PIPs for Gaussian") z3.set_option('smt.phase_selection', 5) criticalOrdered = [i for i in criticalInput] for i in range(0, len(criticalInput)): sat_result = sat.check() sat_inputs = {} z3.set_option('smt.random_seed', 5 + i) m = sat.model() ini = [bool(m.evaluate(z3Nodes[i])) for i in criticalOrdered] pips.append(ini) myTimer.endTime("PIPs for Gaussian") myTimer.startTime("Gaussian elimination") # eprint(rec2str(map2key)) nowH = minH factors = [list(map(lambda k: 1 if k == 0 else -1, i)) for i in pips] cs = [nowH - sum(i) for i in pips] # eprint(factors) import numpy as np a = np.array(factors) b = np.array(cs) x = np.linalg.solve(a, b) xi = { criticalOrdered[i]: abs(x[i] - 1) < 1e-5 for i in range(0, len(x)) } rec_keyG = {i: xi[key2In[i]] for i in key2In} eprint("key = " + rec2str(rec_keyG)) #print(x) myTimer.endTime("Gaussian elimination") myTimer.writeAns(" > H1 = " + str(numHA) + " Key1 = " + idStrA + "\n" + " > H2 = " + str(numHB) + " Key2 = " + idStrB + '\n' + " > KeyG = " + rec2str(rec_keyG) + '\n Gate = ' + str(len(ops)) + '\n')
def execute(trial=False): print("Starting new_station algorithm.") startTime = datetime.datetime.now() trial_size = 25 num_clusters = 50 max_dist = 0.04 min_num_close_stations = 2 # num_results = 5 # Set up the database connection. client = dml.pymongo.MongoClient() repo = client.repo repo.authenticate('kgarber', 'kgarber') repo.dropCollection("bluebikes.new_station") repo.createCollection("bluebikes.new_station") # read from mongodb print("Reading stations from DB.") stations = [st for st in repo['kgarber.bluebikes.stations'].find()] if trial: print("Running in trial mode.") stations = np.random.choice(stations, size=trial_size) # [[longitude, latitude], ...] stations = [[ st["location"]["geometry"]["coordinates"][0], st["location"]["geometry"]["coordinates"][1] ] for st in stations] # filter to make sure coordinates are correct (we have some bad data) stations = [ st for st in stations if -75 < st[0] < -70 and 40 < st[1] < 45 ] if trial: clusters = stations else: # get 100 clusters of stations, # any more than that is too hard for the optimizer. # also, clustering helps us remove weight from dense station areas. print("Running k-means.") clusters, _ = cluster.vq.kmeans(stations, num_clusters) num_pts = len(clusters) # objective variables z3.set_option(precision=6) o_lon, o_lat = z3.Reals('o_lon o_lat') # distances from new station to all other points distances = [ linear_distance(o_lon, o_lat, cl[0], cl[1]) for cl in clusters ] dist_sum = sum(distances) # restrict how far the station gets placed from a few other stations # prevents bad network branching num_close_enough = sum([z3.If(d < max_dist, 1, 0) for d in distances]) has_close_enough = num_close_enough > min_num_close_stations # set up the optimization solver opt = z3.Optimize() # make sure we don't place the station too far away from a few other stations opt.add(has_close_enough) # keep the station out of the atlantic ocean opt.add(o_lon < -70.032) # maximize the distance to other stations print("Running optimization...") maximized = opt.maximize(dist_sum) if (opt.check() == z3.sat): m = opt.model() print("Longitude:", m[o_lon].as_decimal(5)) print("Latitude:", m[o_lat].as_decimal(5)) repo['kgarber.bluebikes.new_station'].insert({ "longitude": m[o_lon].numerator_as_long() / m[o_lon].denominator_as_long(), "latitude": m[o_lat].numerator_as_long() / m[o_lat].denominator_as_long() }) # indicate that the collection is complete repo['kgarber.bluebikes.new_station'].metadata({'complete': True}) else: print("No result for optimization...") repo.logout() endTime = datetime.datetime.now() print("Finished new_station algorithm.") return {"start": startTime, "end": endTime}
def reencode_quantifiers(expr, boundvariables, quantifiers): z3.set_option(max_args=10000000, max_lines=1000000, max_depth=10000000, max_visited=1000000) smt2string = toSMT2Benchmark(expr) # Have to scan the string, because other methods proved to be too slow. log('Detect declarations of the free variables in SMTLIB2 string') free_variables = re.findall( '\(declare-fun (\w+) \(\) (Bool)|\(declare-fun (\w+) \(\) \(\_ BitVec (\d+)\)', smt2string) free_variables += re.findall( '\(declare-const (\w+) (Bool)|\(declare-const (\w+) \(\_ BitVec (\d+)\)', smt2string) for fv in free_variables: if str(fv).startswith('?'): print( 'Error: Variable starts with "?". Potential for confusion with quantified variables. This case is not handled.' ) exit() log(' Found {} free variables'.format(len(free_variables))) # Turn free variables into z3 variabes and add them to the quantifier for idx, (a, b, x, y) in enumerate(free_variables): assert (a != '' or x != '') if a != '': assert (b == 'Bool') free_variables[idx] = Bool(a) else: free_variables[idx] = BitVec(x, int(y)) quantifiers = [['e', free_variables]] + quantifiers log('Replacing de Bruijn indices by variables') matches = re.findall('\?(\d+)', smt2string) deBruijnIDXs = map(int, set(matches)) assert (len(deBruijnIDXs) <= len(boundvariables)) # sort de Bruijn indeces in decreasing order so that replacing smaller numbers does not accidentally match larger numbers deBruijnIDXs = list(deBruijnIDXs) deBruijnIDXs.sort() deBruijnIDXs.reverse() for idx in deBruijnIDXs: smt2string = smt2string.replace('?{}'.format(idx), str(boundvariables[-(1 + int(idx))])) log('Generating SMTLIB without quantifiers') # introduce quantified variables to enable re-parsing declarations = [] for var in boundvariables: if is_bv(var): declarations.append('(declare-fun {} () (_ BitVec {}))'.format( str(var), var.size())) else: assert (is_bool(var)) declarations.append('(declare-fun {} () Bool)'.format(str(var))) smt2string = '\n'.join(declarations) + '\n' + smt2string log('Reparsing SMTLIB without quantifiers') flat_constraints = parse_smt2_string(smt2string) # log('Extract all variables') # allvariables = get_vars(flat_constraints) # # log('Search for free variables') # freevariables = [] # known_vars = set(map(str,boundvariables)) # for idx, var in enumerate(allvariables): # if idx+1 % 10000 == 0: # log(' {} variables checked if free'.format(idx)) # if str(var) not in known_vars: # freevariables.append(var.n) # var.n because var is only the AstRefKey object # # log('Found {} free variables'.format(len(freevariables))) # # quantifiers = [['e', freevariables]] + quantifiers # delete empty quantifiers i = 0 while i < len(quantifiers): if len(quantifiers[i][1]) == 0: del (quantifiers[i]) else: i += 1 for i in range(len(quantifiers) - 1): if quantifiers[i][0] == quantifiers[i + 1][0]: mergedQuantifiers[-1][1] += quantifiers[i + 1][1] else: mergedQuantifiers += [quantifiers[i + 1]] # merge successive quantifiers of the same type if len(quantifiers) > 0: mergedQuantifiers = [quantifiers[0]] for i in range(len(quantifiers) - 1): if quantifiers[i][0] == quantifiers[i + 1][0]: mergedQuantifiers[-1][1] += quantifiers[i + 1][1] else: mergedQuantifiers += [quantifiers[i + 1]] quantifiers = mergedQuantifiers # print quantifiers return quantifiers, And(flat_constraints)
State, Port, get_path_to_attribute from crestdsl import sourcehelper as SH import crestdsl.ml as crestml from operator import attrgetter from methoddispatch import singledispatch, SingleDispatch import ast import types import operator import logging import copy from pprint import pformat import z3 z3.set_option(precision=30) logger = logging.getLogger(__name__) operator_to_operation = { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Mod: operator.mod, ast.Div: operator.truediv, ast.Pow: operator.pow, ast.BitXor: operator.xor, ast.FloorDiv: operator. truediv, # NOT operator.floordiv, because it doesn't work (z3 does floordiv automatically if only ints are present) ast.BitAnd: operator.and_, ast.BitOr: operator.or_,