def test_tactics_z3(self): from z3 import Tactic, Then from pysmt.shortcuts import Iff my_tactic = Then(Tactic('simplify'), Tactic('propagate-values'), Tactic('elim-uncnstr')) for (f, validity, satisfiability, logic) in get_example_formulae(): if not logic.theory.linear: continue if not logic.quantifier_free: continue if logic.theory.bit_vectors: continue s = Solver(name='z3') z3_f = s.converter.convert(f) simp_z3_f = my_tactic(z3_f) simp_f = s.converter.back(simp_z3_f.as_expr()) v = is_valid(simp_f) s = is_sat(simp_f) self.assertEqual(v, validity, (f, simp_f)) self.assertEqual(s, satisfiability, (f, simp_f))
def test_z3_nary_back(self): from z3 import Tactic r = Symbol("r", REAL) s = Symbol("s", REAL) t = Symbol("t", REAL) f = Equals(Times(r,s,t), Real(0)) with Solver(name="z3") as solver: z3_f = solver.converter.convert(f) z3_f = Tactic('simplify', solver.z3.ctx)(z3_f).as_expr() fp = solver.converter.back(z3_f) self.assertValid(Iff(f, fp), (f, fp))
def simplify(self, condition): visit_result = self.visit(condition) if visit_result.sort().name() != "Bool": return visit_result result = Tactic("ctx-solver-simplify")(visit_result)[0] if len(result) == 0: return BoolVal(True) if len(result) < 2: return result[0] return And(*result)
def _flatten_conditions(self): log_debug( f"_flatten_conditions {self.condition} {self._condition_il!r}") if self[True] is None: return nodes = [ n for n in self[True].nodes if n.type != "block" or n.block[0].operation not in ( MediumLevelILOperation.MLIL_IF, MediumLevelILOperation.MLIL_GOTO, ) ] if any(n.type != "cond" for n in nodes): for node in nodes: log_debug(f"- {node}") return new_conditions = [] for node in nodes: if node[False] is not None: return log_debug(f"+ {node}") node._condition = reduce( And, Tactic("ctx-solver-simplify")(And(self._condition, node._condition))[0], ) log_debug(f"flattened condition: {node} -> {node._condition}") new_conditions.append(node) self.__class__ = MediumLevelILAstSeqNode self._type = "seq" self._nodes = sorted(new_conditions)
from z3 import Reals, Ints, Exists, ForAll, Or, And, Implies, Not from z3 import Tactic, Then, OrElse, Repeat, ParThen i, x, n = Ints('i x n') # i,x,n = Reals('i x n') h2 does not imply h #qe = Then(Tactic('qe'),Tactic('simplify'),Tactic('propagate-values'),Tactic('propagate-ineqs')) qe = Tactic('qe') f = Or(And(-i + x == 0, -i + n - 1 == 0, i - 2 >= 0), And(-n + x + 2 == 0, -i + n - 3 >= 0, i >= 0), And(x >= 0, n - x - 3 >= 0, i - x - 1 >= 0), And(-i + x == 0, -i + n - 2 == 0, i - 1 >= 0), And(-n + x + 1 == 0, -i + n - 2 >= 0, n - 3 >= 0, i >= 0), And(-i + x - 1 >= 0, n - x - 3 >= 0, i >= 0), And(-n + x + 1 == 0, n - 3 >= 0, i - n >= 0), And(-i + x == 0, -i + n - 3 >= 0, i >= 0)) g = And(n > 2, ForAll(x, Implies(And(x >= 0, x < n), f))) h = apply(And, qe(g)[0]) h2 = And(n > 2, i >= 0, i <= n - 2) #h2neg = Or(n<=2, i<=-1, i>=n-1) print qe(ForAll(x, Implies(h, h2))) print qe(ForAll(x, Implies(h2, h))) from z3 import solve solve(And(h, Not(h2))) solve(And(h2, Not(h))) simplify = Repeat(Then('nnf', 'ctx-solver-simplify')) h3 = apply(And, simplify(h)[0])
z0r, z2l, z2r), And(-k + z == 0, -i + x >= 0, -k + n - 1 >= 0, -x + y - 1 >= 0, k - y - 1 >= 0, i - 1 >= 0)), (And(Not(x0l), x0r, x2l, Not(x2r), Not(y0l), y0r, y2l, Not(y2r), Not(z0l), z0r, z2l, Not(z2r)), And(-i + x >= 0, -k + n - 1 >= 0, -x + y - 1 >= 0, -y + z - 1 >= 0, k - z - 1 >= 0, i - 1 >= 0)), (And(Not(x0l), x0r, x2l, Not(x2r), Not(y0l), y0r, y2l, Not(y2r), Not(z0l), z0r, Not(z2l), z2r), And(-i + x >= 0, -k + z - 1 >= 0, -x + y - 1 >= 0, n - z - 1 >= 0, k - y - 1 >= 0, i - 1 >= 0)), (And(Not(x0l), x0r, x2l, Not(x2r), Not(y0l), y0r, Not(y2l), y2r, Not(z0l), z0r, Not(z2l), z2r), And(-i + x >= 0, -k + y - 1 >= 0, -y + z - 1 >= 0, n - z - 1 >= 0, k - x - 1 >= 0, i - 1 >= 0)), (And(Not(x0l), x0r, Not(x2l), x2r, Not(y0l), y0r, Not(y2l), y2r, Not(z0l), z0r, Not(z2l), z2r), And(-i + k + 1 >= 0, -k + x - 1 >= 0, -x + y - 1 >= 0, -y + z - 1 >= 0, n - z - 1 >= 0, i - 1 >= 0)), (And(Not(x0l), Not(x0r), Not(x2l), Not(x2r), Not(y0l), Not(y0r), Not(y2l), Not(y2r), Not(z0l), Not(z0r), Not(z2l), Not(z2r)), And(i == 0, -x + y - 1 >= 0, -y + z - 1 >= 0, x >= 0, n - z - 1 >= 0)) ] qe = Tactic('qe') simplify = Repeat(Then('nnf', 'ctx-solver-simplify')) def simpl(f): return apply(And, Then(qe, simplify)(f)[0])
def conv_safety_solve(layer2Consider,nfeatures,nfilters,filters,bias,input,activations,prevSpan,prevNumSpan,span,numSpan,pk): random.seed(time.time()) # number of clauses c = 0 # number of variables d = 0 # variables to be used for z3 variable={} if nfeatures == 1: images = np.expand_dims(input, axis=0) else: images = input if len(activations.shape) == 3: avg = np.sum(activations)/float(len(activations)*len(activations[0])*len(activations[0][0])) elif len(activations[0].shape) == 2: avg = np.sum(activations)/float(len(activations)*len(activations[0])) else: avg = 0 s = Tactic('qflra').solver() s.reset() #print("%s\n%s\n%s\n%s"%(prevSpan,prevNumSpan,span,numSpan)) toBeChanged = [] if inverseFunction == "point": if nfeatures == 1: #print("%s\n%s"%(nfeatures,prevSpan.keys())) ks = [ (0,x,y) for (x,y) in prevSpan.keys() ] else: ks = copy.deepcopy(prevSpan.keys()) toBeChanged = toBeChanged + ks elif inverseFunction == "area": for (k,x,y) in span.keys(): toBeChanged = toBeChanged + [(l,x1,y1) for l in range(nfeatures) for x1 in range(x,x+cfg.filterSize) for y1 in range(y,y+cfg.filterSize) if x1 >= 0 and y1 >= 0 and x1 < images.shape[1] and y1 < images.shape[2]] toBeChanged = list(set(toBeChanged)) for (l,x,y) in toBeChanged: variable[1,0,l+1,x,y] = Real('1_x_%s_%s_%s' % (l+1,x,y)) d += 1 if not(cfg.boundOfPixelValue == [0,0]) and (layer2Consider == 0): pstr = eval("variable[1,0,%s,%s,%s] <= %s"%(l+1,x,y,cfg.boundOfPixelValue[1])) pstr = And(eval("variable[1,0,%s,%s,%s] >= %s"%(l+1,x,y,cfg.boundOfPixelValue[0])), pstr) pstr = And(eval("variable[1,0,%s,%s,%s] != %s"%(l+1,x,y,images[l][x][y])), pstr) s.add(pstr) c += 1 maxterms = "" for (k,x,y) in span.keys(): variable[1,1,k+1,x,y] = Real('1_y_%s_%s_%s' % (k+1,x,y)) d += 1 string = "variable[1,1,%s,%s,%s] == "%(k+1,x,y) for l in range(nfeatures): for x1 in range(cfg.filterSize): for y1 in range(cfg.filterSize): if (l,x+x1,y+y1) in toBeChanged: newstr1 = " variable[1,0,%s,%s,%s] * %s + "%(l+1,x+x1,y+y1,filters[l,k][x1][y1]) elif x+x1 < images.shape[1] and y+y1 < images.shape[2] : newstr1 = " %s + "%(images[l][x+x1][y+y1] * filters[l,k][x1][y1]) string += newstr1 string += str(bias[l,k]) s.add(eval(string)) c += 1 if cfg.enumerationMethod == "line": pstr = eval("variable[1,1,%s,%s,%s] < %s" %(k+1,x,y,activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] + cfg.epsilon)) pstr = And(eval("variable[1,1,%s,%s,%s] > %s "%(k+1,x,y,activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] - cfg.epsilon)), pstr) elif cfg.enumerationMethod == "convex" or cfg.enumerationMethod == "point": if activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] >= 0: upper = activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] + pk lower = -1 * (activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)]) - pk else: upper = -1 * (activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)]) + pk lower = activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] - pk #if span[(k,x,y)] > 0 : # upper = activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] + epsilon # lower = activations[k][x][y] - span[(k,x,y)] * numSpan[(k,x,y)] - epsilon #else: # upper = activations[k][x][y] - span[(k,x,y)] * numSpan[(k,x,y)] + epsilon # lower = activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] - epsilon #if span[(k,x,y)] > 0 : # upper = activations[k][x][y] + span[(k,x,y)] + epsilon # lower = activations[k][x][y] - epsilon - span[(k,x,y)] #else: # upper = activations[k][x][y] + epsilon - span[(k,x,y)] # lower = activations[k][x][y] + span[(k,x,y)] - epsilon pstr = eval("variable[1,1,%s,%s,%s] < %s"%(k+1,x,y,upper)) pstr = And(eval("variable[1,1,%s,%s,%s] > %s"%(k+1,x,y,lower)), pstr) pstr = And(eval("variable[1,1,%s,%s,%s] != %s"%(k+1,x,y,activations[k][x][y])), pstr) s.add(pstr) c += 1 if activations[k][x][y] > 0 : maxterm = "- variable[1,1,%s,%s,%s]"%(k+1,x,y) else: maxterm = "variable[1,1,%s,%s,%s]"%(k+1,x,y) if maxterms == "": maxterms = "(%s)"%maxterm else: maxterms = " %s + (%s) "%(maxterms, maxterm) nprint("Number of variables: " + str(d)) nprint("Number of clauses: " + str(c)) p = multiprocessing.Process(target=s.check) p.start() # Wait for timeout seconds or until process finishes p.join(cfg.timeout) # If thread is still active if p.is_alive(): print "Solver running more than timeout seconds (default="+str(cfg.timeout)+"s)! Skip it" p.terminate() p.join() else: s_return = s.check() if 's_return' in locals(): if s_return == sat: inputVars = [ (l,x,y,eval("variable[1,0,"+ str(l+1) +"," + str(x) +"," + str(y)+ "]")) for (l,x,y) in toBeChanged ] cex = copy.deepcopy(images) for (l,x,y,v) in inputVars: #if cex[l][x][y] != v: print("different dimension spotted ... ") cex[l][x][y] = getDecimalValue(s.model()[v]) #print("%s %s"%(images[l][x][y],cex[l][x][y])) cex = np.squeeze(cex) #cex2 = copy.deepcopy(activations) #nextVars = [ (k,x,y,eval("variable[1,1,"+ str(k+1) +"," + str(x) +"," + str(y)+ "]")) for (k,x,y) in span.keys() ] #for (k,x,y,v) in nextVars: #if cex[l][x][y] != v: print("different dimension spotted ... ") # cex2[k][x][y] = getDecimalValue(s.model()[v]) # print("%s %s"%(activations[k][x][y],cex2[k][x][y])) nprint("satisfiable!") return (True, cex) else: nprint("unsatisfiable!") return (False, input) else: print "timeout! " return (False, input)