def expt_rules(): rules = collections.deque() solver = z3.Solver() solver.set('arith.nl', False) solver.add(hyps) def show(p): report('trying to show(', p, '):') report(' hypotheses = ', solver) solver.push() solver.add(z3.Not(p)) outcome = solver.check() s1 = ' the negation is ' + str(outcome) if (outcome == z3.unsat): report(s1, "; therefore the original claim is valid") elif (outcome == z3.sat): report(s1, "\n here's a counter-example to ", p, "\n ", solver.model()) elif (outcome == z3.unknown): report(s1, "; therefore, the original claim is undecided") else: report(s1, "; how'd that happen?") solver.pop() return outcome == z3.unsat def add_rule(p): report('add_rule(', p, ')') rules.append(p) solver.add(p) while (len(workQ) > 0): v = workQ.pop() x = v.children()[0] n = v.children()[1] report('rewriting expt(', x, ', ', n, ')') # Many of the rules below should have guards to ensure that we don't # accidentally say expt(x, n) is defined when x==0 and n < 0. # Rather that figuring out # all of the corner cases, I first check to # see if (x == 0) and (n < 0) is satisfiable. If so, this code just # throws an exception. I could probably work out a better error message # later. # Now that we know that expt(x, n) is well-defined, we still need to be careful. # Consider expt(x, n+m) where x==0, n==3, and m==(-2). In this case, expt(x, n+m) # is well-defined, but we can't conclude: # expt(x, n+m) == expt(x, n) * expt(x, m) # Rather than working out lots of side conditions (and probably making a mistake), # I just check to see if implies(hyps, x > 0), and then plunge ahead without fear. # Of course, this means I don't generate all of the rules that I could, but I'll # do that later if this simple version turns out to be useful. def expt_rewrite_const(x2, n2): if (n2 == 0): return z3.intVal(1) elif ((0 < n2) and (n2 <= self.maxPowExpand)): add_rule(v == prod(map(lambda _: x2, range(n2)))) elif ((-self.maxPowExpand <= n2) and (n2 < 0)): add_rule(v * prod(map(lambda _: x2, range(-n2))) == 1) if (not show(z3.Or(x != 0, n >= 0))): raise ExptRewriteFailure( 'possible attempt to raise 0 to a negative power') x_is_pos = show(x > 0) x_is_nz = x_is_pos or show(x != 0) x_is_z = (not x_is_nz) and show(x == 0) n_is_pos = show(n > 0) n_is_neg = (not n_is_pos) and show(n < 0) n_is_z = (not n_is_pos) and (not n_is_neg) and show(n == 0) if (n_is_z or x_is_z): if (n_is_z): add_rule(v == 1) elif (n_is_pos): add_rule(v == 0) else: add_rule(v == z3.If(n == 0, 1, 0)) continue elif (x_is_pos): x_lt_1 = show(x < 1) x_gt_1 = (not x_lt_1) and show(x > 1) if ((not x_lt_1) and (not x_gt_1) and show(x == 1)): add_rule(v == 1) continue add_rule(v > 0) else: add_rule(z3.Implies(x > 0, v > 0)) if (x_is_nz): add_rule(z != 0) else: add_rule(z3.Implies(z3.Or(x != 0, n == 0), v != 0)) if ((x.decl().name() == '*') and (len(x.children()) > 1)): # expt(x0*x1*..., n) add_rule(v == prod(map(lambda y: xpt(y, n), x.children()))) elif ((n.decl().name() == '+') and (len(n.children()) > 1)): # expt(x, n0+n1+...) add_rule(v == prod(map(lambda m: xpt(x, m), n.children()))) elif (n.decl().name() == '-'): nn = n.children() if (len(nn) == 0): pass # a variable named '-' elif (len(nn) == 1): # expt(x, -n) add_rule(z3.Implies(x != 0, v * xpt(x, nn[0]) == 1)) elif (len(nn) == 2): # expt(x, n-m) add_rule( z3.Implies(x != 0, v * xpt(x, nn[1]) == xpt(x, nn[0]))) else: RewriteExptFailure( "unexpected: '-' expression with more than two children" ) elif (n.decl().name() == '*'): # expt(x, n0*n1*...) # check to see if n0 is integer constants and not "too big". # if so, replace it with repeated multiplication nn = n.children() if ((len(nn) > 0) and not (longVal(nn[0]) is None)): if (len(nn) == 1): ex = x else: ex = xpt(x, prod(nn[1:])) expt_rewrite_const(ex, longVal(nn[0])) elif (not (longVal(n) is None)): expt_rewrite_const(x, longVal(n)) else: # we can't think of a way to simplify it if (x_lt_1 or x_gt_1): if (n_is_pos or n_is_neg): pass else: add_rule(z3.Implies(n == 0, v == 1)) else: if (n_is_pos or n_is_neg): add_rule(z3.Implies(x == 1, v == 1)) else: add_rule(z3.Implies(z3.Or(x == 1, n == 0), v == 1)) if (x_is_pos): if (x_lt_1): if (n_is_pos): add_rule(v <= x) elif (n_is_neg): add_rule(v * x >= 1) else: add_rule( z3.And(z3.Implies(n > 0, v <= x), z3.Implies(n < 0, v * x >= 1))) elif (x_gt_1): if (n_is_pos): add_rule(v >= x) elif (n_is_neg): add_rule(v * x <= 1) else: add_rule( z3.And(z3.Implies(n > 0, v >= x), z3.Implies(n < 0, v * x <= 1))) else: add_rule( z3.And( z3.Implies(z3.And(x < 1, n > 0), v <= x), z3.Implies(z3.And(x < 1, n < 0), v * x >= 1), z3.Implies(z3.And(x > 1, n > 0), v >= x), z3.Implies(z3.And(x > 1, n < 0), v * x <= 1))) return rules
def __init__(self): self._s = z3.Solver()
import os import z3 f = open("graph1.txt", "r") n = int((f.readline()).split()[0]) rest = f.read() lines = rest.splitlines() edges = [tuple(map(int, line.split())) for line in lines] colors = range(0, 3) color_names = ["Blue", "Green", "Red"] #number of nodes times the number of colors nvars = n * len(colors) vars = [None] * nvars solver = z3.Solver() def varnum(i, j): assert (i in range(0, n) and j in colors) return len(colors) * i + j # define variables for i in range(0, n): for j in colors: vars[varnum(i, j)] = z3.Bool("x" + str(varnum(i, j))) def exactly_one_of(literals):
def clauses_sat(clauses1): """True if clauses1 imply clauses2. """ s = z3.Solver() s.add(clauses_to_z3(clauses1)) return s.check() != z3.unsat
def mk(cls, using_nla, myseed=None): return z3.Solver()
def solve(self, goal, lemmas=None): """ Primary function of the NPSolver class. Attempts to prove the goal with respect to given lemmas and the theory defined by the AnnotatedContext in self.annctx. :param goal: z3.BoolRef :param lemmas: set of z3.BoolRef :return: NPSolution """ z3.set_param('smt.random_seed', 0) z3.set_param('sat.random_seed', 0) # TODO: check that the given lemmas are legitimate bound formula instances with their formal parameters from # the foreground sort. options = self.options # Make recursive definition unfoldings recdefs = get_recursive_definition(None, alldefs=True, annctx=self.annctx) recdef_unfoldings = make_recdef_unfoldings(recdefs) # Sometimes we don't need the unfoldings indexed by recdefs untagged_unfoldings = set(recdef_unfoldings.values()) # Add them to the set of axioms and lemmas to instantiate axioms = get_all_axioms(self.annctx) if lemmas is None: lemmas = set() else: # Check that each bound parameter in all the lemmas are of the foreground sort for lemma in lemmas: bound_vars, lemma_body = lemma if not all( is_expr_fg_sort(bound_var, annctx=self.annctx) for bound_var in bound_vars): raise TypeError( 'Bound variables of lemma: {} must be of the foreground sort' .format(lemma_body)) recdef_indexed_lemmas = _sort_by_trigger( lemmas, list(recdef_unfoldings.keys())) if options.instantiation_mode == proveroptions.lean_instantiation_with_lemmas: # Recdefs and lemmas need to be treated separately using 'lean' instantiation fo_abstractions = axioms if options.instantiation_mode == proveroptions.lean_instantiation: # Recdefs need to be treated separately using 'lean' instantiation fo_abstractions = axioms | lemmas else: # If the instantiation isn't the 'lean' kind then all defs are going to be instantiated with all terms fo_abstractions = axioms | untagged_unfoldings | lemmas # All parameters have been set appropriately. Begin constructing instantiations # Negate the goal neg_goal = z3.Not(goal) # Create a solver object and add the goal negation to it z3solver = z3.Solver() z3solver.add(neg_goal) # Keep track of terms in the quantifier-free problem given to the solver initial_terms = get_foreground_terms(neg_goal, annctx=self.annctx) extraction_terms = initial_terms recdef_application_terms = get_recdef_applications(neg_goal, annctx=self.annctx) instantiation_terms = set() # Instantiate and check for provability according to options # Handle manual instantiation mode first if options.instantiation_mode == proveroptions.manual_instantiation: terms_to_instantiate = options.terms_to_instantiate instantiations = instantiate(fo_abstractions, terms_to_instantiate) if instantiations != set(): instantiation_terms = terms_to_instantiate extraction_terms = extraction_terms.union( get_foreground_terms(instantiations, annctx=self.annctx)) z3solver.add(instantiations) if_sat = _solver_check(z3solver) model = z3solver.model() if if_sat else None return NPSolution(if_sat=if_sat, model=model, extraction_terms=extraction_terms, instantiation_terms=instantiation_terms, options=options) # Automatic instantiation modes # stratified instantiation strategy if options.instantiation_mode == proveroptions.depth_one_stratified_instantiation: conservative_fo_abstractions = axioms | untagged_unfoldings tracked_instantiations = instantiate(conservative_fo_abstractions, initial_terms) if tracked_instantiations != set(): instantiation_terms = initial_terms tracked_terms = get_foreground_terms(tracked_instantiations, annctx=self.annctx) extraction_terms = extraction_terms.union(tracked_terms) z3solver.add(tracked_instantiations) untracked_instantiations = instantiate(lemmas, extraction_terms) if untracked_instantiations != set(): instantiation_terms = instantiation_terms.union( extraction_terms) untracked_terms = get_foreground_terms( untracked_instantiations, annctx=self.annctx) extraction_terms = extraction_terms.union(untracked_terms) other_instantiations = instantiate(conservative_fo_abstractions, extraction_terms) z3solver.add(untracked_instantiations) z3solver.add(other_instantiations) if_sat = _solver_check(z3solver) model = z3solver.model() if if_sat else None return NPSolution(if_sat=if_sat, model=model, extraction_terms=extraction_terms, instantiation_terms=instantiation_terms, options=options) # Set up initial values of variables depth_counter = 0 # Keep track of formulae produced by instantiation instantiations = set() # When the instantiation mode is infinite we realistically can't exceed 10^3 instantiations anyway target_depth = 1000 if options.instantiation_mode == proveroptions.infinite_depth else options.depth while depth_counter < target_depth: # Try to prove with available instantiations z3solver.add(instantiations) # If the instantiation mode is fixed depth we can continue instantiating until we get to that depth if options.instantiation_mode != proveroptions.fixed_depth: # Otherwise check satisfiability with current state of instantiations if_sat = _solver_check(z3solver) # If unsat, stop and return NPSolution instance if not if_sat: return NPSolution(if_sat=if_sat, model=None, extraction_terms=extraction_terms, instantiation_terms=instantiation_terms, depth=depth_counter, options=options) # target depth not reached or unsat not reached # Do another round of instantiations. # TODO: optimise instantiations so repeated instantiation is not done. Currently all instantiations # are done in every round. But optimisation is difficult in the presence of multiple arities. instantiation_terms = extraction_terms # Instantiate all basic abstractions instantiations = instantiate(fo_abstractions, instantiation_terms) # Instantiate other abstractions depending on instantiation mode. Typically recdefs and lemmas if options.instantiation_mode in { proveroptions.lean_instantiation, proveroptions.lean_instantiation_with_lemmas }: # Add recursive definition instantiations to the set of all instantiations for recdef, application_terms in recdef_application_terms.items( ): lean_instantiations = instantiate( recdef_unfoldings[recdef], application_terms) instantiations.update(lean_instantiations) if options.instantiation_mode == proveroptions.lean_instantiation_with_lemmas: # Add lemma instantiations to the set of all instantiations for recdef, application_terms in recdef_application_terms.items( ): triggered_lemmas = recdef_indexed_lemmas.get(recdef, []) triggered_instantiations = instantiate( triggered_lemmas, application_terms) instantiations.update(triggered_instantiations) # If the set of instantiations is empty exit the loop if instantiations == set(): instantiation_terms = set() break # Update the variables for the next round depth_counter = depth_counter + 1 new_terms = get_foreground_terms(instantiations, annctx=self.annctx) recdef_application_terms = get_recdef_applications( instantiations, annctx=self.annctx) extraction_terms = extraction_terms.union(new_terms) # Reach this case when depth_counter = target depth, either in fixed_depth or bounded_depth mode. # Final attempt at proving goal z3solver.add(instantiations) if_sat = _solver_check(z3solver) model = z3solver.model() if if_sat else None return NPSolution(if_sat=if_sat, model=model, extraction_terms=extraction_terms, instantiation_terms=instantiation_terms, depth=depth_counter, options=options)
def get_small_model(clauses, sorts_to_minimize, relations_to_minimize, final_cond=None, shrink=True): """ Return a HerbrandModel with a "small" model of clauses. sorts_to_minimize is a list of sorts, and relations_to_minimize is a list of relations, The model minimization occurs in 2 ways: First, minimize universe size lexicographically according to the order of sorts_to_minimize. Second, minimize the number of positive entries in the relations according to the order of relations_to_minimize. The parameter final_cond can be a list of objects have the following interface: cond(): returns a final condition as a clauses object start(): called before starting sat(): called if sat, return True if should ignore result unsat() : called if unsat assume() : if returns true, assume rather than check """ s = z3.Solver() s.add(clauses_to_z3(clauses)) # res = decide(s) # if res == z3.unsat: # return None if final_cond is not None: if isinstance(final_cond, list): res = z3.unsat for fc in final_cond: fc.start() if fc.assume(): s.add(clauses_to_z3(fc.cond())) else: s.push() s.add(clauses_to_z3(fc.cond())) res = decide(s) if res != z3.unsat: if fc.sat(): res = z3.unsat else: break else: fc.unsat() s.pop() else: s.add(clauses_to_z3(final_cond)) res = decide(s) else: res = decide(s) if res == z3.unsat: return None if shrink: print "searching for a small model...", sys.stdout.flush() for x in chain(sorts_to_minimize, relations_to_minimize): for n in itertools.count(1): s.push() sc = size_constraint(x, n) s.add(formula_to_z3(sc)) res = decide(s) if res == z3.sat: break else: s.pop() print "done" m = get_model(s) # print "model = {}".format(m) # f = open("ivy.smt2","w") # f.write(s.to_smt2()) # f.close() h = HerbrandModel(s, m, used_symbols_clauses(clauses)) return h
def __init__(self, spec: TyrellSpec, loc=None, sym_breaker=False, break_sym_online=False): self.z3_solver = z3.Solver() self.z3_solver.set('random_seed', 7) self.z3_solver.set('sat.random_seed', 7) # productions that are leaves self.leaf_productions = [] self.line_productions = [] # for learning self.program2tree = {} # z3 variables for each production node self.variables = [] self.spec = spec self.num_constraints = 0 self.num_variables = 0 self.sym_breaker = sym_breaker self.break_sym_online = break_sym_online if loc <= 0: raise ValueError(f'LOC cannot be non-positive: {loc}') self.start_time = time.time() self.loc = loc self.parentId = dict() if self.sym_breaker: if self.loc > 2: root = Node(1) root.h = 1 id, tree = self.create_clean_tree(1, root) tree.insert(0, root) self.cleanedTree = tree self.symFinder = SymmetryFinder(self.loc) self.lattices = dict() if self.loc > 2 and not self.break_sym_online: self.find_lattices() self.cleanedModel = dict() self.num_prods = self.spec.num_productions() self.max_children = self.max_children() self.find_types() self.init_leaf_productions() self.init_line_productions() self.linesVars = [] self.typeVars = [] self.line_vars_by_line = defaultdict(list) self.roots, self.leafs = self.build_trees() self.model = None # Times self.symTime = 0 self.totalSymTime = 0 self.solverTime = 0 self.blockedModels = 0 self.totalBlockedModels = 0 self.modelConstraint = 0 self.create_output_constraints() self.create_lines_constraints() self.create_type_constraints() self.create_children_constraints() self._production_id_cache = defaultdict(set) for p in self.spec.productions(): if p.is_enum(): self._production_id_cache[p._get_rhs()].add(p.id) self.resolve_predicates(self.spec.predicates()) logger.info('Number of Nodes: {} '.format(len(self.roots + self.leafs))) logger.info('Number of Variables: {}'.format( len(self.variables + self.typeVars + self.linesVars))) logger.info('Number of Constraints: {}'.format(self.num_constraints)) logger.info('Time spent encoding: {}'.format(time.time() - self.start_time)) res = self.z3_solver.check() if res != z3.sat: logger.warning( f"There is no solution for current loc ({self.loc}).") return self.model = self.z3_solver.model() self.get_model_constraint()
def __init__(self, eqns=None): self.eqns = [] self.locs = [] self.solver = z3.Solver() if eqns: self.add(eqns) self._ctr = 0
def getString(tar): v1 = z3.BitVec('v1', 32) v2 = z3.BitVec('v2', 32) v3 = z3.BitVec('v3', 32) s = z3.Solver() lol = "BCDGPTVZ" tar0 = lol.index(tar[0]) tar1 = lol.index(tar[1]) tar2 = lol.index(tar[2]) tar3 = lol.index(tar[3]) tar4 = lol.index(tar[4]) tar5 = lol.index(tar[5]) tar6 = lol.index(tar[6]) tar7 = lol.index(tar[7]) tar8 = lol.index(tar[8]) tar9 = lol.index(tar[9]) tar10 = lol.index(tar[10]) tar11 = lol.index(tar[11]) tar12 = lol.index(tar[12]) tar13 = lol.index(tar[13]) tar14 = lol.index(tar[14]) tar15 = lol.index(tar[15]) tar16 = lol.index(tar[16]) tar17 = lol.index(tar[17]) tar18 = lol.index(tar[18]) tar19 = lol.index(tar[19]) tar20 = lol.index(tar[20]) tar21 = lol.index(tar[21]) tar22 = lol.index(tar[22]) tar23 = lol.index(tar[23]) tar24 = lol.index(tar[24]) tar25 = lol.index(tar[25]) tar26 = lol.index(tar[26]) tar27 = lol.index(tar[27]) tar28 = lol.index(tar[28]) tar29 = lol.index(tar[29]) tar30 = lol.index(tar[30]) tar31 = lol.index(tar[31]) s.add(v2 >> 0x1F & 0x1 | v3 >> 0x0 & 0x3 == tar0) s.add(v1 >> 0x09 & 0x7 == tar1) s.add(v3 >> 0x05 & 0x7 == tar2) s.add(v3 >> 0x08 & 0x7 == tar3) s.add(v1 >> 0x15 & 0x7 == tar4) s.add(v1 >> 0x06 & 0x7 == tar5) s.add(v3 >> 0x1D & 0x7 == tar6) s.add(v1 >> 0x1B & 0x7 == tar7) s.add(v2 >> 0x04 & 0x7 == tar8) s.add(v2 >> 0x0D & 0x7 == tar9) s.add(v2 >> 0x0A & 0x7 == tar10) s.add(v3 >> 0x1A & 0x7 == tar11) s.add(v2 >> 0x16 & 0x7 == tar12) s.add(v3 >> 0x17 & 0x7 == tar13) s.add(v2 >> 0x1C & 0x7 == tar14) s.add(v3 >> 0x14 & 0x7 == tar15) s.add(v2 >> 0x01 & 0x7 == tar16) s.add(v3 >> 0x11 & 0x7 == tar17) s.add(v1 >> 0x00 & 0x7 == tar18) s.add(v2 >> 0x13 & 0x7 == tar19) s.add(v1 >> 0x18 & 0x7 == tar20) s.add(v3 >> 0x0B & 0x7 == tar21) s.add(v2 >> 0x19 & 0x7 == tar22) s.add(v2 >> 0x10 & 0x7 == tar23) s.add(v1 >> 0x03 & 0x7 == tar24) s.add(v1 >> 0x12 & 0x7 == tar25) s.add(v1 >> 0x0F & 0x7 == tar26) s.add(v3 >> 0x02 & 0x7 == tar27) s.add(v1 >> 0x0C & 0x7 == tar28) s.add(v2 >> 0x07 & 0x7 == tar29) s.add(v3 >> 0x0E & 0x7 == tar30) s.add(v1 >> 0x1E & 0x3 | v2 >> 0x00 & 0x1 == tar31) ## s.add(v1 < 1000) ## s.add(v2 < 1000) ## s.add(v3 < 1000) #print s s.check() return [ s.model()[v1].as_long(), s.model()[v2].as_long(), s.model()[v3].as_long() ]
def initialize(_sketch, _holes, _hole_options, symmetries, differents, _formulae, _mc_formulae, _mc_formulae_alt, _thresholds, _accept_if_above, optimality_setting): Family._sketch = _sketch Family._holes = _holes Family._hole_options = _hole_options # map holes to their indices Family.hole_list = list(Family._holes.keys()) Family._hole_indices = dict() for hole_index, hole in enumerate(Family.hole_list): Family._hole_indices[hole] = hole_index # map hole options to their indices Family._hole_option_indices = dict() for hole, options in Family._hole_options.items(): indices = dict() k = 0 for option in options: indices[option] = k k += 1 Family._hole_option_indices[hole] = indices # initialize z3 solver Family._solver = z3.Solver() Family._solver_meta_vars = OrderedDict() variables = dict() for k, v in Family._hole_options.items(): # create integer variable var = z3.Int(k) # store the variable Family._solver_meta_vars[var] = k variables[k] = var # add constraints for the hole assignments Family._solver.add(var >= 0) Family._solver.add(var < len(v)) # encode restrictions if symmetries is not None: for sym in symmetries: for x, y in zip(sym, sym[1:]): Family._solver.add(variables[x] < variables[y]) if differents is not None: for diff in differents: for idx, x in enumerate(diff): for y in diff[idx + 1:]: Family._solver.add(variables[x] != variables[y]) # store formulae info Family._formulae = _formulae Family._mc_formulae = _mc_formulae Family._mc_formulae_alt = _mc_formulae_alt Family._thresholds = _thresholds Family._accept_if_above = _accept_if_above Family._optimality_setting = optimality_setting # build quotient MDP quotient_builder = JaniQuotientBuilder(Family._sketch, Family._holes) Family._quotient_container = quotient_builder.construct( Family._hole_options, remember=set()) Family._quotient_container.prepare(Family._mc_formulae, Family._mc_formulae_alt) Family._quotient_mdp = Family._quotient_container.mdp_handling.full_mdp Family._quotient_mdp_stats = (Family._quotient_mdp_stats[0] + Family._quotient_mdp.nr_states, Family._quotient_mdp_stats[1] + 1) logger.debug( f"Constructed MDP of size {Family._quotient_mdp.nr_states}.")
def __init__(self, worldmap=World(), curTime=0, tasks=[]): self.tasks = tasks self.world = worldmap self.globalTime = curTime self.solver = z3.Solver()
def __init__(self, y): self.y = y self.equations = z3.Solver() self.sc = {'s1': z3.Real('s1'), 's2': z3.Real('s2'), 's3': z3.Real('s3'), 's4': z3.Real('s4')}
def solve(): f = z3.parse_smt2_file(OUTPUT_PATH) s = z3.Solver() s.add(f) return (s, str(s.check()))
def schedule(nurses, surgeries, monthTable, clientTable, monthInfo, surgeryTimeTable): solver = z3.Solver() grid = dict() result = dict() for date in clientTable.keys(): # night nightNurses = list() for groupi in range(1, groupNumPerNight + 1): for nuri in range(1, nurseNumPerGroup + 1): value = z3.Int("night_%sgroup_%dnur_%d" % (date, groupi, nuri)) grid[(date, groupi, nuri)] = value nightNurses.append(value) # constraint: make sure the nurses in night are the same as monthTable solver.add(value == int(monthTable[date][groupi - 1][nuri - 1])) # surgery for surgeryID in clientTable[date]: nightAndDayNurses = list(nightNurses) # nightAndDayNurses = [value for value in nightNurses] for nurseType in nurseTypes: value = z3.Int("day_%ssid_%stype_%s" % (date, surgeryID, nurseType)) grid[(date, surgeryID, nurseType)] = value # department of surgery nurseIDs = clientTable[date][surgeryID] surgery = surgeries[surgeryID] orListForDepartment = list() # constraint: make sure all of the nurses come from client for nurseID in nurseIDs: nurse = nurses[nurseID] if matchDepartment(surgery, nurse): # constraint: make sure the department of nurse matches with surgery orListForDepartment.append( z3.Or(value == int(nurseID))) # constraint: make sure the department of nurse matches with surgery # constraint: make sure all of the nurses come from client solver.add(z3.Or(orListForDepartment)) nightAndDayNurses.append(value) # constraint: make sure nurses working for day are not working for night solver.add(z3.Distinct(nightAndDayNurses)) # solver.add(z3.Eqel) # constraint: make sure the number of surgeries is limited by work hours for nurseID in nurses.keys(): for date in clientTable.keys(): dayNursesConstraint = list() for surgeryID in clientTable[date]: for nurseType in nurseTypes: value = grid[(date, surgeryID, nurseType)] dayNursesConstraint.append((value == int(nurseID), 1)) #<type 'unicode'> if nurses[nurseID].is_pregnant == "true": solver.add(z3.PbLe(dayNursesConstraint, 1)) else: solver.add(z3.PbLe(dayNursesConstraint, 1)) # # constraint: make sure nurses are different in the same time # for surIDs in surgeryTimeTable : # sameTimeNurses = list() # for surID in surIDs : # for nurseType in nurseTypes : # value = grid[(surgeries[surID].date, surID, nurseType)] # sameTimeNurses.append(value) # # constraint: make sure nurses are different in the same time # solver.add(z3.Distinct(sameTimeNurses)) # check sat if solver.check() != z3.sat: print "unsat" return None else: print "sat" # get the model model = solver.model() # get the result for date in clientTable.keys(): dateTable = dict() nightNurses = list() for groupi in range(1, groupNumPerNight + 1): for nuri in range(1, nurseNumPerGroup + 1): nurseID = str(model[grid[(date, groupi, nuri)]].as_long()) nightNurses.append(nurseID) # assert assert nurseID == monthTable[date][groupi - 1][nuri - 1] dateTable["night"] = nightNurses dayTable = dict() for surgeryID in clientTable[date]: surgeryNurses = dict() for nurseType in nurseTypes: surgeryNurses[nurseType] = str( model[grid[date, surgeryID, nurseType]].as_long()) # print model[grid[date, surgeryID, nurseType]].as_long() # print nurses[str(surgeryNurses[nurseType])].priority # constraint: make sure the qualification of roving nurse is higher than instrument nurse if nurses[surgeryNurses["instrument"]].priority > nurses[ surgeryNurses["roving"]].priority: temp = surgeryNurses["instrument"] surgeryNurses["instrument"] = surgeryNurses["roving"] surgeryNurses["roving"] = temp assert nurses[surgeryNurses["instrument"]].priority <= nurses[ surgeryNurses["roving"]].priority dayTable[surgeryID] = surgeryNurses dateTable["day"] = dayTable result[date] = dateTable return result pass
def __init__(self, context, network): self.ctx = context self.net = network self.solver = z3.Solver() self.constraints = list()
def execute(trial = False): startTime = datetime.datetime.now() # Set up the database connection. client = dml.pymongo.MongoClient() repo = client.repo repo.authenticate('debhe_shizhan0_wangdayu_xt', 'debhe_shizhan0_wangdayu_xt') schoolDict = {} subwayDict = {} distanceHi = 0.002 distanceLo = 0.000003 # Loads the collection schools = [] subwayStop = [] #schools = repo['debhe_shizhan0_wangdayu_xt.allSchool'].find() schools = repo['debhe_shizhan0_wangdayu_xt.schoolSubwayDistance'].find() subwayStop = repo['debhe_shizhan0_wangdayu_xt.subwayStop'].find() #schools = repo['debhe_shizhan0_wangdayu_xt.schoolSubwayDistanceTrial'].find() #subwayStop = repo['debhe_shizhan0_wangdayu_xt.subwayStopTrial'].find() # Need to make the deepcopy of record for further use schools_1 = copy.deepcopy(schools) schools_2 = copy.deepcopy(schools) schools_3 = copy.deepcopy(schools) listSchool = [] totalDistance = 0 maxLength = 0 for i in schools_3: temp = i['Distance'] totalDistance += temp if(temp > maxLength): maxLength = temp distanceLo = totalDistance / schools.count() distanceHi = maxLength + 0.000001 #print(distanceLo) # Compute all the schools that need a bike hub # For each school get the list of all the subway station that is in the certain range # create the system for the z3 solver for row_1 in schools_1: if(row_1['Distance'] < distanceLo): continue else: listSchool += [row_1['schoolName']] schoolDict[row_1['schoolName']] = [] subwayStop_temp = copy.deepcopy(subwayStop) for row_2 in subwayStop_temp: if(row_2['X'] != '""' and row_2['Y'] != '""' and row_1['schoolX'] != '""' and row_1['schoolY'] != '""'): s = (row_1['schoolName'], row_2['stopName'], (float(row_1['schoolX']) - float(row_2['X']))**2 + ( float(row_1['schoolY']) - float(row_2['Y']) )**2, row_2['id']) if(s[2] < distanceHi and s[2] > distanceLo): schoolDict[row_1['schoolName']] += [row_2['stopName']] #schoolDict_1 = copy.deepcopy(schoolDict) #print(len(schoolDict)) solver = z3.Solver() # Create the variables for the z3 solver allSchool = [[z3.Int(subStops) for subStops in schoolDict[s]] for s in listSchool] allSchool_1 = copy.deepcopy(allSchool) # Add the constraint (There must be at least one station that get assigned by a hub) solver.add(sum([sum(school) for school in allSchool_1]) > 0) # Add the constraint # For each school, there must be at least one station that get assigned by a hub for school in allSchool: solver.add(sum(school) > 0) for subStops in school: solver.add(subStops < 2) solver.add(subStops >= 0) # Optimization # We want to find the minimum number of stations that get assigned ''' minPlacementPossible = 199 for i in range(199, -1, -1): solver.push() solver.add(sum([sum(school) for school in allSchool_1]) < 20) if( str(solver.check()) == "sat"): minPlacementPossible = i solver.pop() ''' minPlacementPossible = 0 for i in range(9, -1, -1): solver.push() solver.add(sum([sum(school) for school in allSchool_1]) < (2**i + minPlacementPossible) ) #print(2**i) if( str(solver.check()) != 'unsat' ): minPlacementPossible += 2**i #print(minPlacementPossible) solver.pop() # Once we find the number, add it to the constraint solver.add(sum([sum(school) for school in allSchool_1]) < minPlacementPossible) #print(minPlacementPossible) print(solver.check()) placementResult = solver.model() #placementResult_1 = copy.deepcopy(placementResult) print(placementResult) #print(len(placementResult)) #print(placementResult[placementResult[0]]) # store the assignment to the database finalResult = [] assignCount = 0 for i in range(len(placementResult)): dic = {} stopNameParsed = str(placementResult[i]).replace(".","") assignment = str(placementResult[placementResult[i]]) dic[stopNameParsed] = assignment if(assignment == "1"): assignCount += 1 finalResult.append(dic) print(assignCount) # save the information to the database repo.dropCollection("optimizeBikePlacement") repo.createCollection("optimizeBikePlacement") repo['debhe_shizhan0_wangdayu_xt.optimizeBikePlacement'].insert_many(finalResult) repo['debhe_shizhan0_wangdayu_xt.optimizeBikePlacement'].metadata({'complete': True}) print("Saved optimizeBikePlacement", repo['debhe_shizhan0_wangdayu_xt.optimizeBikePlacement'].metadata()) repo.logout() endTime = datetime.datetime.now() return {"start":startTime, "end":endTime}
def isreachable_check(self, check, interval=None): logger.debug(f"Calculating whether all of the checks are reachable") solver = z3.Optimize() check_ports = check.get_ports() # build a mapping that shows the propagation of information to the guard (what influences the guard) modifier_map = self.get_modifier_map(check_ports) z3var_constraints, z3_vars = self.get_z3_vars(modifier_map) solver.add(z3var_constraints) if interval is None: solver.add(z3_vars['dt'] >= 0) logger.debug(f"Adding time start constraint: dt >= 0") else: interval = interval.resolve_infinitesimal() solver.add(interval.start_operator(z3_vars['dt'], interval.start)) # logger.debug(f"Adding time start constraint: {interval.start_operator(z3_vars['dt'], interval.start)}") if interval.end is not math.inf: # if it's infinity, just drop it... end = interval.end solver.add(interval.end_operator(z3_vars['dt'], end)) # logger.debug(f"Adding time end constraint: {interval.end_operator(z3_vars['dt'], end)}") # create the constraints for updates and influences for port, modifiers in modifier_map.items(): for modifier in modifiers: constraints = self._get_constraints_from_modifier( modifier, z3_vars) solver.add(constraints) conv = checklib.CheckZ3Converter(z3_vars) check_constraints = conv.convert(check) if logger.getEffectiveLevel( ) <= logging.DEBUG: # only log if the level is appropriate, since z3's string-conversion takes ages logger.debug(f"Check constraints: {check_constraints}") solver.add(check_constraints) objective = solver.minimize(z3_vars['dt']) # find minimal value of dt check = solver.check() # logger.debug("satisfiability: %s", check) if solver.check() == z3.sat: inf_coeff, numeric_coeff, eps_coeff = objective.lower_values() returnvalue = Epsilon(numeric_coeff, eps_coeff) logger.info( f"Minimum time to reach passing checks is {returnvalue}") return returnvalue elif check == z3.unknown: logger.warning( f"The calculation of the check reachability was UNKNOWN. This usually happening in the presence of non-linear constraints. Do we have any?" ) std_solver = z3.Solver() std_solver.add(solver.assertions()) std_solver_check = std_solver.check() if std_solver_check == z3.sat: min_dt = std_solver.model()[z3_vars['dt']] as_python = to_python(min_dt) logger.info( f"We did get a solution using the standard solver though: {as_python} Assuming that this is the smallest solution. CAREFUL THIS MIGHT BE WRONG!!!" ) return as_python elif std_solver_check == z3.unknown: logger.error( f"The standard solver was also not able to decide if there is a solution or not. The constraints are too hard!!!" ) return False else: logger.info( "The standard solver says there is no solution to the constraints. This means we also couldn't minimize. Problem solved." ) return False else: logger.debug(f"Constraint set to reach checks is unsatisfiable.") return False
def main(): N = 9 frames = [] for p in range(N): frames.append(z3.BitVec('cnt_%d' % p, 3)) def init(cnt): return (cnt == 0) def R(cnt, cntp): return (cntp == cnt + 1) def to_gray(cnt): return (cnt ^ z3.LShR(cnt, 1)) def hd(n1, n2): d = (n1 ^ n2) d0 = z3.ZeroExt(1, z3.Extract(0, 0, d)) d1 = z3.ZeroExt(1, z3.Extract(1, 1, d)) d2 = z3.ZeroExt(1, z3.Extract(2, 2, d)) return (d0 + d1 + d2) S = z3.Solver() S.add(init(frames[0])) checks = [] for p in range(1, N): # get count in previous step cnt_prev = frames[p - 1] # get count in current step. cnt_curr = frames[p] # ADD constraint to solver. S.add(R(cnt_prev, cnt_curr)) # get gray encoded version of count previous. gray_cnt_prev = to_gray(cnt_prev) # get gray encoded version of count current. gray_cnt_curr = to_gray(cnt_curr) # compute hamming distance b/w gray cnt prev and curr dist = hd(gray_cnt_prev, gray_cnt_curr) # check if this is not equal to one. check_curr = (dist != 1) # add to the list or checks. checks.append(check_curr) S.push() S.add(z3.Or(*checks)) result = S.check() if result == z3.unsat: print("Property HOLDS.") else: print("Property does not HOLD.") S.pop() S.push() # add a constraint stating that all the states must be distict # check for satisfiability and fix the condition below if True: # FIXME: change this condition. print('Reachability diameter not reached.') else: print('Reachability diameter reached.')
def __init__(self): self._ctx = z3.Context() self._solver = z3.Solver(ctx=self._ctx)
def new_solver(): return z3.Solver()
def synthesize_tests(dataset: Dataset, assumptions: Dict[str, str], combined_data: CombinedData): reset_all_tests() tea_logger = TeaLogger.get_logger() construct_all_tests(combined_data) global name stat_var_map = {} # Reorder variables so that y var is at the end combined_data._update_vars() # Compute unique statisical variable names from the combined data. combined_data_vars = [] for v in combined_data.vars: var = StatVar(v.metadata[name]) stat_var_map[v.metadata[name]] = var combined_data_vars.append(var) # Assume properties based on user assumptions and mode solver = z3.Solver() # s = Tactic('qflia').solver() assumed_props = assume_properties(stat_var_map, assumptions, solver, dataset, combined_data) # import pdb; pdb.set_trace() # Update the arity of test-level properties for prop in test_props: prop._update(len(combined_data.vars)) # Apply all tests to the variables we are considering now in combined_data for test in all_tests(): test.apply(*combined_data_vars) solver.push() # Create backtracking point model = None # Store model # For each test, add it to the solver as a constraint. # Add the tests and their properties for test in all_tests(): tea_logger.log_debug(f"\nCurrently considering {test.name}") solver.add(test.__z3__ == z3.And(*test.query())) solver.add(test.__z3__ == z3.BoolVal(True)) # Check the model result = solver.check() if result == z3.unsat: tea_logger.log_debug("Test is unsat.\n") solver.pop() elif result == z3.unknown: print("failed to solve") try: pass except z3.Z3Exception: return else: model = solver.model() test_invalid = False val = False # Does the test apply? # Would this ever be false?? if model and z3.is_true(model.evaluate(test.__z3__)): # Verify the properties for that test for prop in test._properties: if is_assumed_prop(assumed_props, prop): tea_logger.log_debug( f"User asserted property: {prop._name}.") val = True solver.add(prop.__z3__ == z3.BoolVal(val)) else: tea_logger.log_debug( f"Testing assumption: {prop._name}.") # Does this property need to hold for the test to be valid? # If so, verify that the property does hold if model and z3.is_true(model.evaluate(prop.__z3__)): val = verify_prop(dataset, combined_data, prop) if val: tea_logger.log_debug(f"Property holds.") else: # The property does not verify assert (val == False) tea_logger.log_debug(f"Property FAILS") # if not test_invalid: solver.pop() # remove the last test test_invalid = True model = None # else: # test is already invalid. Going here just for completeness of logging # tea_logger.log_debug(f"EVER GET HERE?") solver.add(prop.__z3__ == z3.BoolVal(val)) solver.push() # Push latest state as backtracking point solver.check() model = solver.model() # final model tests_to_conduct = [] # Could add all the test props first # Then add all the tests for test in all_tests(): if model and z3.is_true(model.evaluate(test.__z3__)): tests_to_conduct.append(test.name) elif not model: # No test applies pass # reset_all_tests() return tests_to_conduct
def mk(self, using_nla=False, myseed=None): return z3.Solver()
def generateTraces(self, maxNumberOfSolutions=3): def stateToRangeOfExistence(state, propositions, solution): try: stateIds = self.labelsToIds[state] except: return [] coveredTimesteps = [] for id in stateIds: coveredTimesteps += [ i for i in range( int(solution[propositions[id][0]].as_string()), int(solution[propositions[id][1]].as_string()) + 1) ] return coveredTimesteps allSolutions = [] # allEvents = [("message", i, j) for i in range(self.numMachines) for j in range(self.numMachines)] # allEvents += [("nodeRestart", i) for i in range(self.numMachines)] # allEvents = { allEvents[i] : i for i in range(len(allEvents)) } propositions = { node.eventId : (z3.Int("var_"+repr(node.eventId)+"_"+repr(node.label)+"_start"), z3.Int("var_"+repr(node.eventId)+"_"+repr(node.label)+"_end"))\ for node in self.nodes} sol = z3.Solver() self.lengthOfTrace = self.lengthOfLongestChain + 4 for node in self.nodes: propKey = node.eventId sol.add(propositions[propKey][0] <= propositions[propKey][1]) sol.add(propositions[propKey][0] >= 0) sol.add(propositions[propKey][1] <= self.lengthOfTrace) for pred in node.preds: if node.label[0] == self.idToNodes[pred].label[0]: sol.add(propositions[pred][1] + 1 == propositions[node.eventId][0]) else: sol.add((propositions[node.eventId][0] > propositions[pred][0])) if node.lastOnProcess == True: sol.add(propositions[propKey][1] == self.lengthOfTrace - 1) while len(allSolutions) < maxNumberOfSolutions and sol.check( ) == z3.sat: model = sol.model() allSolutions.append(model) forbidExistingSolution = [d() != model[d] for d in model] sol.add(z3.Or(forbidExistingSolution)) traces = [] allStates = [(machineId, stateKind, stateArg) for stateKind in ["expect", "ready"] for stateArg in range(self.numMachines) for machineId in range(self.numMachines)] allStates += [(machineId, ev) for machineId in range(self.numMachines) for ev in ["crash", "end"]] allStates = sorted(allStates) print({idx: allStates[idx] for idx in range(len(allStates))}) for solution in allSolutions: trace = [[0 for _ in range(len(allStates))] for _ in range(self.lengthOfTrace)] for idx, state in enumerate(allStates): coveredRange = stateToRangeOfExistence(state, propositions, solution) for trueTimestep in coveredRange: trace[trueTimestep][idx] = 1 traces.append(trace) return traces
#!/usr/bin/env python2 ## -*- coding: utf-8 -*- ## ## Triton ## import sys import z3 def sx(bits, value): sign_bit = 1 << (bits - 1) return (value & (sign_bit - 1)) - (value & sign_bit) ctx = z3.Context() s = z3.Solver() SymVar_0 = z3.BitVec('SymVar_0', 64) ref_693 = SymVar_0 ref_708 = ref_693 # MOV operation ref_15247 = ref_708 # MOV operation ref_15308 = ref_15247 # MOV operation ref_15322 = ((0x0 + ((ref_15308 + ((0x217E6161 * 0x1) & 0xFFFFFFFFFFFFFFFF)) & 0xFFFFFFFFFFFFFFFF)) & 0xFFFFFFFFFFFFFFFF) # LEA operation ref_15326 = ref_15247 # MOV operation ref_15340 = (0x217E6161 & ref_15326) # AND operation ref_15347 = (~(ref_15340) & 0xFFFFFFFFFFFFFFFF) # NOT operation ref_15349 = ((ref_15347 + ref_15322) & 0xFFFFFFFFFFFFFFFF) # ADD operation ref_15357 = ((ref_15349 + 0x1) & 0xFFFFFFFFFFFFFFFF) # ADD operation ref_27405 = ref_15357 # MOV operation ref_60810 = ref_27405 # MOV operation ref_65532 = ref_60810 # MOV operation ref_65540 = ref_65532 # MOV operation
if __name__ == "__main__": v_1 = z3.Real('v_1') l5 = z3.And(l2_T, v_1 == x) if __name__ == "__main__": v = z3.Real('v') for s in [z3.And(l3, v == v_0), z3.And(l5, v == v_1)]: z3.solve(x != 0, s) if __name__ == "__main__": v = z3.Real('v') l6 = z3.Or(z3.And(l3, v == v_0), z3.And(l5, v == v_1)) z3.solve(l6) if __name__ == "__main__": s = z3.Solver() s.add(l6) for i in range(5): if s.check() == z3.sat: m = s.model() x_val = m[x] print(m) else: print('no solution') break s.add(z3.Not(x == x_val)) s if __name__ == "__main__": s.add(x < 0) for i in range(5):
#!/usr/bin/env python3 import z3 import sys ctx = z3.Context() s = z3.Solver(ctx=ctx) queries = z3.parse_smt2_file(sys.argv[1]) k = int(sys.argv[2]) outfile = sys.argv[3] query = queries[k] with open(outfile, "w") as fout: fout.write("(assert\n" + query.sexpr() + "\n)\n")
def cons_sat(data_copy, zones, percent_max, percent_min, factor): # ----------------- Each parameter will look like this (r1-1, r1-2, ..., rk-k) ----------------- # ----------------- For example, r2-4 represents a route where the rider mey exit/enter in zone 2 and exit/enter in zone 4 ----------------- parameter_names_z = [] for i in range(1, zones + 1): for j in range(i, zones + 1): val = "r{0:d}".format(i) val += "-{0:d}".format(j) parameter_names_z.append(val) parameters_z = [z3.Real(n) for n in parameter_names_z] S = z3.Solver() projected_route_total = [0] * len(parameter_names_z) real_route_total = 0 for item in data_copy: for i in range(len(parameter_names_z)): dest_1 = int(parameter_names_z[i][1]) dest_2 = int(parameter_names_z[i][-1]) # ----------------- Find daily revenue based on data ----------------- # ----------------- This number will be the sum of the revenue from all route combinations ----------------- if item['zone'] == dest_1 or item['zone'] == dest_2: projected_route_total[i] += (float(item['population']) * (item['trans_percent'] / 100)) real_route_total += float( item['population']) * (item['trans_percent'] / 100) * 2.75 real_route_total = int(real_route_total) val = 0 for i in range(len(parameters_z)): val += (parameters_z[i] * projected_route_total[i]) # ----------------- Ensure that new fares for each route still == overall real revenue ----------------- S.add(val == real_route_total) for i in range(len(parameters_z)): val = (parameters_z[i] * projected_route_total[i]) / real_route_total # ----------------- Enusre new fares dont make one route responsible for more than 20% of revenue or less than 1% revenue ----------------- S.add(val < percent_max, val > percent_min) # ----------------- Ensure that routes between two zones with lower avg incomes pay less than routes between two zones with higher average income ----------------- for i in range(len(parameters_z)): outer_1 = int(parameter_names_z[i][1]) outer_2 = int(parameter_names_z[i][-1]) for j in range(i, len(parameters_z)): inner_1 = int(parameter_names_z[j][1]) inner_2 = int(parameter_names_z[j][-1]) # ----------------- E.g: r1-1 (1+1) < r3-4 (3+4); therefore r1-1 will have a higher fare than r3-4 ----------------- if (outer_1 + outer_2 < inner_1 + inner_2): S.add(parameters_z[i] > parameters_z[j]) # ----------------- Opposite of above ----------------- elif (outer_1 + outer_2 > inner_1 + inner_2): S.add(parameters_z[i] < parameters_z[j]) # ----------------- Ensure that the most expesnive route (r1-1) is at most 1.4 times the cheapest route (r5-5) ----------------- S.add(parameters_z[-1] * factor > parameters_z[0]) if str(S.check()) == 'unsat': return 'unsat' else: sat = S.model() new_fares = [] for i in range(len(sat)): route = sat[i].name() price = sat[sat[i]].as_decimal(2) if price[-1] == '?': price = price[:-1] temp_dict = {} temp_dict[route] = price new_fares.append(temp_dict) return new_fares
def synthesize(self, outputNames, cnsts, sim): """Main synthesizer.""" outs, y1s, y2s, y1cs, y2cs = self.createOutputExpressions(outputNames) input_vars = self.createInputVars() # let's create the initial instance. S = z3.Solver() # do we want unsat cores? if self.unsat_core: S.set(unsat_core=True) # constraints. self.addConstraints(S, cnsts) # let's now create the expression that states one of the outputs must be different. ys = [] for i, (y1, y2, y1c, y2c) in enumerate(itertools.izip(y1s, y2s, y1cs, y2cs)): yi = z3.Bool('y%d' % i) self.addExpr(S, yi == z3.Distinct(y1, y2), 'prob%d' % i) ys.append(yi) if y1c: assert y2c self.addExpr(S, y1c, 'cnst%d_1' % i) self.addExpr(S, y2c, 'cnst%d_2' % i) y = z3.Bool('y') self.addExpr(S, y == z3.Or(*ys), 'prob') # now for the actual solution loop. iterations = 0 # FIXME # y1mz3 = None # y2mz3 = None while S.check(y) == z3.sat: iterations += 1 m = S.model() if self.VERBOSITY >= 2: self.log('\niteration #%d' % iterations) self.dumpModel(m, y1s, y2s) sim_inputs = self.extractInputsFromModel(m, input_vars) sim_outputs = {} # FIXME sim signature. sim(sim_inputs, sim_outputs) if self.DEBUG: pass if self.VERBOSITY >= 2: self.log_dict('sim_inputs', sim_inputs) self.log_dict('sim_outputs', sim_outputs) def assertEquality(ocnst, name): n1 = 'out_%s_1_%d' % (name, iterations) n2 = 'out_%s_2_%d' % (name, iterations) if self.unsat_core: S.assert_and_track(ocnst == y1mz3, n1) S.assert_and_track(ocnst == y2mz3, n2) else: S.add(ocnst == y1mz3) S.add(ocnst == y2mz3) if self.VERBOSITY >= 4: self.log('out:' + repr(ocnst)) y1z3s, y2z3s = [], [] for name, out in itertools.izip(outputNames, outs): out.clearCache() y1mz3 = z3.simplify( out.toZ3Constraints(Synthesizer.P1, sim_inputs)) out.clearCache() y2mz3 = z3.simplify( out.toZ3Constraints(Synthesizer.P2, sim_inputs)) y1mz3c = out.z3ClausesWithConstraints(Synthesizer.P1, sim_inputs) y2mz3c = out.z3ClausesWithConstraints(Synthesizer.P2, sim_inputs) if y1mz3c: assert y2mz3c S.add(z3.simplify(y1mz3c)) S.add(z3.simplify(y2mz3c)) y1z3s.append(y1mz3) y2z3s.append(y2mz3) if self.VERBOSITY >= 4: self.log('#it:' + repr(iterations)) self.log('y1mz3:' + y1mz3.sexpr()) self.log('y2mz3:' + y2mz3.sexpr()) if self.outputTypes[name] == Synthesizer.BITVEC: assertEquality(z3.BitVecVal(sim_outputs[name], out.width), name) elif self.outputTypes[name] == Synthesizer.BOOL: assertEquality(z3.BoolVal(sim_outputs[name]), name) else: assert self.outputTypes[name] == Synthesizer.MEM assertEquality( ast.createConstantArray(out.awidth, out.dwidth, sim_outputs[name]), name) if iterations >= self.MAXITER: raise RuntimeError, 'Too many (%d) iterations executed.' % iterations if self.VERBOSITY >= 4 or self.DUMP_SMT2: filename = 'model%d.smt2' % iterations with open(filename, 'wt') as fileobj: print >> fileobj, S.to_smt2() # and finally we are done. if self.VERBOSITY >= 1: self.log('Finished after %d iteration(s).' % iterations) # now we need to extract solution result = S.check(z3.Not(y)) if result == z3.unsat and self.unsat_core: self.log('UNSAT core: ' + repr(S.unsat_core())) S.add(z3.Not(y)) assert result == z3.sat m = S.model() if self.VERBOSITY >= 3: self.log('model:' + repr(m)) for out in outs: out.clearCache() rs = [ self.cleanup(cnsts, outputNames[i], out.synthesize(m)) for i, out in enumerate(outs) ] for r in rs: r.clearCache() return rs
def check_bounds(lc, pre, rec, ref, bounds, z3_vars, bound2s, z3_var2s, v=0, progbar=False): all_z3_vars = z3_vars.copy() all_z3_vars.update(z3_var2s) ref2, _ = gen_rec_constraints(ref, z3_vars) s = z3.Solver() s2 = z3.Solver() s.set("timeout", 5000) s2.set("timeout", 5000) res = z3.sat # first check eq constraint won't cause timeouts: s.push() res = check_valid([], [], ref, ref2, pre, lc, rec, s) s.pop() if res == z3.unknown: ref, ref2 = [], [] valid_bounds = [] valid_bound2s = [] for bound, bound2 in tqdm(list(zip(bounds, bound2s))): s.push() res = check_valid(valid_bounds + [bound], valid_bound2s + [bound2], ref, ref2, pre, lc, rec, s) if res == z3.unsat: valid_bounds.append(bound) valid_bound2s.append(bound2) elif res == z3.unknown: ref = [] ref2 = [] else: # print('model',s.model()) pass s.pop() loop = range(len(bounds) + len(ref)) if progbar: loop = tqdm(loop) for i in loop: s.push() res1 = check_valid(bounds, bound2s, ref, ref2, pre, lc, rec, s) if v: print('check\n', s, res) if res1 == z3.unsat: if progbar: loop.update(1) break if res1 == z3.unknown: s.pop() ref = [] ref2 = [] continue m = s.model() try: model_constraint = [all_z3_vars[str(mi)] == m[mi] for mi in m] except KeyError: for mi in m: all_z3_vars[str(mi)] = z3.Int(str(mi)) model_constraint = [all_z3_vars[str(mi)] == m[mi] for mi in m] if v: print('model\n', m) s2.push() s2.add(model_constraint) if v: print('bounds') print(bounds) bound_sats = [] for bound, bound2 in zip(bounds, bound2s): s2.push() s2.add(bound, bound2) res = s2.check() bound_sats.append(res) if v: print('\t', bound, res) s2.pop() pruned_bounds = [] pruned_bound2s = [] for bound, bound2, bound_sat in zip(bounds, bound2s, bound_sats): if bound_sat == z3.sat or bound in valid_bounds: pruned_bounds.append(bound) pruned_bound2s.append(bound2) if len(pruned_bounds) == len(bounds): pruned_ref, pruned_ref2 = [], [] for eq_constr, eq_constr2 in zip(ref, ref2): s2.push() s2.add(eq_constr, eq_constr2) res = s2.check() if res == z3.sat: pruned_ref.append(eq_constr) pruned_ref2.append(eq_constr2) ref = pruned_ref ref2 = pruned_ref2 bounds = pruned_bounds bound2s = pruned_bound2s s.pop() s2.pop() if res1 != z3.unsat: # could not verify soundness, do not return any bounds bounds = valid_bounds return bounds