def __init__( # pylint: disable=R0913 self, lattice: Lattice, shapes: List[List[Vector]], solver: Optional[Solver] = None, complete: bool = False, allow_rotations: bool = False, allow_reflections: bool = False, allow_copies: bool = False ): ShapeConstrainer._instance_index += 1 if solver: self.__solver = solver else: self.__solver = Solver() self.__lattice = lattice self.__complete = complete self.__allow_copies = allow_copies self.__shapes = shapes self.__make_variants(allow_rotations, allow_reflections) self.__create_grids() self.__add_constraints()
class SudokuSolver: def __init__(self): self.rows, self.cols = '012345678', '012345678' self.positions = list( map(lambda a: a[0] + a[1], product(self.rows, self.cols))) self.symbols = {pos: Int(pos) for pos in self.positions} self.solver = None def solve(self, problem): self.set_conditions(problem) if self.solver.check() != sat: raise Exception("No solution.") model = self.solver.model() solution = { pos: int(model.evaluate(s).as_string()) for pos, s in self.symbols.items() } return np.array(list(solution.values())).reshape(9, 9) def set_conditions(self, problem): self._initialize_solver() self._add_value_conditions() self._add_row_conditions() self._add_col_conditions() self._add_block_conditions() self._import_problem(problem) def _initialize_solver(self): self.solver = Solver() def _add_value_conditions(self): for symbol in self.symbols.values(): self.solver.add(Or([symbol == i for i in range(1, 10)])) def _add_row_conditions(self): for row in self.rows: self.solver.add( Distinct([self.symbols[row + col] for col in self.cols])) def _add_col_conditions(self): for col in self.cols: self.solver.add( Distinct([self.symbols[row + col] for row in self.rows])) def _add_block_conditions(self): for i, j in product(range(3), repeat=2): blocks = [ self.symbols[self.rows[m + 3 * i] + self.cols[n + 3 * j]] for m, n in product(range(3), repeat=2) ] self.solver.add(Distinct(blocks)) def _import_problem(self, problem): for row, col, value in zip(*np.nonzero(problem) + (problem[np.nonzero(problem)], )): pos = str(row) + str(col) self.solver.add(self.symbols[pos] == str(value))
def xform_correct(x, typing): # type: (XForm, VarTyping) -> bool """ Given an XForm x and a concrete variable typing for x check whether x is semantically preserving for the concrete typing. """ assert x.ti.permits(typing) # Create copies of the x.src and x.dst with their concrete types src_m = {v: Var(v.name, typing[v]) for v in x.src.vars()} # type: VarAtomMap # noqa src = x.src.copy(src_m) dst = x.apply(src) dst_m = x.dst.substitution(dst, {}) # Build maps for the inputs/outputs for src->dst inp_m = {} # type: VarAtomMap out_m = {} # type: VarAtomMap for v in x.src.vars(): src_v = src_m[v] assert isinstance(src_v, Var) if v.is_input(): inp_m[src_v] = dst_m[v] elif v.is_output(): out_m[src_v] = dst_m[v] # Get the primitive semantic Rtls for src and dst prim_src = elaborate(src) prim_dst = elaborate(dst) asserts = equivalent(prim_src, prim_dst, inp_m, out_m) s = Solver() s.add(*asserts) return s.check() == unsat
def __init__(self, rand: random.Random, expr: z3.ExprRef, solver: z3.Solver): if self.condition_value is None: if not solver_is_sat(solver): debug('bad solver', solver.sexpr()) raise CrosshairInternal('unexpected un sat') self.condition_value = solver.model().evaluate(expr, model_completion=True) WorstResultNode.__init__(self, rand, expr == self.condition_value, solver)
def collide(target_str, base_str, count=10, size_suffix=6, prefix=False): '''Generates a string with the following properties: * strcmp(res, base_str) = 0 * H(res) == H(target_str)''' solver = Solver() if prefix: res = generate_ascii_printable_string( 'res', size_suffix, solver) + str_to_BitVecVals8(base_str) else: res = str_to_BitVecVals8(base_str) + generate_ascii_printable_string( 'res', size_suffix, solver) target_checksum = H(str_to_BitVecVals8(target_str)) res_checksum = H(res) solver.add(res_checksum == target_checksum) for i in range(count): if solver.check() == sat: model = solver.model() if prefix: solution = "".join( chr(model[x].as_long()) for x in res[:size_suffix]) + base_str solver.add( [x != model[x].as_long() for x in res[:size_suffix]]) else: solution = base_str + "".join( chr(model[x].as_long()) for x in res[-size_suffix:]) solver.add( [x != model[x].as_long() for x in res[-size_suffix:]]) yield solution
def __init__(self, state_graph: StateGraph, default_value: Fraction, statistics: Statistics, settings: Settings, model_type: PrismModelType): self.state_graph = state_graph self.statistics = statistics self.settings = settings self.model_type = model_type if default_value < 0: raise ValueError("Oracle values must be greater or equal to 0") self.default_value = RealVal(default_value) self.solver = Solver() self.solver_mdp = Optimize() # The way we refine the Oracle depends on the model type if model_type == PrismModelType.DTMC: self.refine_oracle = self.refine_oracle_mc elif model_type == PrismModelType.MDP: self.refine_oracle = self.refine_oracle_mdp else: raise Exception("Oracle: Unsupported model type") self.oracle_states: Set[StateId] = set() self.oracle: Dict[StateId, z3.ExprRef] = dict()
def __init__( # pylint: disable=R0913 self, lattice: Lattice, solver: Solver = None, complete: bool = True, rectangular: bool = False, min_region_size: Optional[int] = None, max_region_size: Optional[int] = None ): RegionConstrainer._instance_index += 1 self.__lattice = lattice if solver: self.__solver = solver else: self.__solver = Solver() self.__complete = complete if min_region_size is not None: self.__min_region_size = min_region_size else: self.__min_region_size = 1 if max_region_size is not None: self.__max_region_size = max_region_size else: self.__max_region_size = len(self.__lattice.points) self.__manage_edge_sharing_directions() self.__create_grids() self.__add_constraints() if rectangular: self.__add_rectangular_constraints()
def check_adversarial_robustness_z3(): from z3 import Reals, Int, Solver, If, And sk, sk_1, zk, zk_1 = Reals('sk sk_1 zk zk_1') i = Int('i') s = Solver() s.add(And(i >= 0, i <= 20, sk_1 >= 0, sk >= 0, zk >= 0, zk_1 >= 0)) A = If(sk * 1 >= 0, sk * 1, 0) B = If(zk * 1 >= 0, zk * 1, 0) s.add(If(i == 0, And(sk >= 0, sk <= 3, zk >= 10, zk <= 21, sk_1 == 0, zk_1 == 0), sk - zk >= sk_1 - zk_1 + 21 / i)) s.add(And(A < B, i == 20)) # # we negate the condition, instead if for all sk condition we check if there exists sk not condition # s.add(sk_ReLU * w > ylim) t = s.check() if t == sat: print("z3 result:", s.model()) return False else: # print("z3 result:", t) return True
def get_mus(constraints): ''' Returns a single MUS ''' seed = set(range(len(constraints))) idx2indicator = {i:Bool(str(i)) for i in seed} indicator2idx = {b.get_id():i for (i,b) in idx2indicator.items()} s = Solver() for i, b in idx2indicator.items(): s.add(Implies(b, constraints[i])) def check_subset(current_seed): assumptions = [idx2indicator[i] for i in current_seed] return (s.check(assumptions) == sat) current = set(seed) for i in seed: if i not in current: continue current.remove(i) if not check_subset(current): core = s.unsat_core() # FIXME: do constraints never show up in the core? Seems like we could get a key error current = set(indicator2idx[ind.get_id()] for ind in core) else: current.add(i) assert not check_subset(current), "Expecting unsat at end of get_mus" return [constraints[i] for i in current]
def getInitSolver(var): s = Solver() if (var.min_max is not None): print "adding min_max for ", var min_value, max_value = var.min_max z3var = Z3VarTable.get(var) s.add(min_value <= z3var) s.add(z3var <= max_value) return s
def __init__(self, flatline=None, sudoku=None): super().__init__(flatline, sudoku) self.symbols = {pos: Int(pos) for pos in self.sudoku.positions } # Convert pos to SAT solver value. self.solver = Solver() self.solved = None # Final solved state of the sudoku if possible. self.add_default_constraints()
def __init__(self, rand: random.Random, expr: z3.ExprRef, solver: z3.Solver): if not solver_is_sat(solver): debug("Solver unexpectedly unsat; solver state:", solver.sexpr()) raise CrosshairInternal("Unexpected unsat from solver") self.condition_value = solver.model().evaluate(expr, model_completion=True) self._stats_key = f"realize_{expr}" if z3.is_const(expr) else None WorstResultNode.__init__(self, rand, expr == self.condition_value, solver)
def check_sat(solver: z3.Solver, pop_if_exception: bool = True) -> z3.CheckSatResult: try: ret = solver.check() if ret == z3.unknown: raise z3.Z3Exception(solver.reason_unknown()) except Exception as e: if pop_if_exception: solver.pop() raise e return ret
def are_z3_satisfiable(z3_constraints): """ Checks the satisfiability of Z3 constraints. :param z3_constraints: to be checked :return: if satisfiable """ s = Solver() for c in z3_constraints: s.add(c) return s.check() == sat
def trim_unrechable_states(self): # (parent, trace, child) tuples pending_parent_trace_child_tuples = [(None, None, self.root_wstate)] deleted_counter = 0 s = Solver() while(len(pending_parent_trace_child_tuples)): s.push() parent_wstate, trace, curr_wstate = pending_parent_trace_child_tuples.pop() if curr_wstate.status != WorldStateStatus.REACHABLE: s.add(curr_wstate.constraints) res = s.check() if res == sat: curr_wstate.status = WorldStateStatus.REACHABLE elif res == unsat: curr_wstate.status = WorldStateStatus.UNREACHABLE elif res == z3.unknown: print(curr_wstate.get_full_trace()) raise Exception("pdb") if curr_wstate.status == WorldStateStatus.REACHABLE: if curr_wstate != self.root_wstate: parent_wstate.trace_to_children[trace].append(curr_wstate) for child_trace, children in curr_wstate.trace_to_children.items(): for child_wstate in children: pending_parent_trace_child_tuples.append((curr_wstate, child_trace, child_wstate)) curr_wstate.trace_to_children.clear() else: curr_wstate.status = WorldStateStatus.DELETED self.gen_to_wstates[curr_wstate.gen].remove(curr_wstate) deleted_counter += 1 s.pop() logging.info('%d WorldStates are deleted', deleted_counter) logging.info('SVM initialized')
def collide(target_str, base_str, count = 10, size_suffix = 6, prefix = False): '''Generates a string with the following properties: * strcmp(res, base_str) = 0 * H(res) == H(target_str)''' solver = Solver() if prefix: res = generate_ascii_printable_string('res', size_suffix, solver) + str_to_BitVecVals8(base_str) else: res = str_to_BitVecVals8(base_str) + generate_ascii_printable_string('res', size_suffix, solver) target_checksum = H(str_to_BitVecVals8(target_str)) res_checksum = H(res) solver.add(res_checksum == target_checksum) for i in range(count): if solver.check() == sat: model = solver.model() if prefix: solution = "".join(chr(model[x].as_long()) for x in res[:size_suffix]) + base_str solver.add([x != model[x].as_long() for x in res[:size_suffix]]) else: solution = base_str + "".join(chr(model[x].as_long()) for x in res[-size_suffix:]) solver.add([x != model[x].as_long() for x in res[-size_suffix:]]) yield solution
class Model(type): """ Meta class which allows to agregate the solvers of parent class """ def __new__(cls, name, bases, dct): def _agregateSolver(self): self.s = Solver() for base in bases: s1 = base.resetSolver(self) self.s.add(s1.assertions()) dct["reset"] = _agregateSolver return type.__new__(cls, name, bases, dct)
def z3_problem(constraints, solver: z3.Solver): for con in constraints: break n = con.n x = np.array([z3.Real('x_%s' % (i + 1)) for i in range(n)]) x = sympy.Matrix([z3.Real('x_%s' % (i + 1)) for i in range(n)]) for con in constraints: solver.add(con.z3_expression(x)) return x, solver
def all_solutions_point2(solver: z3.Solver, fillet_center) -> typing.List[Point2]: solutions = [] x, y = fillet_center while solver.check() == z3.sat: m = solver.model() solution = Point2(solution_as_float(m[x]), solution_as_float(m[y])) solutions.append(solution) solver.add((x - solution.x)**2 + (y - solution.y)**2 > 10**(-PRECISION) * 100) return solutions
def bound_sort_counts(solver: z3.Solver, bounds: Dict[str, int]) -> None: for sort, K in bounds.items(): S = sorts_to_z3[sort] bv = z3.Const("elem_{}".format(sort), S) solver.add( z3.ForAll( bv, z3.Or(*[ z3.Const("elem_{}_{}".format(sort, i), S) == bv for i in range(K) ])))
def main(): target_bin = sys.argv[1] target_bin_name = os.path.basename(target_bin) if (len(sys.argv) > 2): output_dir = sys.argv[2] else: output_dir = None print output_dir # args = claripy.BVS('args', 8 * 16) arg1 = claripy.BVS('args', 8 * 100) arg2 = claripy.BVS('args', 8 * 100) arg3 = claripy.BVS('args', 8 * 100) arg4 = claripy.BVS('args', 8 * 300) proj = angr.Project(target_bin) state = proj.factory.entry_state(args=[arg1, arg2, arg3, arg4]) simgr = proj.factory.simgr(state) level = 0 while simgr.active: print 'level:', level level += 1 print 'state_num:', len(simgr.active) print simgr.active print '' count = 0 for s in simgr.active: solver = Solver() bsolver = BackendZ3() constr = s.solver.constraints print constr if constr: z3_constr = bsolver.convert_list(constr) solver.add(z3_constr) if (output_dir): filename = "{}-{}-{}".format(target_bin_name, level, count) output_path = os.path.join(output_dir, filename) with open(output_path, "w") as f: f.write(solver.to_smt2()) # logging.info("Output constraint to: " + output_path + "\n") print "Output constraint to: " + output_path + "\n" else: print sovler.to_smt2() count += 1 simgr.step()
def test_concrete_calldata_calldatasize(): # Arrange calldata = ConcreteCalldata(0, [1, 4, 7, 3, 7, 2, 9]) solver = Solver() # Act solver.check() model = solver.model() result = model.eval(calldata.calldatasize) # Assert assert result == 7
def fm(a: Formula, b: Formula, env: Environment, solver: z3.Solver, timer: Timer) -> Tuple[z3.CheckSatResult, Optional[z3.ModelRef]]: solver.push() solver.add(toZ3(a, env)) solver.add(z3.Not(toZ3(b, env))) r = timer.solver_check(solver) m = solver.model() if r == z3.sat else None solver.pop() return (r, m)
def __init__(self, filename): # Grid size self.n = 9 self.s = 3 # Grid initialization self.grid = [[0 for j in range(self.n)] for i in range(self.n)] # Z3 solver instanciation self.solver = Solver() # Parse input file self.parseFile(filename)
def test_puzzle_task_2(self): """ The puzzle should be solvable. """ claims = puzzle_task() stmts = encode_statements(claims) s = Solver() d1 = abc_different() d2 = knights_tell_truths() d3 = knaves_tell_lies() s.add(d1,d2,d3,stmts) # This should be satisifable self.assertEqual(sat, s.check(), "Puzzle is not solvable.")
def test_concrete_calldata_constrain_index(): # Arrange calldata = Calldata(0, [1, 4, 7, 3, 7, 2, 9]) solver = Solver() # Act constraint = calldata[2] == 3 solver.add(calldata.constraints + [constraint]) result = solver.check() # Assert assert str(result) == "unsat"
def test_concrete_calldata_constrain_index(): # Arrange calldata = Calldata(0, [1, 4, 7, 3, 7, 2, 9]) solver = Solver() # Act value, calldata_constraints = calldata[2] constraint = value == 3 solver.add([constraint] + calldata_constraints) result = solver.check() # Assert assert str(result) == "unsat"
def solve(): start = time.time() s = Solver() s.reset() for req in conf.reqs: target = req[0] accessConstraint = req[1] requirementEncoding = encodeRequirement(target, accessConstraint) s.add(ForAll(template.getAttributeVars(), requirementEncoding)) timeToTranslate = time.time() - start measurements.addToTranslationTime(timeToTranslate) start = time.time() solution = None if s.check() == sat: solution = {} model = s.model() for PEP in conf.PEPS: solution[PEP] = template.PEPPolicy(PEP, model) else: solution = unsat timeToSolve = time.time() - start measurements.addToSMTTime(timeToSolve) return solution
def z3_solve(self, n, timeout_amount): """ Integer factorization using z3 theorem prover implementation: We can factor composite integers by SAT solving the model N=PQ directly using the clasuse (n==p*q), wich gives a lot of degree of freedom to z3, so we want to contraint the search space. Since every composite number n=pq, there always exists some p>sqrt(n) and q<sqrt(n). We can safely asume the divisor p is in the range n > p >= next_prime(sqrt(n)) if this later clause doesn't hold and sqrt(p) is prime the number is a perfect square. We can also asume that p and q are alyaws odd otherwise our whole composite is even. Not all composite numbers generate a valid model that z3 can SAT. SAT solving is efficient with low bit count set in the factors, the complexity of the algorithm grows exponential with every bit set. The problem of SAT solving integer factorization still is NP complete, making this just a showcase. Don't expect big gains. """ s = Solver() s.set("timeout", timeout_amount * 1000) p = Int("p") q = Int("q") i = int(isqrt(n)) np = int(next_prime(i)) s.add(p * q == n, n > p, n > q, p >= np, q < i, q > 1, p > 1, q % 2 != 0, p % 2 != 0) try: s_check_output = s.check() if s_check_output == sat: res = s.model() P, Q = res[p].as_long(), res[q].as_long() assert P * Q == n return P, Q else: return None, None except: return None, None
def find_model_or_equivalence(current: Formula, formula: Formula, env: Environment, s: z3.Solver, t: Timer) -> Optional[Model]: (r1, m) = fm(current, formula, env, s, t) if m is not None: for k in range(1, 100000): s.push() bound_sort_counts(s, dict((s, k) for s in env.sig.sorts)) (_, m) = fm(current, formula, env, s, t) s.pop() if m is not None: return extract_model(m, env.sig, "-") assert False (r2, m) = fm(formula, current, env, s, t) if m is not None: for k in range(1, 100000): s.push() bound_sort_counts(s, dict((s, k) for s in env.sig.sorts)) (_, m) = fm(formula, current, env, s, t) s.pop() if m is not None: return extract_model(m, env.sig, "+") assert False if r1 == z3.unsat and r2 == z3.unsat: return None # TODO: try bounded model checking up to some limit # test = Timer(1000000) # with test: # r = fm(current, formula, env, s, test) # if repr(r) != "unknown": # print("Inconsistency in timeouts") raise RuntimeError("Z3 did not produce equivalence or model")
def test_concrete_calldata_constrain_index(): # Arrange calldata = Calldata(0) solver = Solver() # Act constraints = [] constraints.append(calldata[51] == 1) constraints.append(calldata.calldatasize == 50) solver.add(calldata.constraints + constraints) result = solver.check() # Assert assert str(result) == "unsat"
def PEPPolicy(PEP, model): disjunctions = [] for or_id in range(NUM_ORS): conjunctions = [] for enum_id in range(NUM_ENUMS): enumVar = TEMPLATE_ENUM_VARS[PEP][or_id][enum_id] if model[enumVar] is not None: synthVal = model[enumVar].as_long() else: synthVal = -1 if synthVal >= 0 and synthVal < len(ENUM_INDEX.keys()): if not isinstance(ENUM_INDEX[synthVal], list): boolVar = ENUM_INDEX[synthVal] conjunctions.append(boolVar) else: [enumVar, val] = ENUM_INDEX[synthVal] conjunctions.append(enumVar == val) elif synthVal >= len(ENUM_INDEX.keys()) and synthVal < 2 * len(ENUM_INDEX.keys()): if not isinstance(ENUM_INDEX[synthVal - len(ENUM_INDEX.keys())], list): boolVar = ENUM_INDEX[synthVal - len(ENUM_INDEX.keys())] conjunctions.append(Not(boolVar)) else: [enumVar, val] = ENUM_INDEX[synthVal - len(ENUM_INDEX.keys())] conjunctions.append(enumVar != val) elif synthVal == 2 * len(ENUM_INDEX.keys()): conjunctions.append(True) else: conjunctions.append(False) for num_id in range(NUM_NUMERIC): minVar = TEMPLATE_NUMERIC_VARS[PEP][or_id][num_id]['min'] maxVar = TEMPLATE_NUMERIC_VARS[PEP][or_id][num_id]['max'] if model[minVar] is not None and model[maxVar] is not None: crosscheck = Solver() crosscheck.add(model[minVar] <= model[maxVar]) if crosscheck.check() == sat: conjunctions.append(NUM_VAR >= model[minVar].as_long()) conjunctions.append(NUM_VAR <= model[maxVar].as_long()) elif model[minVar] is not None: conjunctions.append(NUM_VAR >= model[minVar].as_long()) elif model[maxVar] is not None: conjunctions.append(NUM_VAR <= model[maxVar].as_long()) disjunctions.append(simplify(And(conjunctions))) return simplify(Or(disjunctions))
def is_tautology(formula) : """Check whether the formula is a tautology, and give a counterexample if it is not. Parameters ---------- formula@Formula - The formula to be tested. Returns ---------- check_res@bool - Whether the formula is a tautology. counterexample@Model - None if the formula is a tautology, otherwise a counterexample. """ s = Solver() s.add(Not(formula)) if s.check() == unsat : return True, None return False, s.model()
class MySolver(object): def __init__(self): self._solver = Solver() # TODO: Initialize datatypes here # TODO: Port the below functions to here as methods def push(self): """Push solver state.""" self._solver.push() def pop(self): """Pop solver state.""" self._solver.pop() def add(self, assertion): """Add an assertion to the solver state. Arguments: assertion : Z3-friendly predicate or boolean """ return self._solver.add(assertion) def model(self): """Return a model for the current solver state. Returns: : Z3 model. TODO: Modify this all so that it returns sets, etc. """ return self._solver.model() def check(self): """Check satisfiability of current satisfiability state. Returns: : boolean -- True if sat, False if unsat """ # check() returns either unsat or sat # sat.r is 1, unsat.r is -1 return self._solver.check().r > 0 @contextmanager def context(self): """To do something in between a push and a pop, use a `with context()`.""" self.push() yield self.pop() def quick_check(self, assertion): """Add an assertion only temporarily, and check sat.""" with self.context(): self.add(assertion) return self.check()
def is_equivalent(self, state): solver = Solver() b1, b2 = FreshBool(), FreshBool() solver.add(b1 == self.z3_expr) solver.add(b2 == state.z3_expr) solver.add(Not(And(Implies(b1, b2), Implies(b2, b1)))) # print "comparing" # print self # print "-------" # print state # if solver.check() != unsat: # m = solver.model() # print m # raw_input("press any key to continue") # return False # return True return solver.check() == unsat
def testZ3Distinctness(): ''' This test is simply a playground to explore how z3 handles distinctness and equality checking. ''' s = Solver() x, y = Consts('x y', language.PointSort) s.add(Distinct(x)) s.add(Distinct(y)) print s # print s.add(Not(eq(x,y))) # print eq(simplify(x),simplify(y)) # s.add(eq(x,y)) s.add(Not(eq(x,y))) print s.check() print s
def get_models(F): result = [] s = Solver() s.add(F) while True: if s.check() == sat: m = s.model() result.append(m) # Create a new constraint the blocks the current model block = [] for d in m: # d is a declaration if d.arity() > 0: raise Z3Exception( "uninterpreted functions are not suppported") # create a constant from declaration c = d() if is_array(c) or c.sort().kind() == Z3_UNINTERPRETED_SORT: raise Z3Exception( "arrays and uninterpreted sorts are not supported") block.append(c != m[d]) s.add(Or(block)) else: return result
def __call__(self, project, test, dump): logger.info('inferring specification for test \'{}\''.format(test)) environment = dict(os.environ) if self.config['klee_max_forks'] is not None: environment['ANGELIX_KLEE_MAX_FORKS'] = str(self.config['klee_max_forks']) if self.config['klee_max_depth'] is not None: environment['ANGELIX_KLEE_MAX_DEPTH'] = str(self.config['klee_max_depth']) if self.config['klee_search'] is not None: environment['ANGELIX_KLEE_SEARCH'] = self.config['klee_search'] if self.config['klee_timeout'] is not None: environment['ANGELIX_KLEE_MAX_TIME'] = str(self.config['klee_timeout']) if self.config['klee_solver_timeout'] is not None: environment['ANGELIX_KLEE_MAX_SOLVER_TIME'] = str(self.config['klee_solver_timeout']) if self.config['klee_debug']: environment['ANGELIX_KLEE_DEBUG'] = 'YES' if self.config['klee_ignore_errors']: environment['KLEE_DISABLE_MEMORY_ERROR'] = 'YES' if self.config['use_semfix_syn']: environment['ANGELIX_USE_SEMFIX_SYN'] = 'YES' environment['ANGELIX_KLEE_WORKDIR'] = project.dir test_dir = self.get_test_dir(test) shutil.rmtree(test_dir, ignore_errors='true') klee_dir = join(test_dir, 'klee') os.makedirs(klee_dir) self.run_test(project, test, klee=True, env=environment) # loading dump # name -> value list oracle = dict() vars = os.listdir(dump) for var in vars: instances = os.listdir(join(dump, var)) for i in range(0, len(instances)): if str(i) not in instances: logger.error('corrupted dump for test \'{}\''.format(test)) raise InferenceError() oracle[var] = [] for i in range(0, len(instances)): file = join(dump, var, str(i)) with open(file) as f: content = f.read() oracle[var].append(content) # solving path constraints angelic_paths = [] solver = Solver() smt_glob = join(project.dir, 'klee-out-0', '*.smt2') smt_files = glob(smt_glob) for smt in smt_files: logger.info('solving path {}'.format(relpath(smt))) try: path = z3.parse_smt2_file(smt) except: logger.warning('failed to parse {}'.format(smt)) continue variables = [str(var) for var in get_vars(path) if str(var).startswith('int!') or str(var).startswith('bool!') or str(var).startswith('char!') or str(var).startswith('reachable!')] outputs, choices, constants, reachable, original_available = parse_variables(variables) # name -> value list (parsed) oracle_constraints = dict() def str_to_int(s): return int(s) def str_to_bool(s): if s == 'false': return False if s == 'true': return True raise InferenceError() def str_to_char(s): if len(s) != 1: raise InferenceError() return s[0] dump_parser_by_type = dict() dump_parser_by_type['int'] = str_to_int dump_parser_by_type['bool'] = str_to_bool dump_parser_by_type['char'] = str_to_char def bool_to_bv32(b): if b: return BitVecVal(1, 32) else: return BitVecVal(0, 32) def int_to_bv32(i): return BitVecVal(i, 32) to_bv32_converter_by_type = dict() to_bv32_converter_by_type['bool'] = bool_to_bv32 to_bv32_converter_by_type['int'] = int_to_bv32 def bv32_to_bool(bv): return bv.as_long() != 0 def bv32_to_int(bv): l = bv.as_long() if l >> 31 == 1: # negative l -= 4294967296 return l from_bv32_converter_by_type = dict() from_bv32_converter_by_type['bool'] = bv32_to_bool from_bv32_converter_by_type['int'] = bv32_to_int matching_path = True for expected_variable, expected_values in oracle.items(): if expected_variable == 'reachable': expected_reachable = set(expected_values) if not (expected_reachable == reachable): logger.info('labels \'{}\' executed while {} required'.format( list(reachable), list(expected_reachable))) matching_path = False break continue if expected_variable not in outputs.keys(): outputs[expected_variable] = (None, 0) # unconstraint does not mean wrong required_executions = len(expected_values) actual_executions = outputs[expected_variable][1] if required_executions != actual_executions: logger.info('value \'{}\' executed {} times while {} required'.format( expected_variable, actual_executions, required_executions)) matching_path = False break oracle_constraints[expected_variable] = [] for i in range(0, required_executions): type = outputs[expected_variable][0] try: value = dump_parser_by_type[type](expected_values[i]) except: logger.error('variable \'{}\' has incompatible type {}'.format(expected_variable, type)) raise InferenceError() oracle_constraints[expected_variable].append(value) if not matching_path: continue solver.reset() solver.add(path) def array_to_bv32(array): return Concat(Select(array, BitVecVal(3, 32)), Select(array, BitVecVal(2, 32)), Select(array, BitVecVal(1, 32)), Select(array, BitVecVal(0, 32))) def angelic_selector(expr, instance): s = 'angelic!{}!{}!{}!{}!{}'.format(expr[0], expr[1], expr[2], expr[3], instance) return BitVec(s, 32) def original_selector(expr, instance): s = 'original!{}!{}!{}!{}!{}'.format(expr[0], expr[1], expr[2], expr[3], instance) return BitVec(s, 32) def env_selector(expr, instance, name): s = 'env!{}!{}!{}!{}!{}!{}'.format(name, expr[0], expr[1], expr[2], expr[3], instance) return BitVec(s, 32) for name, values in oracle_constraints.items(): type, _ = outputs[name] for i, value in enumerate(values): array = self.output_variable(type, name, i) bv_value = to_bv32_converter_by_type[type](value) solver.add(bv_value == array_to_bv32(array)) for (expr, item) in choices.items(): type, instances, env = item for instance in range(0, instances): selector = angelic_selector(expr, instance) array = self.angelic_variable(type, expr, instance) solver.add(selector == array_to_bv32(array)) selector = original_selector(expr, instance) array = self.original_variable(type, expr, instance) solver.add(selector == array_to_bv32(array)) for name in env: selector = env_selector(expr, instance, name) env_type = 'int' #FIXME array = self.env_variable(env_type, expr, instance, name) solver.add(selector == array_to_bv32(array)) result = solver.check() if result != z3.sat: logger.info('UNSAT') continue model = solver.model() # store smt2 files shutil.copy(smt, klee_dir) # generate IO file self.generate_IO_file(test, choices, oracle_constraints, outputs) # expr -> (angelic * original * env) list angelic_path = dict() for (expr, item) in choices.items(): angelic_path[expr] = [] type, instances, env = item for instance in range(0, instances): bv_angelic = model[angelic_selector(expr, instance)] angelic = from_bv32_converter_by_type[type](bv_angelic) bv_original = model[original_selector(expr, instance)] original = from_bv32_converter_by_type[type](bv_original) if original_available: logger.info('expression {}[{}]: angelic = {}, original = {}'.format(expr, instance, angelic, original)) else: logger.info('expression {}[{}]: angelic = {}'.format(expr, instance, angelic)) env_values = dict() for name in env: bv_env = model[env_selector(expr, instance, name)] value = from_bv32_converter_by_type['int'](bv_env) env_values[name] = value if original_available: angelic_path[expr].append((angelic, original, env_values)) else: angelic_path[expr].append((angelic, None, env_values)) # TODO: add constants to angelic path angelic_paths.append(angelic_path) # update IO files for smt in glob(join(klee_dir, '*.smt2')): with open(smt) as f_smt: for line in f_smt.readlines(): if re.search("declare-fun [a-z]+!output!", line): output_var = line.split(' ')[1] output_var_type = output_var.split('!')[0] for io_file in glob(join(test_dir, '*.IO')): if not output_var in open(io_file).read(): with open(io_file, "a") as f_io: f_io.write("\n") f_io.write("@output\n") f_io.write('name {}\n'.format(output_var)) f_io.write('type {}\n'.format(output_var_type)) if self.config['max_angelic_paths'] is not None and \ len(angelic_paths) > self.config['max_angelic_paths']: angelic_paths = self._reduce_angelic_forest(angelic_paths) else: logger.info('found {} angelic paths for test \'{}\''.format(len(angelic_paths), test)) return angelic_paths
def remove_derived_clauses(self): clauses = sorted(self, key=lambda x: (len(x), x.rank, id(x))) solver = Solver() for c in clauses: if c.must_keep: solver.add(c.z3_expr) continue solver.push() solver.add(*[(~l).z3_expr for l in c]) if solver.check() != unsat: solver.pop() solver.add(c.z3_expr) else: solver.pop() self.clauses.remove(c)
from z3 import Solver, BitVec s = Solver() x = BitVec('x', 32) s.add(x > 1337) s.add(x*7 + 4 == 1337) s.check() print s.model()
t3 = Real('t3') t4 = Real('t4') q1x = p0[0]+t1*(p1[0]-p0[0]) q1y = p0[1]+t1*(p1[1]-p0[1]) q2x = p1[0]+t2*(p2[0]-p1[0]) q2y = p1[1]+t2*(p2[1]-p1[1]) q3x = p2[0]+t3*(p3[0]-p2[0]) q3y = p2[1]+t3*(p3[1]-p2[1]) q4x = p3[0]+t4*(p4[0]-p3[0]) q4y = p3[1]+t4*(p4[1]-p3[1]) solver = Solver() solver.add(t1 >= 0, t2 >= 0, t3 >= 0, t4 >= 0) solver.add(t1 <= 1, t2 <= 1, t3 <= 1, t4 <= 1) def orthogonal(px, py, qx, qy, rx, ry): return (px-qx)*(rx-qx)+(py-qy)*(ry-qy) == 0 solver.add(orthogonal(q1x, q1y, q2x, q2y, q3x, q3y)) solver.add(orthogonal(q2x, q2y, q3x, q4y, q4x, q4y)) solver.add(orthogonal(q3x, q3y, q4x, q4y, q1x, q1y)) solver.add(orthogonal(q4x, q4y, q1x, q1y, q2x, q2y)) solver.add((q2x-q1x)**2+(q2y-q1y)**2 == (q4x-q3x)**2+(q4y-q3y)**2) solver.add((q3x-q2x)**2+(q3y-q2y)**2 == (q4x-q1x)**2+(q4y-q1y)**2) solver.add()
def get_solver(self): solver = Solver() for c in self: solver.add(c.z3_expr) return solver
def exploit(t): target = lambda: remote(t['hostname'], t['port'], timeout=3) try: with target() as s: n_inputs = int(s.recvline().strip()) for _ in range(n_inputs): inp = s.recvline().strip() c1, c2, c3 = solve_for(inp) s.sendline('{} {} {}'.format(c1, c2, c3)) s.recvuntil("want?:") s.send("2\n3\n19\n"+t['flag_id']+"\n16\n"+"A"*16+"\n0\n") s.recvuntil("GameTime:") v19_c, v20_c, x_c, v22_c, v23_c, y_c = map(int, s.recv().split(', ')) solv = Solver() v18 = Int('v18') v21 = Int('v21') v19 = Int('v19') solv.add(v19 == v19_c) v20 = Int('v20') solv.add(v20 == v20_c) v22 = Int('v22') solv.add(v22 == v22_c) v23 = Int('v23') solv.add(v23 == v23_c) x = Int('x') solv.add(x == x_c) solv.add(x == v19*v18 + v20*v21) y = Int('y') solv.add(y == y_c) solv.add(y == v22*v18 + v21*v23) solv.check() solv.model() s.sendline(str(solv.model()[v18].as_long())) s.sendline(str(solv.model()[v21].as_long())) s.recvuntil("log:") s.send("15\n:83xkHFchNObsWf\n") s.recvuntil("):") s.sendline("478175") s.recvuntil("Name:") magic = s.recvuntil(":")[:-1] with target() as s: n_inputs = int(s.recvline().strip()) for _ in range(n_inputs): inp = s.recvline().strip() c1, c2, c3 = solve_for(inp) s.sendline('{} {} {}'.format(c1, c2, c3)) s.recvuntil("want?:") s.send("2\n5\n19\n"+t['flag_id']+"\n16\n"+magic+"\n") s.recvline() flag = s.recvline().strip() return flag except: return
def Synthesize(spec, specInputPorts, specConn, circuits): wellFormedConstraints = [Bool(True)] for circuit in circuits: wellFormedConstraints.append(circuit.GenerateWellFormednessConstraints()) wellFormedConstraints.append(GenerateCircuitSimilarityConstraints(circuits)) psiWfp = And(wellFormedConstraints) psiConn = And([circuit.GenerateConnectionConstraints() for circuit in circuits]) #if logger.IsLogging(): print psiConn examples = [] iterCounter = 0 synthSolver = Solver() verifSolver = Solver() synthSolver.assert_exprs(psiWfp) synthSolver.assert_exprs(GenerateConstraintForExample(spec, specConn, circuits, psiConn, {}, iterCounter)) while True: iterCounter+=1 if logger.IsLogging(): print 'Attempting Synthesis...' if synthSolver.check() == unsat: if logger.IsLogging(): print 'Synth Failed!' return False model = synthSolver.model() if logger.IsLogging(): print 'Synthesized program:\n' if logger.IsLogging(): for circuit in circuits: print circuit.funcName print circuit.LValToProg(model) print '\n' verifConstraint = GenerateVerificationConstraint(spec, specConn, circuits, psiConn, model) verifSolver.push() verifSolver.assert_exprs(verifConstraint) if logger.IsLogging(): print 'Attempting Verification...' #if logger.IsLogging(): print verifConstraint #raw_input("waiting for keypress") if (verifSolver.check() == unsat): if logger.IsLogging(): print 'Verification succeeded!\n' verifSolver.pop() if logger.IsLogging(): print 'Took %d iterations to '\ 'complete synthesis' % (iterCounter) if logger.IsLogging(): print 'Final Circuits:\n' printedCircuits = [] for circuit in circuits: if not circuit.funcName in printedCircuits: print circuit.GenerateCircuitExpression(model) printedCircuits.append(circuit.funcName) return True if logger.IsLogging(): print 'Verification Failed!\n' newExample = GetExampleFromInputModel(verifSolver.model(), specInputPorts) verifSolver.pop() examples.append(newExample) synthConstraintForExample = GenerateConstraintForExample(spec, specConn, circuits, psiConn, newExample, iterCounter) synthSolver.assert_exprs(synthConstraintForExample) if logger.IsLogging(): print 'Added Example %d:' % iterCounter if logger.IsLogging(): print newExample
def main(): cppfile = 'Vtop_b12.cpp' hfile = 'Vtop_b12.h' CoveragesToTest = range(104 + 1) cppstring=[] hstring=[] check = check_mod() check.readfi(cppfile, cppstring) check.readfi(hfile, hstring) seqfunc=[] check.get_seqfunc(cppstring, seqfunc) AllSigList = check.get_all_sig_names(hstring, seqfunc) parser = CParser() generator = c_generator.CGenerator() # cov_no = 1 for cov_no in CoveragesToTest: #cov_no = 3 #Making global instance of CParser and CCgenerator #as their they take a long time to run. So, just making it once print("\n\nCoverage No. to test : {}".format(cov_no)) trueCond, falseCond = check.getAllCondsForCovNo(seqfunc, cov_no) # Most probably this full search can be simplified to getting first false or true condition after detecting it CondType, CondNo = check.CondAboveCovNo(seqfunc, cov_no, trueCond, falseCond) SigOnDecision = [] if CondType == "falseCond": SigOnDecision = check.getSigFromCond(falseCond[CondNo], AllSigList) print("Coverage {} requires {} to be false".format(cov_no, falseCond[CondNo])) else: SigOnDecision = check.getSigFromCond(trueCond[CondNo], AllSigList) print("Coverage {} requires {} to be true".format(cov_no, trueCond[CondNo])) print("It involves Signal : {}".format(SigOnDecision)) SigAssignDict1 = check.GetAllAssignOfSig(SigOnDecision, seqfunc) SigAssgnStrip1 = check.StripSign(SigAssignDict1) NewSig1 = check.findNewSig(SigAssgnStrip1, SigOnDecision, AllSigList) print("Which is assigned values at {}".format(SigAssgnStrip1)) SigAssignDict2 = check.GetAllAssignOfSig(NewSig1, seqfunc) SigAssgnStrip2 = check.StripSign(SigAssignDict2) if len(NewSig1)>0: print("This involves New Signals = {}".format(NewSig1)) print("Which is assigned values at {}".format(SigAssgnStrip2)) if len(SigAssgnStrip2)>0: NewSig2 = [] SigOnDecision += NewSig1 NewSig2 = check.findNewSig(SigAssgnStrip2, SigOnDecision, AllSigList) if len(NewSig2)>0: print("This involves New Signals = {}".format(NewSig2)) SigOnDecision += NewSig2 NewSig3 = "Going 3 levels deep hasn't been implemented, Visit later :)" print(NewSig3) print("Final list of signals on which coverage {} depends {}\n".format(cov_no, SigOnDecision)) # Done getting all signals till here. #z3 signals initialization code z3Sigs = [] flag = 0 for Sigs in SigOnDecision: if type(AllSigList[Sigs]) == int: msb = AllSigList[Sigs] z3Sigs.append(BitVec('{}'.format(Sigs), msb)) # print("{} = BitVec(\'{}\', {})".format(Sigs, Sigs, msb)) else: print("""Error: Probably an array, whose definition for z3 hasn't been written\n\n""") flag = 1 break if flag == 1: continue print("All constraints on final signals are") s = Solver() for idx, cond in enumerate(trueCond): cond = cond.strip().replace(('vlTOPp->'), '').replace('(IData)','') for Sig in SigOnDecision: if re.search(r"\b{}\b".format(Sig), cond) is not None: print("{} should be true".format(trueCond[idx])) clause1 = check.GetZ3String(1, trueCond[idx], SigOnDecision, z3Sigs, parser, generator, AllSigList) if clause1 != "": clauseeval = eval(clause1) s.add(clauseeval) break for idx, cond in enumerate(falseCond): cond = cond.strip().replace(('vlTOPp->'), '').replace('(IData)','') for Sig in SigOnDecision: if re.search(r"\b{}\b".format(Sig), cond) is not None: #if any new signal is found then don't take this cond print("{} should be false".format(falseCond[idx])) clause1 = check.GetZ3String(0, falseCond[idx], SigOnDecision, z3Sigs, parser, generator, AllSigList) if clause1 != "": clauseeval = eval(clause1) s.add(clauseeval) break #need to put main condition first print("Assignments 1 level deep and their coverage no. are {}".format(SigAssgnStrip1)) print("Assignments 2 level deep and their coverage no. are {}".format(SigAssgnStrip2)) satis = [] unsatis = [] for Sig1 in SigAssgnStrip1: Sig1cl = check.GetZ3String(1, Sig1.replace(';',''), SigOnDecision, z3Sigs, parser, generator, AllSigList) if Sig1cl != "": Sig1s = eval(Sig1cl) s.push() s.add(Sig1s) Cover_No = int(SigAssgnStrip1[Sig1]) if s.check() == sat: if Cover_No not in satis: satis.append(Cover_No) else: if Cover_No not in unsatis: unsatis.append(Cover_No) for Sig2 in SigAssgnStrip2: sig2ss = check.GetZ3String(1, Sig2.replace(';',''), SigOnDecision, z3Sigs, parser, generator, AllSigList) if sig2ss != "": sig2s = eval(sig2ss) s.push() s.add(sig2s) # print s.check() Cover_No = int(SigAssgnStrip1[Sig1]) if s.check() == sat: if Cover_No not in satis: satis.append(Cover_No) else: if Cover_No not in unsatis: unsatis.append(Cover_No) s.pop() if Sig1cl != "": s.pop() print("Satisfiable Coverages are {}".format(satis)) print("Unsatisfiable Coverages are {}".format(unsatis)) if ((len(satis) == 0) and (len(unsatis) == 0)): print("Looks like 'Input' so can be assigned any value")
def __init__(self): self._solver = Solver()
def check(self, smt2_formula, context=None): s = Solver() s.add(parse_smt2_string((context if context else self.context) + smt2_formula)) return str(s.check())
def __init__(self, solver=0): if solver != 0: self.solver = solver else: self.solver = Solver() self.nameNumber = 0
def check_termination(trs, DEBUG=False): # create the variables we're solving for W = WeightFunction(trs.functions) P = Precedence(trs.functions) # create solver and constraints solver = Solver() if DEBUG: print("Solver created...") # constraint 1: weight constraints solver.assert_exprs(W[0] > 0) for f, arity in trs.functions.items(): solver.assert_exprs(P[f] >= 0) if arity == 0: solver.assert_exprs(W[f] >= W[0]) elif arity == 1: local_constraints = [] for g in trs.functions.keys(): local_constraints.append(P[f] >= P[g]) solver.assert_exprs(Implies(W[f] == 0, And(local_constraints))) if DEBUG: print("Weight constraints asserted...") # constraint 2: kbo constraint per rule for lhs, rhs in trs.rules: solver.assert_exprs(kbo(lhs, rhs, trs, W, P)) if DEBUG: print("Rule constraint asserted...") if DEBUG: for c in solver.assertions(): print(c.sexpr()) print("Starting z3...") start_time = clock() if solver.check() == unsat: if DEBUG: print("Done - z3 ran for {} seconds.".format(clock() - start_time)) return None else: model = solver.model() weights, precedence = {}, {} for f in trs.functions.keys(): weights[f] = model[W[f]].as_long() precedence[f] = model[P[f]].as_long() weights[0] = model[W[0]].as_long() if DEBUG: print("Done - z3 ran for {} seconds.".format(clock() - start_time)) return weights, precedence
def synthesize_with_components(self, components, constraint, system): # components maps unique comp_ids to component objects # not one-to-one, but def. onto # step 0: some useful values card_I, N = len(self.synth_function.parameters), len(components) # step 1: make some solvers synth_solver = Solver() verify_solver = Solver() # step 2: initialize examples S = [] # step 2b: create location variables and location constraints initial_constraints = [] L = create_location_variables(components) if system: patterns = create_pattern_constraints(L, components, system) initial_constraints.append(patterns) wfp = create_wfp_constraint(L, N) initial_constraints.append(wfp) # step 3: looooooooop while True: # step 4: assert L constraint synth_solver.assert_exprs(*initial_constraints) # step 5: start the looooop for i, X in enumerate(S): I, O, T = [], [], [] for w in range(constraint.width): # step 6: create I, O, T for synth at width i I_w = create_input_variables(self.synth_function.parameters, i, w) O_w = create_output_variables(self.synth_function.output, i, w) T_w = create_temp_variables(components, i, w) # step 7: assert library and connection constraints lib = create_lib_constraint(T_w, I_w, components) # for conn constraint, need map from component_id to l value locations = create_location_map(O_w, T_w, L, N) conn = create_conn_constraint(O_w, T_w, locations) synth_solver.assert_exprs(lib, conn) I += I_w O += O_w T += T_w # step 8: once we've got all the I, O, we can assert the spec constraint conn_spec, spec = create_spec_constraint(I, O, X, constraint) synth_solver.assert_exprs(conn_spec, spec) # get a model, or just bail if synth_solver.check() == unsat: if DEBUG: print("Failed to find a model.") return None model = synth_solver.model() curr_l = [l._replace(value=model[l.value]) for l in L] # step 9: need to verify the model we just found, so we'll construct verificatio constraint I, O, T = [], [], [] for w in range(constraint.width): # same as above, but we only have a single example I_w = create_input_variables(self.synth_function.parameters, 0, w) O_w = create_output_variables(self.synth_function.output, 0, w) T_w = create_temp_variables(components, 0, w) lib = create_lib_constraint(T_w, I_w, components) locations = create_location_map(O_w, T_w, curr_l, N) conn = create_conn_constraint(O_w, T_w, locations) verify_solver.assert_exprs(lib, conn) I += I_w O += O_w T += T_w # now we need to create variables for X so we can check our spec X = create_spec_variables(constraint, self.variables) conn_spec, spec = create_spec_constraint(I, O, X, constraint) verify_solver.assert_exprs(conn_spec, Not(spec)) # now we'll try and get a model of our exectution if verify_solver.check() == unsat: return curr_l model = verify_solver.model() example = [x._replace(value=model[x.value]) for x in X] S.append(example) if DEBUG: print("Found bad solution: ", [l.value.sexpr() for l in curr_l]) # clear synthesizers and start anew synth_solver.reset() verify_solver.reset() return None
from z3 import Solver, BitVec, sat s = Solver() q = [BitVec("q_%s" % (i),16) for i in range(17)] s.add([q[x] >= 33 for x in range(17)]) s.add([q[x] <= 125 for x in range(17)]) s.add(q[16] ^ 128 == 253) s.add(q[0] & q[16] == 121) s.add((q[0] + 2) % 5 == 0) s.add(q[11] == 95) s.add((q[5] >> (q[16] - q[0])) == 16) s.add((q[5] << (q[16] - q[0])) == 260) s.add(q[13] ^ q[11] == 110) s.add((q[13] * 1.0 / q[10]) == 7/11.0) # Floating points :( s.add(((q[13] & q[11]) * 4) + 1 == q[6]) s.add(q[5] & q[13] <= 17) s.add(q[1] - 9 == q[9]) s.add((q[7] & q[9]) == q[11] + (q[5] & q[13])) s.add(q[7] % 57 == 0) s.add((q[9] + q[11]) / 2 == q[12]) s.add(q[7] ^ q[3] == q[11]) s.add(q[3] ^ q[8] == 0) s.add(q[15] & q[3] == q[9] & q[8]) s.add(q[15] >> 3 == 6) s.add(q[15] % 5 == 3) s.add(q[4] ^ q[7] == q[5] - q[8]) s.add(q[2] & q[8] == 32) s.add(q[2] << 2 == q[0] + q[6]) s.add(q[14] % 29 == 0)
def __init__(self): ''' Constructor ''' print "=== Initializing language EuclidZ3 ===" # # make sorts self.PointSort = DeclareSort("Point") self.LineSort = DeclareSort("Line") self.CircleSort = DeclareSort("Circle") # # make basic relations between diagrammatic sorts self.Between = Function("Between", self.PointSort, self.PointSort, self.PointSort, BoolSort()) self.OnLine = Function("On", self.PointSort, self.LineSort, BoolSort()) self.OnCircle = Function("Onc", self.PointSort, self.CircleSort, BoolSort()) self.Inside = Function ("Inside" , self.PointSort, self.CircleSort, BoolSort()) self.Center = Function ("Center" , self.PointSort, self.CircleSort, BoolSort()) self.SameSide = Function("SameSide", self.PointSort, self.PointSort, self.LineSort, BoolSort()) self.Intersectsll = Function("Intersectsll", self.LineSort, self.LineSort, BoolSort()) self.Intersectslc = Function("Intersectslc", self.LineSort, self.CircleSort, BoolSort()) self.Intersectscc = Function("Intersectscc", self.CircleSort, self.CircleSort, BoolSort()) # # make the magnitude sorts self.Segment = Function("Segment", self.PointSort, self.PointSort, RealSort()) self.Angle = Function("Angle", self.PointSort, self.PointSort, self.PointSort, RealSort()) self.Area = Function("Area", self.PointSort, self.PointSort, self.PointSort, RealSort()) # # make constants/terms self.RightAngle = Const("RightAngle", RealSort()) a, b, c, d, e = Consts('a b c d e', self.PointSort) L, M, N = Consts('L M N' , self.LineSort) alpha, beta = Consts('alpha beta', self.CircleSort) # # assert self.axioms for language E self.axioms = [ ] """ ---------- DIAGRAMMATIC AXIOMS ---------- """ """ Two points determine a line 1. If a != b, a is on L, and b is L, a is on M and b is on M, then L = M """ self.axioms.append(ForAll([a, b, L, M], \ Implies(And(\ Not(a == b), self.OnLine(a, L), self.OnLine(b, L), \ self.OnLine(a, M), self.OnLine(b, M)), \ L == M))) """ self.Center of circle is unique 2. if a and b are both centers of alpha then a=b 3. if a is the center of alpha then a is inside alpha """ self.axioms.append(ForAll([a, b, alpha], \ Implies((And (self.Center(a, alpha), self.Center(b, alpha))), a == b))) self.axioms.append(ForAll([a, alpha], \ Implies(self.Center(a, alpha), self.Inside(a, alpha)))) """ No degenerate circles 4. if a is inside alpha, then a is not on alpha """ self.axioms.append(ForAll([a, alpha] , \ Implies(self.Inside(a, alpha), Not(self.OnCircle(a, alpha))))) """ Strict betweeness 1. If b is between a and c then b is between c and a, a != b, a != c, and a is not between b and c 2. If b is between a and c, a is on L, and b is on L, then c is on L. 3. If b is between a and c, a is on L, and c is on L, then b is on L. 4. If b is between a and c and d is between a and b then d is between a and c. 5. If b is between a and c and c is between b and d then b is between a and d. 6. if a, b, and c are distinct points on a line L, then either b is between a and c, or a is between b and c, or c is between a and b. 7. if b is between a and c and b is between a and d then b is not between c and d. """ self.axioms.append(ForAll([a, b, c], \ Implies(self.Between(a, b, c), \ And(self.Between(c, b, a), Not(a == c), Not(a == b), Not(self.Between(b, a, c)))))) self.axioms.append(ForAll([a, b, c], \ Implies(And(\ self.Between(a, b, c), self.OnLine(a, L), self.OnLine(b, L)), \ self.OnLine(c, L)))) self.axioms.append(ForAll([a, b, c], \ Implies(And(\ self.Between(a, b, c), self.OnLine(a, L), self.OnLine(c, L)), \ self.OnLine(b, L)))) self.axioms.append(ForAll([a, b, c], \ Implies(And(\ self.Between(a, b, c), self.Between(a, d, b)), \ self.Between(a, d, c)))) self.axioms.append(ForAll([a, b, c, d], \ Implies(And(\ self.Between(a, b, c), self.Between(b, c, d)), \ self.Between(a, b, d)))) self.axioms.append(ForAll([a, b, c, L], \ Implies(And(\ self.OnLine(a, L), self.OnLine(b, L), self.OnLine(c, L), \ Not(a == b), Not(a == c), Not(b == c)), \ Or(self.Between(a, b, c), self.Between(b, a, c), self.Between(a, c, b))))) self.axioms.append(ForAll([a, b, c, d], \ Implies(And(\ self.Between(a, b, c), self.Between(a, b, d)), \ Not(self.Between(d, b, c))))) """ Same-side self.axioms 1. if a is not on L, then a and a are on the same side of L. 2. if a and b are on the same side of L, then b and a are on teh same side of L. 3. if a and b are on the same side of L, then a is not on L. 4. if a and b are on the same side of L, and a and c are on the same side of L, then b and c are on the same side L. 5. if a,b, and c are not on L, and a and b are not on the same side of L, then either a and c are on the same side of L, or b """ self.axioms.append(ForAll([a, L], \ Implies(Not(self.OnLine(a, L)), \ self.SameSide(a, a, L)))) self.axioms.append(ForAll([a, b, L], \ Implies(self.SameSide(a, b, L), \ And(Not(self.OnLine(a, L), self.SameSide(b, a, L)))))) self.axioms.append(ForAll([a, b, c, L], \ Implies(And(\ self.SameSide(a, b, L), self.SameSide(a, c, L)), \ self.SameSide(b, c, L)))) self.axioms.append(ForAll([ a, b, c, L], \ Implies(And(\ Not(self.OnLine(a, L)), Not(self.OnLine(b, L)), Not(self.OnLine(c, L))), \ Or(self.SameSide(a, b, L), self.SameSide(a, c, L), self.SameSide(b, c, L))))) # # TODO: check this axiom below with avigad, # # "either a and c are sameside L, or b" # # is that sameside(a,c,L) or sameside(b,c,L) and NOT both? self.axioms.append(ForAll([a, b, c, L], \ Implies(And(\ Not(self.OnLine(a, L)), Not(self.OnLine(b, L)), Not(self.OnLine(c, L)), \ Not(self.SameSide(a, b, L))), \ Or(self.SameSide(a, c, L), self.SameSide(b, c, L))))) """ Pasch self.axioms 1. if b is between a and c, and a and c are on the same side of L, then a and b are on teh same side of L. 2. if b is between a and c, and a is on L and b is not on L, then b and c are on the same side of L. 3. if b is between a and c and b is on L then a and c are not on the same side of L 4. if b is the intersection of distinct lines L and M, a and c are distinct points on m, a != b, c !=b, and a and c are not on teh same side of L, then b is between a and c. """ self.axioms.append(ForAll([a, b, c, L], \ Implies(And(\ self.Between(a, b, c), self.SameSide(a, c, L)), \ self.SameSide(a, b, L)))) self.axioms.append(ForAll([a, b, c, L], \ Implies(And(\ self.Between(a, b, c), self.OnLine(a, L), Not(self.OnLine(b, L))), \ self.SameSide(b, c, L)))) self.axioms.append(ForAll([a, b, c, L], \ Implies(And(\ self.Between(a, b, c), self.OnLine(b, L)), \ Not(self.SameSide(a, c, L))))) self.axioms.append(ForAll([a, b, c, L, M], \ Implies(And(\ Not(a == b), Not(b == c), Not(L == M), \ self.OnLine(a, M), self.OnLine(b, M), self.OnLine(c, M), Not(self.SameSide(a, c, L)), self.OnLine(b, L)), \ self.Between(a, b, c)))) """ Triple incidence self.axioms 1. if L, M, and N are lines meeting at a point a, and b, c, and d are points on L, M,and N resctively, and if c and d are on the same side of L, and b and c are on the same side of N, then b and d are not on the same side of M. 2. if L,M,N are lines meeting at a point a, and b, c, and d are points on L M and N respectively, and if c and d are on the same side of L, and b and d are not on the same side of M, and d is not on M and b != a, then b and c are on the same side of N. 3. If L, M and N are lines meeting at a point a, and b, c, and d are points on L,M, and N respectively, and if c and d are on the same side of L, and b and c are on the same side of N, and d and e are on the sameside of M, and c and e are on the same side of N, then c and e are on the same side of L. """ self.axioms.append(ForAll([a, b, c, d, L, M, N], \ Implies(And(\ self.OnLine(a, L), self.OnLine(a, M), self.OnLine(a, N), self.OnLine(b, L), self.OnLine(c, M), self.OnLine(d, N), \ self.SameSide(c, d, L), self.SameSide(b, c, N)), \ Not(self.SameSide(b, d, M))))) self.axioms.append(ForAll([a, b, c, d], \ Implies(And(\ self.OnLine(a, L), self.OnLine(a, M), self.OnLine(a, N), \ self.OnLine(b, L), self.OnLine(c, M), self.OnLine(d, N), \ self.SameSide(c, d, L), Not(self.SameSide(d, b, M)), Not(self.OnLine(d, M)), Not(b == a)), \ self.SameSide(b, c, N)))) self.axioms.append(ForAll([a, b, c, d, e, L, M, N], \ Implies(And(\ self.OnLine(a, L), self.OnLine(c, M), self.OnLine(a, N), self.OnLine(b, L), \ self.OnLine(c, M), self.OnLine(d, N), self.SameSide(b, c, N), self.SameSide(d, c, L), \ self.SameSide(d, e, M), self.SameSide(c, e, N)), \ self.SameSide(c, e, L)))) """ Circle self.axioms """ self.axioms.append(ForAll([a, b, c, alpha, L], \ Implies(And(\ self.Inside(a, alpha), self.OnCircle(b, alpha), self.OnCircle(c, alpha), \ self.OnLine(a, L), self.OnLine(b, L), self.OnLine(c, L), Not(b == c)), \ self.Between(b, a, c)))) self.axioms.append(ForAll([a, b, c, alpha], \ Implies(And(\ Or(self.Inside(a, alpha), self.OnCircle(a, alpha)), Or(self.Inside(b, alpha), self.OnCircle(b, alpha)), \ self.Between(a, c, b)), \ And(Not(self.Inside(b, alpha)), Not(self.OnCircle(b, alpha)))))) self.axioms.append(ForAll([a, b, c, alpha, L], \ Implies(And(\ Or(self.Inside(a, alpha), self.OnCircle(a, alpha)), Not(self.Inside(c, alpha)), self.Between(a, c, b)), \ And(Not(self.Inside(b, alpha)), Not(self.OnCircle(b, alpha)))))) self.axioms.append(ForAll([a, b, c, d, alpha, beta], \ Implies(And(\ self.OnCircle(c, alpha), self.OnCircle(c, beta), self.OnCircle(d, alpha), self.OnCircle(d, beta), \ Not(alpha == beta), Not(c == d), self.OnLine(a, L), self.OnLine(b, L), \ self.Center(a, alpha), self.Center(a, beta)), \ Not(self.SameSide(c, d, L))))) """ Intersection """ self.axioms.append(ForAll([L, M, a, b], \ Implies(And(\ self.OnLine(a, M), self.OnLine(b, M), Not(self.SameSide(a, b, L))), \ self.Intersectsll(L, M)))) self.axioms.append(ForAll([alpha, L, a, b], \ Implies(And(\ Or(self.Inside(a, alpha), self.OnCircle(a, alpha)), \ Or(self.Inside(b, alpha), self.OnCircle(b, alpha)), \ Not(self.OnLine(a, L)), Not(self.OnLine(b, L)), Not(self.SameSide(a, b, L))), \ self.Intersectslc(L, alpha)))) self.axioms.append(ForAll([L, alpha, a], \ Implies(And(\ self.Inside(a, alpha), self.OnLine(a, L)), \ self.Intersectslc(L, alpha)))) self.axioms.append(ForAll([alpha, beta, a, b], \ Implies(And(\ self.OnCircle(a, alpha), Or(self.Inside(b, alpha), self.OnCircle(b, alpha)), \ self.Inside(a, beta), Not(self.Inside(b, beta)), Not(self.OnCircle(b, beta))), \ self.Intersectscc(alpha, beta)))) self.axioms.append(ForAll([alpha, beta, a, b], \ Implies(And(\ self.OnCircle(a, alpha), self.Inside(b, beta), self.Inside(a, beta), self.OnCircle(b, beta)), \ self.Intersectscc(alpha, beta)))) """ ---------- METRIC AXIOMS ---------- """ """ Segments """ self.axioms.append(ForAll([a, b], \ Implies(self.Segment(a, b) == RealVal(0.0), a == b))) self.axioms.append(ForAll([a], \ self.Segment(a, a) == RealVal(0.0))) self.axioms.append(ForAll([a, b], \ (self.Segment(a, b) >= RealVal(0.0)))) self.axioms.append(ForAll([a, b], \ self.Segment(a, b) == self.Segment(b, a))) """ Angles """ self.axioms.append(ForAll ([a, b, c], \ Implies(And(\ Not(a == b), Not(b == c)), \ self.Angle(a, b, c) == self.Angle(c, b, a)))) self.axioms.append(ForAll ([a, b, c], \ Implies(And(\ Not((a == b)), Not((b == c))), \ And(\ self.Angle(a, b, c) >= RealVal(0.0), \ self.Angle(a, b, c) <= (self.RightAngle + self.RightAngle))))) """ Areas """ self.axioms.append(ForAll([a, b], \ self.Area(a, a, b) == RealVal(0.0))) self.axioms.append(ForAll([a, b, c], \ self.Area(a, b, c) >= RealVal(0.0))) self.axioms.append(ForAll([a, b, c], \ And(self.Area(a, b, c) == self.Area(c, a, b), self.Area(a, b, c) == self.Area(b, a, c)))) """ ---------- Transfer AXIOMS ---------- """ """ Diagram-segment transfer self.axioms """ self.axioms.append(ForAll([a, b, c], \ Implies(self.Between(a, b, c), ((self.Segment(a, b) + self.Segment(b, c)) == self.Segment(a, c))))) # # center and radius determine circle self.axioms.append(ForAll([a, b, c, alpha, beta], \ Implies(And(\ self.Center(a, alpha), self.Center(a, beta), self.OnCircle(b, alpha), self.OnCircle(c, beta), \ self.Segment(a, b) == self.Segment(a, c)), \ (alpha == beta)))) self.axioms.append(ForAll([a, b, c, alpha], \ Implies(And(self.Center(a, alpha), self.OnCircle(b, beta), self.Segment(a, c) == self.Segment(a, b)), \ self.OnCircle(c, alpha)))) self.axioms.append(ForAll([a, b, c, alpha], \ Implies(And(\ self.Center(a, alpha), self.OnCircle(b, alpha)), \ ((self.Segment(a, c) == self.Segment(a, b)) == self.Inside(c, alpha))))) """ Diagram-angle transfer self.axioms """ self.axioms.append(ForAll([a, b, c, L], \ Implies(And(\ Not((a == b)), Not((a == c)), self.OnLine(a, L), self.OnLine(b, L)), \ (And(self.OnLine(c, L), Not(self.Between(c, a, b))) == (self.Angle(b, a, c) == RealVal(0.0)))))) # # Possibly this is superfluous self.axioms.append(ForAll([a, b], \ Implies(Not((a == b)), self.Angle(a, b, a) == RealVal(0.0)))) # # Point inside angle iff angles sum self.axioms.append(ForAll([a, b, c, d, L, M], \ Implies(And(\ self.OnLine(a, L), self.OnLine(b, L), self.OnLine(a, M), self.OnLine(c, M), \ Not((a == b)), Not((a == c)), Not(self.OnLine(d, L)), Not(self.OnLine(d, M)), \ Not((L == M))), \ ((self.Angle(b, a, c) == (self.Angle(b, a, d) + self.Angle(d, a, c))) == \ And(self.SameSide(b, d, M), self.SameSide(d, c, L)))))) # # Define right angle (and all right angles are equal) self.axioms.append(ForAll([a, b, c, d, L], \ Implies(And(\ self.OnLine(a, L), self.OnLine(b, L), self.Between(a, c, b), Not(self.OnLine(d, L))), \ ((self.Angle(a, c, d) == self.Angle(d, c, b)) == (self.Angle(a, c, d) == self.RightAngle))))) """ Diagram-area transfer self.axioms """ self.axioms.append(ForAll([a, b, c, L], \ Implies(And(\ self.OnLine(a, L), self.OnLine(b, L), Not((a == b))), \ ((self.Area(a, b, c) == RealVal(0.0)) == self.OnLine(c, L))))) # # Sum of Areas self.axioms.append(ForAll([a, b, c, d, L], \ Implies(And(\ self.OnLine(a, L), self.OnLine(b, L), self.OnLine(c, L), Not(self.OnLine(d, L)), \ Not((a == b)), Not((c == a)), Not((c == b))), \ (self.Between(a, c, b) == ((self.Area(a, c, d) + self.Area(d, c, b)) == self.Area(a, d, b)))))) self.solver = Solver() self.solver.add(self.axioms) print "Axiom set : " + str(self.solver.check())
def __call__(self, project, test, dump, validation_project): logger.info('inferring specification for test \'{}\''.format(test)) environment = dict(os.environ) if self.config['klee_max_forks'] is not None: environment['ANGELIX_KLEE_MAX_FORKS'] = str(self.config['klee_max_forks']) if self.config['klee_max_depth'] is not None: environment['ANGELIX_KLEE_MAX_DEPTH'] = str(self.config['klee_max_depth']) if self.config['klee_search'] is not None: environment['ANGELIX_KLEE_SEARCH'] = self.config['klee_search'] if self.config['klee_timeout'] is not None: environment['ANGELIX_KLEE_MAX_TIME'] = str(self.config['klee_timeout']) if self.config['klee_solver_timeout'] is not None: environment['ANGELIX_KLEE_MAX_SOLVER_TIME'] = str(self.config['klee_solver_timeout']) if self.config['klee_debug']: environment['ANGELIX_KLEE_DEBUG'] = 'YES' if self.config['klee_ignore_errors']: environment['KLEE_DISABLE_MEMORY_ERROR'] = 'YES' if self.config['use_semfix_syn']: environment['ANGELIX_USE_SEMFIX_SYN'] = 'YES' environment['ANGELIX_KLEE_WORKDIR'] = project.dir klee_start_time = time.time() self.run_test(project, test, klee=True, env=environment) klee_end_time = time.time() klee_elapsed = klee_end_time - klee_start_time statistics.data['time']['klee'] += klee_elapsed statistics.save() logger.info('sleeping for 1 second...') time.sleep(1) smt_glob = join(project.dir, 'klee-out-0', '*.smt2') smt_files = glob(smt_glob) err_glob = join(project.dir, 'klee-out-0', '*.err') err_files = glob(err_glob) err_list = [] for err in err_files: err_list.append(os.path.basename(err).split('.')[0]) non_error_smt_files = [] for smt in smt_files: smt_id = os.path.basename(smt).split('.')[0] if not smt_id in err_list: non_error_smt_files.append(smt) if not self.config['ignore_infer_errors']: smt_files = non_error_smt_files if len(smt_files) == 0 and len(err_list) == 0: logger.warning('No paths explored') raise NoSmtError() if len(smt_files) == 0: logger.warning('No non-error paths explored') raise NoSmtError() # loading dump # name -> value list oracle = dict() vars = os.listdir(dump) for var in vars: instances = os.listdir(join(dump, var)) for i in range(0, len(instances)): if str(i) not in instances: logger.error('corrupted dump for test \'{}\''.format(test)) raise InferenceError() oracle[var] = [] for i in range(0, len(instances)): file = join(dump, var, str(i)) with open(file) as f: content = f.read() oracle[var].append(content) # solving path constraints inference_start_time = time.time() angelic_paths = [] z3.set_param("timeout", self.config['path_solving_timeout']) solver = Solver() for smt in smt_files: logger.info('solving path {}'.format(relpath(smt))) try: path = z3.parse_smt2_file(smt) except: logger.warning('failed to parse {}'.format(smt)) continue variables = [str(var) for var in get_vars(path) if str(var).startswith('int!') or str(var).startswith('long!') or str(var).startswith('bool!') or str(var).startswith('char!') or str(var).startswith('reachable!')] try: outputs, choices, constants, reachable, original_available = parse_variables(variables) except: continue # name -> value list (parsed) oracle_constraints = dict() def str_to_int(s): return int(s) def str_to_long(s): return int(s) def str_to_bool(s): if s == 'false': return False if s == 'true': return True raise InferenceError() def str_to_char(s): if len(s) != 1: raise InferenceError() return s[0] dump_parser_by_type = dict() dump_parser_by_type['int'] = str_to_int dump_parser_by_type['long'] = str_to_long dump_parser_by_type['bool'] = str_to_bool dump_parser_by_type['char'] = str_to_char def bool_to_bv(b): if b: return BitVecVal(1, 32) else: return BitVecVal(0, 32) def int_to_bv(i): return BitVecVal(i, 32) def long_to_bv(i): return BitVecVal(i, 64) def char_to_bv(c): return BitVecVal(ord(c), 32) to_bv_converter_by_type = dict() to_bv_converter_by_type['bool'] = bool_to_bv to_bv_converter_by_type['int'] = int_to_bv to_bv_converter_by_type['long'] = long_to_bv to_bv_converter_by_type['char'] = char_to_bv def bv_to_bool(bv): return bv.as_long() != 0 def bv_to_int(bv): l = bv.as_long() if l >> 31 == 1: # negative l -= pow(2, 32) return l def bv_to_long(bv): l = bv.as_long() if l >> 63 == 1: # negative l -= pow(2, 64) return l def bv_to_char(bv): l = bv.as_long() return chr(l) from_bv_converter_by_type = dict() from_bv_converter_by_type['bool'] = bv_to_bool from_bv_converter_by_type['int'] = bv_to_int from_bv_converter_by_type['long'] = bv_to_long from_bv_converter_by_type['char'] = bv_to_char matching_path = True for expected_variable, expected_values in oracle.items(): if expected_variable == 'reachable': expected_reachable = set(expected_values) if not (expected_reachable == reachable): logger.info('labels \'{}\' executed while {} required'.format( list(reachable), list(expected_reachable))) matching_path = False break continue if expected_variable not in outputs.keys(): outputs[expected_variable] = (None, 0) # unconstraint does not mean wrong required_executions = len(expected_values) actual_executions = outputs[expected_variable][1] if required_executions != actual_executions: logger.info('value \'{}\' executed {} times while {} required'.format( expected_variable, actual_executions, required_executions)) matching_path = False break oracle_constraints[expected_variable] = [] for i in range(0, required_executions): type = outputs[expected_variable][0] try: value = dump_parser_by_type[type](expected_values[i]) except: logger.error('variable \'{}\' has incompatible type {}'.format(expected_variable, type)) raise InferenceError() oracle_constraints[expected_variable].append(value) if not matching_path: continue solver.reset() solver.add(path) def array_to_bv32(array): return Concat(Select(array, BitVecVal(3, 32)), Select(array, BitVecVal(2, 32)), Select(array, BitVecVal(1, 32)), Select(array, BitVecVal(0, 32))) def array_to_bv64(array): return Concat(Select(array, BitVecVal(7, 32)), Select(array, BitVecVal(6, 32)), Select(array, BitVecVal(5, 32)), Select(array, BitVecVal(4, 32)), Select(array, BitVecVal(3, 32)), Select(array, BitVecVal(2, 32)), Select(array, BitVecVal(1, 32)), Select(array, BitVecVal(0, 32))) def angelic_variable(type, expr, instance): pattern = '{}!choice!{}!{}!{}!{}!{}!angelic' s = pattern.format(type, expr[0], expr[1], expr[2], expr[3], instance) return Array(s, BitVecSort(32), BitVecSort(8)) def original_variable(type, expr, instance): pattern = '{}!choice!{}!{}!{}!{}!{}!original' s = pattern.format(type, expr[0], expr[1], expr[2], expr[3], instance) return Array(s, BitVecSort(32), BitVecSort(8)) def env_variable(expr, instance, name): pattern = 'int!choice!{}!{}!{}!{}!{}!env!{}' s = pattern.format(expr[0], expr[1], expr[2], expr[3], instance, name) return Array(s, BitVecSort(32), BitVecSort(8)) def output_variable(type, name, instance): s = '{}!output!{}!{}'.format(type, name, instance) if type == 'long': return Array(s, BitVecSort(32), BitVecSort(8)) else: return Array(s, BitVecSort(32), BitVecSort(8)) def angelic_selector(expr, instance): s = 'angelic!{}!{}!{}!{}!{}'.format(expr[0], expr[1], expr[2], expr[3], instance) return BitVec(s, 32) def original_selector(expr, instance): s = 'original!{}!{}!{}!{}!{}'.format(expr[0], expr[1], expr[2], expr[3], instance) return BitVec(s, 32) def env_selector(expr, instance, name): s = 'env!{}!{}!{}!{}!{}!{}'.format(name, expr[0], expr[1], expr[2], expr[3], instance) return BitVec(s, 32) for name, values in oracle_constraints.items(): type, _ = outputs[name] for i, value in enumerate(values): array = output_variable(type, name, i) bv_value = to_bv_converter_by_type[type](value) if type == 'long': solver.add(bv_value == array_to_bv64(array)) else: solver.add(bv_value == array_to_bv32(array)) for (expr, item) in choices.items(): type, instances, env = item for instance in range(0, instances): selector = angelic_selector(expr, instance) array = angelic_variable(type, expr, instance) solver.add(selector == array_to_bv32(array)) selector = original_selector(expr, instance) array = original_variable(type, expr, instance) solver.add(selector == array_to_bv32(array)) for name in env: selector = env_selector(expr, instance, name) array = env_variable(expr, instance, name) solver.add(selector == array_to_bv32(array)) result = solver.check() if result != z3.sat: logger.info('UNSAT') # TODO: can be timeout continue model = solver.model() # expr -> (angelic * original * env) list angelic_path = dict() if os.path.exists(self.load[test]): shutil.rmtree(self.load[test]) os.mkdir(self.load[test]) for (expr, item) in choices.items(): angelic_path[expr] = [] type, instances, env = item expr_str = '{}-{}-{}-{}'.format(expr[0], expr[1], expr[2], expr[3]) expression_dir = join(self.load[test], expr_str) if not os.path.exists(expression_dir): os.mkdir(expression_dir) for instance in range(0, instances): bv_angelic = model[angelic_selector(expr, instance)] angelic = from_bv_converter_by_type[type](bv_angelic) bv_original = model[original_selector(expr, instance)] original = from_bv_converter_by_type[type](bv_original) if original_available: logger.info('expression {}[{}]: angelic = {}, original = {}'.format(expr, instance, angelic, original)) else: logger.info('expression {}[{}]: angelic = {}'.format(expr, instance, angelic)) env_values = dict() for name in env: bv_env = model[env_selector(expr, instance, name)] value = from_bv_converter_by_type['int'](bv_env) env_values[name] = value if original_available: angelic_path[expr].append((angelic, original, env_values)) else: angelic_path[expr].append((angelic, None, env_values)) # Dump angelic path to dump folder instance_file = join(expression_dir, str(instance)) with open(instance_file, 'w') as file: if isinstance(angelic, bool): if angelic: file.write('1') else: file.write('0') else: file.write(str(angelic)) # Run Tester to validate the dumped values validated = self.run_test(validation_project, test, load=self.load[test]) if validated: angelic_paths.append(angelic_path) else: logger.info('spurious angelic path') if self.config['synthesis_bool_only']: angelic_paths = self._boolean_angelic_forest(angelic_paths) if self.config['max_angelic_paths'] is not None and \ len(angelic_paths) > self.config['max_angelic_paths']: angelic_paths = self._reduce_angelic_forest(angelic_paths) else: logger.info('found {} angelic paths for test \'{}\''.format(len(angelic_paths), test)) inference_end_time = time.time() inference_elapsed = inference_end_time - inference_start_time statistics.data['time']['inference'] += inference_elapsed iter_stat = dict() iter_stat['time'] = dict() iter_stat['time']['klee'] = klee_elapsed iter_stat['time']['inference'] = inference_elapsed iter_stat['paths'] = dict() iter_stat['paths']['explored'] = len(smt_files) iter_stat['paths']['angelic'] = len(angelic_paths) statistics.data['iterations']['klee'].append(iter_stat) statistics.save() return angelic_paths
import sys from z3 import Solver, BitVec def print_dword(dword): sys.stdout.write(chr(dword & 0xFF) + chr((dword >> 8) & 0xFF) + chr((dword >> 16) & 0xFF) + chr((dword >> 24) & 0xFF)) dword_1 = BitVec('dword_1', 32) dword_2 = BitVec('dword_2', 32) dword_3 = BitVec('dword_3', 32) dword_4 = BitVec('dword_4', 32) dword_5 = BitVec('dword_5', 32) dword_6 = BitVec('dword_6', 32) dword_7 = BitVec('dword_7', 32) dword_8 = BitVec('dword_8', 32) s = Solver() s.add(dword_3 + dword_2 == 0x0C0DCDFCE) s.add(dword_3 + dword_2 == 0x0C0DCDFCE) s.add(dword_2 + dword_1 == 0x0D5D3DDDC) s.add((dword_2 * 5) + (dword_1 * 3) == 0x404A7666) s.add((dword_4 ^ dword_1) == 0x18030607) s.add((dword_1 & dword_4) == 0x666C6970) s.add(dword_2 * dword_5 == 0xB180902B) s.add(dword_5 * dword_3 == 0x3E436B5F) s.add(dword_5 + (dword_6 * 2) == 0x5C483831) s.add((dword_6 & 0x70000000) == 0x70000000) s.add(dword_6 / dword_7 == 1) s.add(dword_6 % dword_7 == 0x0E000CEC) s.add((dword_5 * 3) + (dword_8 * 2) == 0x3726EB17) s.add((dword_8 * 7) + (dword_3 * 4) == 0x8B0B922D)
e = ExprId('e', 1) left = ExprCond(e + ExprOp('parity', a), ExprMem(a * a, 64), ExprMem(a, 64)) cond = ExprSlice(ExprSlice(ExprSlice(a, 0, 32) + b, 0, 16) * c, 0, 8) << ExprOp('>>>', d, ExprInt(uint8(0x5L))) right = ExprCond(cond, a + ExprInt(uint64(0x64L)), ExprInt(uint64(0x16L))) e = ExprAff(left, right) # initialise translators t_z3 = TranslatorZ3() t_smt2 = TranslatorSMT2() # translate to z3 e_z3 = t_z3.from_expr(e) # translate to smt2 smt2 = t_smt2.to_smt2([t_smt2.from_expr(e)]) # parse smt2 string with z3 smt2_z3 = parse_smt2_string(smt2) # initialise SMT solver s = Solver() # prove equivalence of z3 and smt2 translation s.add(e_z3 != smt2_z3) assert (s.check() == unsat)
def test1(): print "=== Loading Core ===" solver = Solver() solver.push() solver.add(language.axioms) print "=== Starting tests ===" print ">> Let p q r s t u v be distinct points" p, q, r, s, t, u, v = Consts('p q r s t u v', language.PointSort) solver.add(simplify(Distinct(p,q,r,s,t,u,v), blast_distinct=True)) print ">> Let L M N O be distinct lines" K, L, M, N, O = Consts('K L M N O', language.LineSort) solver.add(simplify(Distinct(K,L,M,N,O), blast_distinct=True)) ## Diagram description assumptions = [] assumptions.append(language.OnLine(p,L)) assumptions.append(language.OnLine(q,L)) assumptions.append(language.OnLine(p,N)) assumptions.append(language.OnLine(s,N)) assumptions.append(language.OnLine(t,N)) assumptions.append(language.OnLine(p,M)) assumptions.append(language.OnLine(r,M)) assumptions.append(language.OnLine(q,O)) assumptions.append(language.OnLine(s,O)) assumptions.append(language.OnLine(r,O)) assumptions.append(language.OnLine(q,K)) assumptions.append(language.OnLine(t,K)) assumptions.append(Not(language.OnLine(r,L))) assumptions.append(language.Between(p,s,t)) assumptions.append(language.Between(q,s,r)) assumptions.append(language.Between(s,u,t)) assumptions.append(Not(p == q)) assumptions.append(language.Between(p,q,v)) print ">> Assume " + str(assumptions) solver.add(assumptions) print " << z3: " + str(solver.check()) ## Satisfied solver.push() solver.add(True) print ">> Hence True" print " << z3: " + str(solver.check()) solver.pop() ## Satisfied solver.push() solver.add(Not(language.SameSide(s,t,O))) print ">> Hence s and t are on opposite sides of O" print " << z3: " + str(solver.check()) solver.pop() ## Satisfied solver.push() solver.add(language.SameSide(u,t,M)) print ">> Hence u and t are on same side of M" print " << z3: " + str(solver.check()) solver.pop() ## unsatisfied solver.push() solver.add(language.SameSide(p,t,O)) print ">> Hence p and t are on same side of O" print " << z3: " + str(solver.check()) solver.pop() ## unsatisfied solver.push() solver.add(language.SameSide(s,t,O)) print ">> Hence s and t are on same side of O" print " << z3: " + str(solver.check()) solver.pop() ## unsatisfied solver.push() solver.add(Not(language.SameSide(s,t,M))) print ">> Hence s and t are on opposite sides of M" print " << z3: " + str(solver.check()) solver.pop() ## unsatisfied solver.push() solver.add(Not(language.SameSide(u,t,M))) print ">> Hence u and t are on opposite sides of M" print " << z3: " + str(solver.check()) solver.pop() ## unsatisfied solver.push() solver.add(language.Between(s,p,t)) print ">> Hence p is between s and t" print " << z3: " + str(solver.check()) solver.pop() ## unsatisfied solver.push() solver.add(M == N) print ">> Hence p is between s and t" print " << z3: " + str(solver.check()) solver.pop() ## unsatisfied solver.push() solver.add(language.Between(q,s,u)) print ">> Hence s is between q and u" print " << z3: " + str(solver.check()) solver.pop() ## unsatisfied solver.push() solver.add(Not( language.Segment(s,u) < language.Segment(s,t))) print ">> Hence seg su is less than seg st" print " << z3: " + str(solver.check()) solver.pop() ## unsatisfied solver.push() solver.add(L==K) print ">> Hence L = K" print " << z3: " + str(solver.check()) solver.pop()
from z3 import Real, Solver s = Solver() x = Real('x') s.add((x * 3.0 + 18.0) == (x * 12.56637061435917)) print s.check() print s.model() print s.model()[x].as_decimal(10)
class ACL22SMT(object): class status: def __init__(self, value): self.value = value def __str__(self): if self.value is True: return "QED" elif self.value.__class__ == "msg".__class__: return self.value else: raise Exception("unknown status?") def isThm(self): return self.value is True class atom: # added my mrg, 21 May 2015 def __init__(self, string): self.who_am_i = string.lower() def __eq__(self, other): return self.who_am_i == other.who_am_i def __ne__(self, other): return self.who_am_i != other.who_am_i def __str__(self): return self.who_am_i def __init__(self, solver=0): if solver != 0: self.solver = solver else: self.solver = Solver() self.nameNumber = 0 def newVar(self): varName = "$" + str(self.nameNumber) self.nameNumber = self.nameNumber + 1 return varName def isBool(self, who): return Bool(who) def isInt(self, who): return Int(who) def isReal(self, who): return Real(who) def plus(self, *args): return reduce(lambda x, y: x + y, args) def times(self, *args): return reduce(lambda x, y: x * y, args) def reciprocal(self, x): if type(x) is int: return Q(1, x) elif type(x) is float: return 1.0 / x else: return 1.0 / x def negate(self, x): return -x def lt(self, x, y): return x < y def equal(self, x, y): return x == y def notx(self, x): return Not(x) def implies(self, x, y): return Implies(x, y) def Qx(self, x, y): return Q(x, y) # type related functions def integerp(self, x): return sort(x) == IntSort() def rationalp(self, x): return sort(x) == RealSort() def booleanp(self, x): return sort(x) == BoolSort() def ifx(self, condx, thenx, elsex): return If(condx, thenx, elsex) # usage prove(claim) or prove(hypotheses, conclusion) def prove(self, hypotheses, conclusion=0): if conclusion is 0: claim = hypotheses else: claim = Implies(hypotheses, conclusion) self.solver.push() self.solver.add(Not(claim)) res = self.solver.check() if res == unsat: print "proved" return self.status(True) # It's a theorem elif res == sat: print "counterexample" m = self.solver.model() print m # return an counterexample?? return self.status(False) else: print "failed to prove" r = self.status(False) self.solver.pop() return r