def assert_any_transition(s: Solver, t: Z3Translator, state_index: int, allow_stutter: bool = False) -> None: prog = syntax.the_program uid = str(state_index) tids = [] for transition in prog.transitions(): tid = z3.Bool(get_transition_indicator(uid, transition.name)) tids.append(tid) s.add( z3.Implies( tid, t.translate_expr( New(transition.as_twostate_formula(prog.scope), state_index)))) if allow_stutter: tid = z3.Bool(get_transition_indicator(uid, '$stutter')) tids.append(tid) frame = syntax.And(*DefinitionDecl._frame(prog.scope, mods=())) s.add(z3.Implies(tid, t.translate_expr(New(frame, state_index)))) s.add(z3.Or(*tids))
def baseoperationVisit(self, baseop): #TODO should go deeper. if issubclass(baseop.op, Lazy): return z3.Bool("bool!" + str(baseop.dimacs_var)) else: #print(baseop.args) res = [] blasted = baseop.op.apply(self.solver, *baseop.args) return retvisit(self,blasted) #TODO CLEAN #print(blasted) subargs = [] for i in blasted: subargs.append(retvisit(self, i)) return z3.And(subargs) sys.exit() flag = False for arg in blasted: subres = [] for subarg in arg: if isinstance(subarg, BoolConst): if subarg.val: flag = True break else: continue if subarg < 0: subres.append(z3.Not(z3.Bool(str(-subarg)))) else: subres.append(z3.Bool(str(subarg))) if flag: flag = False continue res.append(z3.Or(subres)) return z3.And(res)
def _init_z3_variables(self, valid, condition_invalid): # a vars: self.as_valid = {} self.as_invalid = {} for ex in valid: self.as_valid[ex] = z3.Bool(self._get_a_var_name(ex, valid=True)) for ex in condition_invalid: self.as_invalid[ex] = z3.Bool(self._get_a_var_name(ex, valid=False)) # s vars: self.ss_valid = {} self.ss_invalid = {} for cap_idx in range(self.num_captures): for ex in valid: self.ss_valid[(cap_idx, ex)] = z3.Bool( self._get_s_var_name(cap_idx, ex, True)) for ex in condition_invalid: self.ss_invalid[(cap_idx, ex)] = z3.Bool( self._get_s_var_name(cap_idx, ex, False)) # u vars self.us = {} for cond in self.conditions: for cap_idx in range(self.num_captures): self.us[(cap_idx, cond)] = z3.Bool(self._get_u_var_name(cap_idx, cond)) # bounds self.bounds = {} for cap_idx in range(self.num_captures): for cond in self.conditions: bound = z3.Int(f"cap{cap_idx}_{cond}") self.bounds[(cap_idx, cond)] = bound
def merge_queries_new_pred(clauses, queries, decls): if len(queries) > 1: false1 = z3.Bool("CHC_COMP_FALSE") decls.add(false1.decl()) for query in queries: assert (z3.is_quantifier(query) and query.is_forall()) qvars = [ z3.Const(query.var_name(n), query.var_sort(n)) for n in range(0, query.num_vars()) ] body = query.body() assert (body.decl().kind() == z3.Z3_OP_IMPLIES) kids = body.children() assert (kids[1] == z3.BoolVal(False)) newBody = z3.Implies(kids[0], false1) newClause = z3.ForAll(qvars, newBody) clauses.append(newClause) queries.clear() queries.append( z3.ForAll(z3.Bool("CHC_COMP_UNUSED"), z3.Implies(z3.And(false1), z3.BoolVal(False))))
def solve(grid): """ . . . .1.1. . .3. """ s = z3.Solver() # Construct atoms to represent the dots Dot = z3.Datatype("Dot") for d in grid.dots(): Dot.declare("dot_{}".format(d)) Dot = Dot.create() dot_atom = {d: getattr(Dot, "dot_{}".format(d)) for d in grid.dots()} # Booleans for each of the points dot = {d: z3.Bool("dot-{}".format(d)) for d in grid.dots()} # Booleans for each of the connectors line = {l: z3.Bool("line-{}".format(l)) for l in grid.lines()} # For each point: if it is on, it must have precisely two adjoining lines activated # If it's off, then there are zero adjoining lines activated bool_to_int = z3.Function("bool_to_int", z3.BoolSort(), z3.IntSort()) s.add(bool_to_int(True) == 1) s.add(bool_to_int(True) != 0) s.add(bool_to_int(False) == 0) s.add(bool_to_int(False) != 1) for d in grid.dots(): # Get all lines coming out of this dot ls = [line[l] for l in d.lines()] sm = z3.Sum(*(bool_to_int(l) for l in ls)) s.add(z3.Implies(dot[d], sm == 2)) s.add(z3.Implies(z3.Not(dot[d]), sm == 0)) # For each line: if it is activated, then the points at both ends are activated for l in line: d1, d2 = l.ends() s.add(z3.Implies(line[l], z3.And(dot[d1], dot[d2]))) # "Is connected to" relationship connected = z3.Function("connected", Dot, Dot, z3.BoolSort()) # For each line: # The Dot at each end is connected to the other iff the line is activated for d1 in grid.dots(): for d2 in grid.dots(): a = dot_atom[d1] b = dot_atom[d2] if (l := grid.line(d1, d2)) is None: # These dots are never connected s.add(connected(a, b) != True) else: s.add(z3.Implies(line[l], connected(a, b))) s.add(z3.Implies(z3.Not(line[l]), z3.Not(connected(a, b))))
def trivial_check(sat_formula: z3.ExprRef, vars: Iterable[int]) -> Optional[Formula]: s = z3.Solver() s.add(sat_formula) if s.check(*[z3.Bool('M' + str(x)) for x in vars]) == z3.sat: return And([]) if s.check(*[z3.Not(z3.Bool('M' + str(x))) for x in vars]) == z3.sat: return Or([]) return None
def __init__(self, name, fabric, width, height): super().__init__(name, fabric) self._width = width self._height = height self._d0 = z3.Bool(name + '_d0') self._d90 = z3.Bool(name + '_d90') self._d180 = z3.Bool(name + '_d180') self._d270 = z3.Bool(name + '_d270') self._horiz_var = z3.Int(name + '_horiz') self._vert_var = z3.Int(name + '_vert')
def evaluateUpdateFunction(aVars, rVars, geneValues, counter): i = counter intermediateValueVariablesA = [ z3.Bool("va%i_%i" % (j, i)) for j in range(7) ] intermediateValueVariablesR = [ z3.Bool("vr%i_%i" % (j, i)) for j in range(7) ] def andConstraints(symVars, variables, pi, c1i, c2i): return z3.Implies( symVars[pi] == z3.BitVecVal(AND, 32), variables[pi] == z3.And(variables[c1i], variables[c2i])) def orConstraints(symVars, variables, pi, c1i, c2i): return z3.Implies( symVars[pi] == z3.BitVecVal(OR, 32), variables[pi] == z3.Or(variables[c1i], variables[c2i])) def variableConstraints(symVars, intermediateVars): def f(symVar, i): return z3.And([ z3.Implies( symVar == v, intermediateVars[i] == z3.BoolVal(geneValues[v - 2])) for v in range(2, NOTHING) ]) return z3.And([f(symVars[i], i) for i in range(7)]) circuitVal = z3.Bool("circuit_%i" % i) def circuitValue(): noRepressors = rVars[0] == NOTHING return z3.If(noRepressors, intermediateValueVariablesA[0], \ z3.And(intermediateValueVariablesA[0], z3.Not(intermediateValueVariablesR[0]))) return (z3.And([variableConstraints(aVars, intermediateValueVariablesA), \ variableConstraints(rVars, intermediateValueVariablesR), \ andConstraints(aVars, intermediateValueVariablesA, 0, 1, 2), \ andConstraints(aVars, intermediateValueVariablesA, 1, 3, 4), \ andConstraints(aVars, intermediateValueVariablesA, 2, 5, 6), \ andConstraints(rVars, intermediateValueVariablesR, 0, 1, 2), \ andConstraints(rVars, intermediateValueVariablesR, 1, 3, 4), \ andConstraints(rVars, intermediateValueVariablesR, 2, 5, 6), \ orConstraints(aVars, intermediateValueVariablesA, 0, 1, 2), \ orConstraints(aVars, intermediateValueVariablesA, 1, 3, 4), \ orConstraints(aVars, intermediateValueVariablesA, 2, 5, 6), \ orConstraints(rVars, intermediateValueVariablesR, 0, 1, 2), \ orConstraints(rVars, intermediateValueVariablesR, 1, 3, 4), \ orConstraints(rVars, intermediateValueVariablesR, 2, 5, 6), \ circuitVal == circuitValue()]), circuitVal)
def find_max_satisfiable_rule(self): """ Build a model that satisfies as many soft clauses as possible using MAX-SMT """ self.threshold_open = z3.Real('t') self.threshold_listen = z3.Real('u') t = self.threshold_open u = self.threshold_listen self.solver.add(0.0 < t) self.solver.add(t <= 1.0) self.solver.add(0.0 < u) self.solver.add(u <= 1.0) for run in range(len(self.belief_in_runs)): for bel, belief in enumerate(self.belief_in_runs[run]): soft = z3.Bool('b_{}_{}'.format(run, bel)) self.soft_constr_open.append(DummyVar(soft, run, bel, 1)) formula = z3.If(belief[0] > belief[1], belief[0] >= t, belief[1] >= t) if self.actions_in_runs[run][bel] != 0 : self.solver.add(z3.Or(soft, formula)) else: self.solver.add(z3.Or(soft, z3.Not(formula))) soft = z3.Bool('c_{}_{}'.format(run, bel)) self.soft_constr_listen.append(DummyVar(soft, run, bel, 2)) formula = z3.If(belief[0] > belief[1], belief[0] <= u, belief[1] <= u) if self.actions_in_runs[run][bel] == 0 : self.solver.add(z3.Or(soft, formula)) else: self.solver.add(z3.Or(soft, z3.Not(formula))) self.solver.add(self.threshold_open > 0.9) low_threshold = 0 total_soft_constr = len(self.soft_constr_open) + len(self.soft_constr_listen) high_threshold = len(self.soft_constr_open) + len(self.soft_constr_listen) final_threshold = -1 best_model = [] while low_threshold <= high_threshold: self.solver.push() threshold = (low_threshold + high_threshold) // 2 self.solver.add(z3.PbLe([(soft.literal, 1) for soft in (self.soft_constr_open+self.soft_constr_listen)], threshold)) result = self.solver.check() if result == z3.sat: final_threshold = threshold best_model = self.solver.model() high_threshold = threshold - 1 else: low_threshold = threshold + 1 self.solver.pop() return best_model
def p_plainDescript(p): """plainDescription : compRel | compRel EQ compRel | compRel NEQ compRel | compRel LT compRel | compRel GT compRel | compRel LE compRel | compRel GE compRel | ID LEFTFUNC paramlist RIGHTFUNC""" if len(p[1:]) == 1: p[0] = plainDescriptionAst( repText( p[1] ) , simpInfo ( z3e = z3.Bool(z3UniqueName()), z3vlist = [] ) ) # create z3var but uncontrolled elif len(p[1:]) == 3: p[0] = plainDescriptionAst( repText( p[1] + p[2] + p[3] ) , simpInfo ( z3e = z3.Bool(z3UniqueName()), z3vlist = [] ) ) # create z3var but uncontrolled elif len(p[1:]) == 4: iden, _ , paramlist , _ = p[1:] # function application # this is the place we add z3 variable # checking Type : for internal functions paramGenList = [] for func_name, argList in FunctionDeclList: argNo = len(argList) if func_name == iden: if len( paramlist ) != argNo: print 'Error: argNo required:',argNo, ' provided:',len(paramlist) exit(1) # for each arg, treat it differently print func_name,argList for paramIdx,param in enumerate(paramlist) : argType = argList[paramIdx] if argType == ArgTypeTs: paramGenList.append( '*' + param ) else: paramGenList.append( param ) break else: # not found paramGenList = [ '*'+x for x in paramlist ] # otherwise treated as all Ts Type print paramGenList applyText = ','.join( paramGenList ) # special handling if iden in ['SameAddress','SameData']: larg = paramlist[0] rarg = paramlist[1] sname = paramlist[2] lhint = 'AxiomFuncHint::{' + larg + 'AccType}' rhint = 'AxiomFuncHint::{' + rarg + 'AccType}' applyText += ',' + lhint + ',' + rhint # track expression using z3 z3vName = z3UniqueName() func_replace_val = z3.Bool(z3vName) func_repl_list = [func_replace_val] if iden in ['SameCore'] else [] z3vNameToFunc[z3vName] = (func_replace_val, repText( iden + ' ( ' + applyText + ' ) ' ) ) p[0] = plainDescriptionAst( repText( iden + ' ( ' + applyText + ' ) ' ) , simpInfo(z3e = func_replace_val, z3vlist = func_repl_list ) )
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 add_valid(self, new_valid: str): """ Add a new valid example to Capturer. """ match = self.compiled_re.fullmatch(new_valid) if match is None: logger.debug(f"Bad example: {new_valid}") return self.as_valid[new_valid] = z3.Bool( self._get_a_var_name(new_valid, valid=True)) for cap_idx in range(self.num_captures): self.ss_valid[(cap_idx, new_valid)] = \ z3.Bool(self._get_s_var_name(cap_idx, new_valid, True)) self.solver.add(self._make_a_constraints([new_valid], valid=True))
def to_constraint(feature, position, value): plus = z3.Bool(f'{feature} {position} +') minus = z3.Bool(f'{feature} {position} -') alpha = z3.Bool(f'alpha left right {feature}') if value == '+': return minus elif value == '-': return plus else: if position in {'left', 'right'}: return z3.Or(plus, minus, alpha) else: return z3.Or(plus, minus)
def infer_change(change_vsa): opt = z3.Optimize() output = {} idents_to_changes = {} complete_change = {} simplified_change = {} for feature, values in change_vsa.changes.items(): for value in values: idents_to_changes[f'input {feature} {value}'] = (feature, value) if feature not in output: output[feature] = [] output[feature].append(f'input {feature} {value}') if value in {'+', '-', '0'}: opt.add_soft(z3.Not(z3.Bool(f'input {feature} {value}'))) elif value != '0': opt.add_soft(z3.Not(z3.Bool(f'input {feature} {value}')), weight=2) for (feature1, values1), (feature2, values2) in product(change_vsa.changes.items(), repeat=2): for value1, value2 in product(values1, values2): if value1 in {'+', '-'} and value2 in {'+', '-'}: if ipa_data.implies(feature1, value1, feature2, value2): output[feature2].append(f'input {feature1} {value1}') for feature, explanations in output.items(): if feature in change_vsa.necessary_features: disjunction = [] for explanation in explanations: disjunction.append(z3.Bool(explanation)) opt.add(z3.Or(*disjunction)) if opt.check() == z3.sat: model = opt.model() for ident in model: if str(ident) in idents_to_changes and model[ident]: feature, value = idents_to_changes[str(ident)] if value != '0': simplified_change[feature] = value complete_change[feature] = value for implied_feature, implied_value in ipa_data.get_implied( feature, value): complete_change[implied_feature] = implied_value return complete_change, simplified_change else: print('Change is unsat, this should never happen')
def createVars(self): # self.taskVars is a dictionary that maps tasks to a table of # their variables. self.taskVars = {} for task in self.tasks: # For each table, the entry at -1 is the variable that # cooresponds to whether or not the task got done at all. self.taskVars[task] = {-1: z3.Bool(str(task))} for t in range(len(self.tasks)): # For each timestep t, the entry at t is whether the # task got done at that timestep. taskVarName = str(task) + "@" + str(t) self.taskVars[task][t] = z3.Bool(taskVarName) if self.debugPrint: print "Created Task Variables: " + str(self.taskVars)
def helper(x): if (x is None): return x elif (self.is_uninterpreted_fun(x)): match = [f[1] for f in funQ if f[0] is x] if (len(match) == 1): # found a match return match[0] else: rangeSort = x.decl().range() varName = '|$' + str(x) + '|' if (rangeSort == z3.RealSort()): newVar = z3.Real(varName) elif (rangeSort == z3.IntSort()): newVar = z3.Int(varName) elif (rangeSort == z3.BoolSort()): newVar = z3.Bool(varName) else: raise ExptRewriteFailure( 'unknown sort for range of uninterpreted function -- ' + varName + ' returns a ' + rangeSort + ' ?') funQ.append((x, newVar)) return newVar else: ch = x.children() newch = self.fun_to_var(ch, report) if (len(ch) != len(newch)): raise ExptRewriteFailure('Internal error') elif (len(newch) == x.decl().arity()): return x.decl().__call__(*newch) elif ((x.decl().arity() == 2) and (len(newch) > 2)): return reduce(x.decl(), newch) else: raise ExptRewriteFailure('Internal error')
def solve(self, verbose=False, assertion=None): solver = z3.Solver() if verbose: solver.set(unsat_core=True) for name, fact in self._facts: try: solver.assert_and_track(fact, z3.Bool(f"Fact: {name}")) except z3.z3types.Z3Exception: raise Exception(f"Fact {name} multiply defined") if assertion is not None: try: solver.assert_and_track(z3.Not(assertion), f"Assertion") except z3.z3types.Z3Exception: raise Exception(f"Assertion multiply defined") if verbose: print("Solving...") result = solver.check() if result == z3.sat: if verbose: print("SAT") return Solution(self, solver.model()) else: if verbose: print("UNSAT") core = solver.unsat_core() print("UNSAT Core has len", len(core)) print(core) return None
def get_z3_var(vartype, name, datatype_name=None, ctx=None): var = None if isinstance(vartype, z3.z3.DatatypeSortRef): # discrete values datatype var = z3.Const(name, vartype) elif vartype is Types.INT: var = z3.BitVec(name, 32, ctx=ctx) elif vartype is Types.INTEGER: var = z3.Int(name, ctx=ctx) elif vartype is Types.FLOAT: var = z3.FP(name, z3.Float32(), ctx=ctx) elif vartype is Types.REAL: var = z3.Real(name, ctx=ctx) elif vartype is Types.BOOL: var = z3.Bool(name, ctx=ctx) elif vartype is Types.STRING: var = z3.String(name, ctx=ctx) elif isinstance(vartype, list): datatype = _get_datatype_from_list(vartype, datatype_name) var = z3.Const(name, datatype) vartype = datatype else: raise ValueError( f"I do not know how to create a z3-variable for type {vartype} (name: {name})" ) assert var is not None, f"Var wasn't converted: vartype: {vartype}, name: {name}" var.type = vartype return var
def CheckDataIsolationPropertyCore(self, src, dest): class Result(object): def __init__(self, core): self.assertions = core assert (src in self.net.elements) assert (dest in self.net.elements) constraints = self.GetConstraints() p = z3.Const('check_isolation_p_%s_%s' % (src.z3Node, dest.z3Node), self.ctx.packet) n_0 = z3.Const('check_isolation_n_0_%s_%s' % (src.z3Node, dest.z3Node), self.ctx.node) n_1 = z3.Const('check_isolation_n_1_%s_%s' % (src.z3Node, dest.z3Node), self.ctx.node) t = z3.Int('check_isolation_t_%s_%s' % (src.z3Node, dest.z3Node)) constraints.append(self.ctx.recv(n_0, dest.z3Node, p, t)) constraints.append(self.ctx.packet.origin(p) == src.z3Node) print constraints self.solver.push() names = [] for constraint in constraints: n = z3.Bool('%s' % constraint) names += [n] self.solver.add(z3.Implies(n, constraint)) is_sat = self.solver.check(names) ret = None if is_sat == z3.sat: print "SAT" ret = Result(self.solver.model()) elif is_sat == z3.unsat: print "unsat" ret = Result(self.solver.unsat_core()) self.solver.pop() return ret
def create_param_map_for_query(thread_ctx, query): params = [] if isinstance(query, ReadQuery): if query.pred: params += query.pred.get_all_params() for v, f in query.aggrs: params += f.get_all_params() else: params += query.get_all_params() for i, p in enumerate(params): if is_int_type(p.tipe) or is_unsigned_int_type(p.tipe): v = z3.Int('param-{}-{}'.format(p.symbol, i)) elif is_bool_type(p.tipe): v = z3.Bool('param-{}-{}'.format(p.symbol, i)) elif is_float_type(p.tipe): v = z3.Real('param-{}-{}'.format(p.symbol, i)) elif is_string_type(p.tipe): v = z3.Int('param-{}-{}'.format(p.symbol, i)) else: assert (False) if not is_bool_type(p.tipe): thread_ctx.get_symbs().solver.add(v < INVALID_VALUE) thread_ctx.get_symbs().param_symbol_map[p] = v if isinstance(query, ReadQuery): for k, v in query.includes.items(): create_param_map_for_query(thread_ctx, v)
def __init__(self, name, test_vars, test_properties=None, properties_for_vars=None): global __test_map__, __ALL_TESTS__ self.name = name self.test_vars = test_vars if test_properties is None: test_properties = [] if properties_for_vars is None: properties_for_vars = {} self.test_properties = test_properties self.properties_for_vars = {} for key in properties_for_vars: # properties_for_vars is a list of lists of variables. Get the indices of the variables # in each list. for prop_args in properties_for_vars[key]: indices = [] # if self.name == 'pointbiserial_corr_a': # import pdb; pdb.set_trace() # if self.name == 'factorial_ANOVA': # import pdb; pdb.set_trace() indices = [self.test_vars.index(arg) for arg in prop_args] if key not in self.properties_for_vars.keys(): self.properties_for_vars[key] = [] self.properties_for_vars[key].append(indices) # Create variable. self.__z3__ = z3.Bool(self.name) # Populate global table. __test_map__[self.__z3__] = self __ALL_TESTS__.append(self)
def marco(Pk): print 'Starting to think about...', Pk sys.stdout.flush() solver = z3.Solver() P = [] for line_number in conjecture_line_numbers: P.append(z3.Bool('P_' + str(line_number))) out = [] while True: if solver.check() == z3.sat: m = solver.model() #seed = [conjecture_line_numbers[i] for i, Pi in enumerate(P) if m.eval(Pi, model_completion=True)] seed = [conjecture_line_numbers[i] for i, Pi in enumerate(P) if not z3.is_false(m[Pi])] #print 'Got seed:', seed if query(Pk, set(seed), set()): seed = shrink(Pk, seed) #print 'Shrank to:', seed, 'which works' out.append(seed) block = z3.Or([z3.Not(P[i]) for i, line_number in enumerate(conjecture_line_numbers) if line_number in seed]) #print 'Blocking:', block solver.add(block) else: seed = grow(Pk, seed) #print 'Grew to:', seed, 'which does not work' block = z3.Or([P[i] for i, line_number in enumerate(conjecture_line_numbers) if line_number not in seed]) #print 'Blocking:', block solver.add(block) else: #print out break print 'Fully analyzed...', Pk sys.stdout.flush() return out
def propagate_validity_bit(self): # structs can be contained in headers so they can also be deactivated... for member_name in self.members: member_val = self.resolve_reference(member_name) if isinstance(member_val, P4ComplexInstance): member_val.propagate_validity_bit() self.valid = z3.Bool(f"{self.name}_valid")
def checkLength(M, bad, count): fp = z3.Fixedpoint() options = {'engine': 'spacer'} fp.set(**options) addCounter(M) xs = M.variables sorts = M.sorts + [z3.BoolSort()] inv = z3.Function('inv', *sorts) err = z3.Bool('err') fp.register_relation(inv) fp.register_relation(err.decl()) fp.declare_var(*xs) bad_state = [z3.And(bad(xs) + [xs[-1] == count])] fp.rule(inv(*xs), M.init) fp.rule(inv(*M.tr), inv(*xs)) fp.rule(err, bad_state + [inv(*xs)]) r = fp.query(err) if r == z3.unsat: return (z3.unsat, None) else: return (z3.sat, len(inv.children()))
def visitCompare(self, node): children = node.getChildren() if len(children) == 3: left = node.getChildren()[0] op = str(node.getChildren()[1]) if op == "==" or op == "!=": right = node.getChildren()[2] left_z3 = self.visit(left) right_z3 = self.visit(right) if z3.is_string(left_z3) and z3.is_string( right_z3) or z3.is_bool(left_z3) and z3.is_bool( right_z3): if op == "==": result = z3.simplify( z3.Not(z3.Distinct(left_z3, right_z3))) return result elif op == "!=": # sys.stderr.write("%s != %s\n" % (left_z3, right_z3)) result = z3.simplify(z3.Distinct(left_z3, right_z3)) return result # elif z3.is_string(left_z3) and z3.is_bool(right_z3): # if op == "==": # pass # elif op == "!=": # pass # elif z3.is_bool(left_z3) and z3.is_string(right_z3): # if op == "==": # pass # elif op == "!=": # pass # this expression is not supported, so make a predicate variable for it predicate = str(node) return z3.Bool("PREDICATE_%s" % (predicate))
def p_quanexpr_exists(p): """expr : EXISTS ID COLON typelist BAR expr | EXISTS ID COLON typelist restriction BAR expr """ (_,varname,_,typelist) = tuple(p[1:4+1]) retBody = '' retVal = uniqueName() +'_L' retList = uniqueName() retBody += 'ZExprVec ' + retVal +';\n' retBody += 'for (auto && ' + varname + ' : ' + typelist + ' ) { // ' + ' '.join(p[1:5]) + '\n' CurrentVarAccType = 'CurrentVarAccType' QAccTypeName= varname + 'AccType' QAccType= "HINT_READ" if typelist == "READ_list" else ("HINT_WRITE" if typelist == "WRITE_list" else "HINT_NONE") VarAccessType = "READ" if typelist == "READ_list" else ("WRITE" if typelist == "WRITE_list" else "EITHER") nameKey = {QAccTypeName:QAccType , CurrentVarAccType:VarAccessType} retSimpleInfo = simpInfo(z3e = z3.Bool(z3UniqueName()), z3vlist = []) if len(p[1:]) == 7: # has restriction (_,_,_,typelist,restriction,_,e) = tuple(p[1:]) retBody += addTab( restriction[1].format(varname = varname) ) + '\n' # if ( ?? == x ) continue retBody += addTab( body(e) ) + '\n' # the body of inside expr = val(e) retBody += '\t' + restriction[2].format(expr = expr, varname = varname, OPANDIMPLY = 'And') # varX = z3.Implies( z3.And( ) , ... ) retBody += '\t' + retVal + '.push_back( ' + restriction[0] + '); }\n' retBody += 'ZExpr ' + retList + ' = Z3ExistsList( ' +retVal + ');\n' p[0] = ExprAst( retList, retBody.format(**nameKey) , simpleInfo = retSimpleInfo ) else: # 6 (_,_,_,typelist,_,e) = tuple(p[1:]) retBody += addTab( body(e) ) + '\n' expr = val(e) retBody += '\t' + retVal + '.push_back( ' + expr + ')\n' retBody += 'ZExpr ' + retList + ' = Z3ExistsList( ' +retVal + ')\n' p[0] = ExprAst( retList, retBody.format(**nameKey) , simpleInfo = retSimpleInfo )
def addTaskConstraints(self): htConstraints = [] for task in self.tasks: # Aggregate the variables indicating this task got done at # a particular time. taskAtTimes = [] for t in range(len(self.tasks)): intervalVars = [] # Did we do the task in any of our intervals? for i, (start, end) in enumerate(task.intervals): # Create a variable for getting done in the interval. intervalVar = z3.Bool( str(task) + "@" + str(t) + "_for_" + str(i)) # The task must be contained within the interval. htConstraints.append(Or(Not(intervalVar),\ self.timeVars[t] >= start)) htConstraints.append(Or(Not(intervalVar),\ self.timeVars[t] + self.world.duration(task.ID) <= end)) intervalVars.append(intervalVar) # For a task to get done at a particular time, that # time must be within one of our intervals. htConstraints.append(Or(Not(self.taskVars[task][t]),\ *intervalVars)) taskAtTimes.append(self.taskVars[task][t]) # For a task to get done at all, it has to get done at # some time. htConstraints.append(Or(Not(self.taskVars[task][-1]), *taskAtTimes)) for constraint in htConstraints: self.solver.add(constraint) if self.debugPrint: print "Added hard task constraints: " + str(htConstraints)
def create_field(size_x, size_y, transitions): field = [] for t in range(transitions): row = [[z3.Bool(f"{x}.{y};t{t}") for y in range(size_y)] for x in range(size_x)] field.append(row) return field
def p_quanexpr_forall(p): """expr : FORALL ID COLON typelist BAR expr | FORALL ID COLON typelist restriction BAR expr """ (_, varname, _, typelist) = tuple(p[1:4 + 1]) expr = p[7] if len(p[1:]) == 7 else p[6] retBody = '' retVal = uniqueName() + '_L' retList = uniqueName() retBody += 'ZExprVec ' + retVal + ';\n' retBody += 'for (auto && ' + varname + ' : ' + typelist + \ ') { ' + ' // ' + ' '.join(p[1:5]) + '\n' retSimpleInfo = simpInfo(z3e=z3.Bool(z3UniqueName()), z3vlist=[]) extra_restrict = static_determine( expr.simpleInfo.z3e, expr.simpleInfo.z3vlist, True) print extra_restrict CurrentVarAccType = 'CurrentVarAccType' QAccTypeName = varname + 'AccType' QAccType = "HINT_READ" if typelist == "READ_list" else ( "HINT_WRITE" if typelist == "WRITE_list" else "HINT_NONE") VarAccessType = "READ" if typelist == "READ_list" else ( "WRITE" if typelist == "WRITE_list" else "EITHER") nameKey = {QAccTypeName: QAccType, CurrentVarAccType: VarAccessType} if len(p[1:]) == 7: # has restriction (_, _, _, typelist, restriction, _, e) = tuple(p[1:]) # if ( ?? == x ) continue retBody += addTab(restriction[1].format(varname=varname)) + '\n' if extra_restrict: retBody += addTab(extra_restrict) # if( SameCore ... ) retBody += addTab(body(e)) + '\n' # the body of inside expr = val(e) # varX = z3.Implies( z3.And( ) , ... ) retBody += '\t' + \ restriction[2].format( expr=expr, varname=varname, OPANDIMPLY='Implies') retBody += '\t' + retVal + '.push_back( ' + restriction[0] + '); }\n' retBody += 'ZExpr ' + retList + ' = Z3ForallList( ' + retVal + ');\n' p[0] = ExprAst( retList, retBody.format( **nameKey), simpleInfo=retSimpleInfo) else: # 6 (_, _, _, typelist, _, e) = tuple(p[1:]) if extra_restrict: retBody += addTab(extra_restrict) # if( SameCore ... ) retBody += addTab(body(e)) + '\n' expr = val(e) retBody += '\t' + retVal + '.push_back( ' + expr + '); }\n' retBody += 'ZExpr ' + retList + ' = Z3ForallList( ' + retVal + ');\n' p[0] = ExprAst( retList, retBody.format( **nameKey), simpleInfo=retSimpleInfo)
def addStepCompressedConstraints(self): self.noneVars = [] clauses = [] # None at the step has to be true unless some task is true at # the step. for i in range(len(self.tasks)): self.noneVars.append(z3.Bool("None@" + str(i))) clauses.append(Or(self.noneVars[i],\ *[varTable[i] for var, varTable in self.taskVars.items()])) # If none is true at the step, then no task can be # true. Together, these two sets of constraints make up # bi-implication between the none variable, and no tasks being # accomplished at this step. for t in range(len(self.tasks)): for taskVar, varTable in self.taskVars.items(): clauses.append(Or(Not(self.noneVars[t]),\ Not(varTable[t]))) # If any none variable is true, then the one after it is # true. Because of transitivity, this means that all none # variables after it are true. for i in range(len(self.tasks) - 1): clauses.append(Or(Not(self.noneVars[i]), self.noneVars[i + 1])) for clause in clauses: if self.debugPrint: print "adding clause " + str(clause) self.solver.add(clause)