def main(): variable_names = sys.argv[1].split(',') constraint_strs = sys.argv[2].split(',') constraints = [] for var in variable_names: exec('{n} = z3.Int(\'{n}\')'.format(n=var)) for constraint in constraint_strs: constraints.append(eval(constraint)) z3.solve(*constraints)
def part2(inp): import z3 inps = [(i, x) for i, x in enumerate(inp) if x != "x"] ts = z3.Int("t") cs = [ts > 0] for a, n in inps: cs.append(((ts + a) % n) == 0) print(cs) z3.solve(*cs)
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!")
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]) simplify = Then( Tactic('simplify'), Tactic('propagate-values'), ParThen(Repeat(OrElse(Tactic('split-clause'), Tactic('skip'))), Tactic('propagate-ineqs'))) #print tactic(ForAll(x,Or(h2neg,h)))
def main(): """Lantern demo""" # Initialize a PyTorch network # Lantern currently supports: Linear, ReLU, Hardtanh, Dropout, Identity net = nn.Sequential(nn.Linear(2, 5), nn.ReLU(), nn.Linear(5, 1), nn.ReLU()) print("A PyTorch network:") print(net) print() # Normally, we would train this network to compute some function. However, # for this demo, we'll just use the initialized weights. print("Network parameters:") print(list(net.parameters())) print() # lantern.as_z3(model) returns a triple of z3 constraints, input variables, # and output variables that directly correspond to the behavior of the # given PyTorch network. By default, latnern assumes Real-sorted variables. constraints, in_vars, out_vars = lantern.as_z3(net) print("Z3 constraints, input variables, output variables (Real-sorted):") print(constraints) print(in_vars) print(out_vars) print() # The 'payoff' is that we can prove theorems about our network with z3. # Trivially, we can ask for a satisfying assignment of variables print("A satisfying assignment to the variables in this network:") z3.solve(constraints) print() # However, we can run the network "backwards"; e.g. what is an *input* that # causes the network to output the value 0 (if such an input exists)? constraints.append(out_vars[0] == 0) print("An assignment such that the output variable is 0:") z3.solve(constraints) print() # To more precisely represent the underlying computations, consider using # an appropriate floating-point sort; PyTorch defaults to single precision. # To speed up satisfiability computations, models can be 'rounded', which # truncates the mantissa of every PyTorch model parameter. Note that the # exponent part remains the same (11 bits) so that the result can be # returned as a Python float. Here, we truncate to 10 bits (half precision). rounded_net = lantern.round_model(net, 10) constraints, in_vars, out_vars = lantern.as_z3(rounded_net, sort=z3.FPSort(11, 10)) print("Z3 constraints, input, output (FPSort(11, 10)):") print(constraints) print(in_vars) print(out_vars) print() # We add the constraint that the output must be 0.0, and solve using a # solver for FloatingPoint theory. print("An assignment such that the output variable is 0.0:") constraints.append(out_vars[0] == 0.0) z3.solve_using(z3.SolverFor("QF_FP"), *constraints) print() # Note that the constraints, and variables are all 'ordinary' Z3Py objects. print("Happy hacking!")
print('rightUnique preds:', rUnique) print('-----') print('type(x) = {}, {}:\n'.format(type(x), x)) print('type(y) = {}, {}:\n'.format(type(y), y)) # print('type(xx) = {}, {}:\n'.format(type(xx), xx)) print('-----') # print('y\'s children:') # gg = y[1].children() # gh = z3.Solver() # gh.add(gg[-3] != gg[-2]) # print(gh.check().r == -1) # print('-----') z3.solve(x != y) s = z3.Solver() s.add(x != y) # s.add(z3.Or(z3.Not(y[1]), x[1]) != True) # s.check.r(): 1 (eq is true...PCs are inqeuiv) or -1 (eq is false...PCSs are equiv) print(s.check().r == -1) # If above prints False, the eqs are INEQ, else if it prints True, they're EQUIV # Uncomment the code below to run the implication checker on each PC: # If the two PCs are INEQUIV if s.check().r == 1: a_preamble, b_preamble, a_rem, b_rem = [], [], [], [] # Get preambles for both PCs for i in range(len(a_clean)):
def euler185(): import z3 x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16 = z3.Ints( "x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16") #x1,x2,x3,x4,x5 = z3.Ints("x1 x2 x3 x4 x5") variables = [ x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16 ] #variables = [x1,x2,x3,x4,x5] def none_correct(arr): return reduce(z3.And, [arr[i] != variables[i] for i in range(len(arr))]) def one_correct(arr): return reduce(z3.Or, [ reduce(z3.And, [ arr[j] != variables[j] if i != j else arr[j] == variables[j] for j in range(len(arr)) ]) for i in range(len(arr)) ]) def two_correct(arr): out = [] for i in range(len(arr)): for j in range(len(arr)): if i < j: out.append( reduce(z3.And, [ arr[k] == variables[k] if (k == i or k == j) else arr[k] != variables[k] for k in range(len(arr)) ])) return reduce(z3.Or, out) def three_correct(arr): out = [] for i in range(len(arr)): for j in range(len(arr)): for k in range(len(arr)): if i < j < k: out.append( reduce(z3.And, [ arr[l] == variables[l] if (l == i or l == j or l == k) else arr[l] != variables[l] for l in range(len(arr)) ])) return reduce(z3.Or, out) s = [] for i in variables: s.append(0 <= i) s.append(i <= 9) # s.append(z3.simplify(two_correct([int(i) for i in "90342"]))) # s.append(z3.simplify(none_correct([int(i) for i in "70794"]))) # s.append(z3.simplify(two_correct([int(i) for i in "39458"]))) # s.append(z3.simplify(one_correct([int(i) for i in "34109"]))) # s.append(z3.simplify(two_correct([int(i) for i in "51545"]))) # s.append(z3.simplify(one_correct([int(i) for i in "12531"]))) # print z3.solve(reduce(z3.And,s)) """ 5616185650518293 ;2 correct 3847439647293047 ;1 correct 5855462940810587 ;3 correct 9742855507068353 ;3 correct 4296849643607543 ;3 correct 3174248439465858 ;1 correct 4513559094146117 ;2 correct 7890971548908067 ;3 correct 8157356344118483 ;1 correct 2615250744386899 ;2 correct 8690095851526254 ;3 correct 6375711915077050 ;1 correct 6913859173121360 ;1 correct 6442889055042768 ;2 correct 2321386104303845 ;0 correct 2326509471271448 ;2 correct 5251583379644322 ;2 correct 1748270476758276 ;3 correct 4895722652190306 ;1 correct 3041631117224635 ;3 correct 1841236454324589 ;3 correct 2659862637316867 ;2 correct """ guesses = "5616185650518293 3847439647293047 5855462940810587 9742855507068353 4296849643607543 3174248439465858 4513559094146117 7890971548908067 8157356344118483 2615250744386899 8690095851526254 6375711915077050 6913859173121360 6442889055042768 2321386104303845 2326509471271448 5251583379644322 1748270476758276 4895722652190306 3041631117224635 1841236454324589 2659862637316867".split( " ") guesses = zip( guesses, [2, 1, 3, 3, 3, 1, 2, 3, 1, 2, 3, 1, 1, 2, 0, 2, 2, 3, 1, 3, 3, 2]) for (i, j) in guesses: print i if j == 0: s.append(z3.simplify(none_correct([int(k) for k in i]))) elif j == 1: s.append(z3.simplify(one_correct([int(k) for k in i]))) elif j == 2: s.append(z3.simplify(two_correct([int(k) for k in i]))) else: s.append(z3.simplify(three_correct([int(k) for k in i]))) return sorted(z3.solve(reduce(z3.And, s)))
import z3 feed = z3.Int("feed") clean = z3.Int("clean") play = z3.Int("play") solver = z3.Solver() z3.solve( (feed * 10) - (play * 2) == 72, (feed * 2) + (play * 4) - (clean * 1) == 30, (clean * 6) - (feed * 1) - (play * 1) == 0) # clean = 2, play = 4, feed = 8
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)
def simpl(f): l = Then(qe, simplify)(f)[0] if len(l) == 0: return True elif len(l) == 1: return l[0] else: return apply(And, l) middle3 = And(middle2, 0 <= y, y < n, n >= 2) middle4 = And(p >= -1, p < y, y < q, q <= n, n >= 2) middle5 = simpl(middle3) # middle3 <=> middle4 print solve(And(middle4, Not(middle3))) # no solution print solve(And(middle3, Not(middle4))) # no solution print "middle:", middle5 # middle3 <=> middle4 print solve(And(middle4, Not(middle5))) # no solution print solve(And(middle5, Not(middle4))) # no solution # simpl(middle3) # WOO HOO! # And(Or(p == -1, p >= 0), # -1*p + y >= 1,
import z3 def print_expression(exp): print("num args: ", exp.num_args()) print("children: ", exp.children()) print("1st child:", exp.arg(0)) print("2nd child:", exp.arg(1)) print("operator: ", exp.decl()) print("op name: ", exp.decl().name()) if __name__ == '__main__': ''' What to prove: x > 2, y < 10, x + 2*y == 7 ''' x = z3.Int('x') y = z3.Int('y') exps = [x > 2, y < 10, x + 2 * y == 7] for exp in exps: print_expression(exp) z3.solve(*exps)
from z3 import Int, solve from Z3 import * if __name__ == '__main__': x = Int('x') y = Int('y') s = solve(x > 2, y < 10, x + 2 * y == 7) print(s)
params, ret = get_annotations(if_triangle) params, ret SYM_VARS = { int: (z3.Int, z3.IntVal), float: (z3.Real, z3.RealVal), str: (z3.String, z3.StringVal) } def get_symbolicparams(fn): params, ret = get_annotations(fn) return [SYM_VARS[typ][0](name) for name, typ in params], SYM_VARS[ret][0]('__return__') (a, b, c), r = get_symbolicparams(if_triangle) a, b, c, r ################################################################ FINDING SOLUTIONS FOR THE PATH z3.solve(a > b, b > c, c > b) # no solution z3.solve(a < b, b < c, c > a) z3.solve(b > c, a > b, c < a) ################################################################################################ # Generate all possible paths from fnenter to all paths in the function. symfz_ct = SimpleSymbolicFuzzer(if_triangle) paths = symfz_ct.get_all_paths(symfz_ct.fnenter) print(len(paths)) for i in range(0, len(paths)): print(paths[i])
def check0(num): v1 = num + 35881 return v1 == (-144734034 ^ (4286 * (4294932349 + 1167))) def check1(a1): v1 = (4294960452 + a1) return v1 == (1182247522 ^ (52074 * (37454 + 4294907139))) def check2(a1): v1 = (4294927469 + 4294923120) return (7606 * (a1 + 46494)) == (-3648869 ^ v1) def check3(a1): v1 = (4294956380 + 59384) return (13921 * (34208 + a1)) == (-414417428 ^ v1) a = z3.BitVec("a", 32) b = z3.BitVec("b", 32) c = z3.BitVec("c", 32) d = z3.BitVec("d", 32) solve(check0(a), check1(-b), check2(-c), check3(-d)) key = list(map(hex, [52253, 48220, 46021, 63976])) print(*key) flag = b'cc1d-bc5c-b3c5-f9e8'
import z3 x = z3.Int('x') y = z3.Int('y') z3.solve(x > 2, y < 10, x + 2 * y == 7)
def triangle(x, y, z): return z3.And(x > 0, y > 0, z > 0, x + y + z == 180) def acute(x, y, z): return z3.And(x < 90, y < 90, z < 90) def abs(x): return z3.If(x > 0, x, -x) def almost_right(x, y, z): return z3.Or(abs(x - 90) <= 15, abs(y - 90) <= 15, abs(z - 90) <= 15) def almost_isosceles(x, y, z): return z3.Or(abs(x - y) <= 15, abs(x - z) <= 15, abs(y - z) <= 15) x = z3.Real("x") y = z3.Real("y") z = z3.Real("z") z3.solve( triangle(x, y, z), acute(x, y, z), z3.Not(almost_right(x, y, z)), z3.Not(almost_isosceles(x, y, z)), )
import z3 if __name__ == '__main__': ''' And, Or, Not, Implies, If, Bi-Implies: == 0: p -> q :=> ~p or q 1: r <-> ~q :=> (~r and ~q) and (q and r) 2: ~p or r ------------------------------------------- Theoretically, in 3-way logics, we got: 0: true; 1: false; 2: not-sure; For p -> q statements: if p is true |= q is deterministic. if p is false |= we have no idea about q. i.e., q is undeterministic. "undeterministic" is 1 in binary logic. ''' p, q, r = [z3.Bool(x) for x in 'pqr'] exps = [z3.Implies(p, q), r == z3.Not(q), z3.Or(z3.Not(p), r)] z3.solve(*exps) # unsat!
def dec(dic): out = '' for i in dic: m = i x = z3.Int("x") z3.solve(x>0, m == 5 * x**2 + 6 * x - 8)
str: (z3.String, z3.StringVal) } def get_symbolicparams(fn): params, ret = get_annotations(fn) return [SYM_VARS[typ][0](name) for name, typ in params], SYM_VARS[ret][0]('__return__') if __name__ == '__main__': (a, b, c), r = get_symbolicparams(check_triangle) a, b, c, r if __name__ == '__main__': z3.solve(a == b, a == c, b == c) from .ConcolicFuzzer import ArcCoverage # minor dependency if __name__ == '__main__': with ArcCoverage() as cov: assert check_triangle(0, 0, 0) == 'Equilateral' cov._trace, cov.arcs() ### The CFG with Path Taken if __name__ == '__main__': print('\n### The CFG with Path Taken') if __name__ == '__main__': show_cfg(check_triangle, arcs=cov.arcs())
left = self.value right = other.value expr = left == right return klara.inference.InferenceResult.load_result(Z3Proxy(expr)) def __k_bool__(self): yield klara.inference.InferenceResult(self, status=True) AST2Z3TYPE_MAP = {"int": z3.Int, "float": z3.Real, "bool": z3.Bool, "str": z3.String} @klara.inference.inference_transform_wrapper def _infer_arg(node: klara.Arg, context): name = node.arg z3_var_type = AST2Z3TYPE_MAP[str(node.annotation)] z3_var = z3_var_type(name) proxy = Z3Proxy(z3_var) yield klara.inference.InferenceResult.load_result(proxy) klara.MANAGER.register_transform(klara.Arg, _infer_arg) source = """ def foo(a: int): return a + 2 == 12 """ tree = klara.parse(source) for res in tree.body[0].infer_return_value(): z3.solve(res.result.value)