def initialize_z3(self): self.predicate_expr = True z3.set_option(html_mode=False) if self.config.z3_parallel: z3.set_param("parallel.enable", True) if self.config.z3_parallel_max_threads: z3.set_param("parallel.threads.max", self.config.z3_parallel_max_threads)
def main(args): if args.randomize_input: seed = int.from_bytes(os.getrandom(8), "big") z3.set_param( "smt.phase_selection", 5, "smt.random_seed", seed, "smt.arith.random_initial_value", True, "sat.phase", "random", ) config = {} config["arch"] = args.arch if config["arch"] == "tna": config["pipe_name"] = "pipe0_ingress" config["ingress_var"] = "ingress" elif config["arch"] == "v1model": config["pipe_name"] = "ig" config["ingress_var"] = "ig" elif config["arch"] == "psa": config["pipe_name"] = "ingress_ig" config["ingress_var"] = "ig" else: raise RuntimeError("Unsupported test arch \"%s\"!" % config["arch"]) if args.p4_input: p4_input = Path(args.p4_input) out_base_dir = Path(args.out_dir) else: out_base_dir = Path(args.out_dir).joinpath("rnd_test") util.check_dir(out_base_dir) p4_input = out_base_dir.joinpath("rnd_test.p4") # generate a random program from scratch generate_p4_prog(P4RANDOM_BIN, p4_input, config) if os.path.isfile(p4_input): out_dir = out_base_dir.joinpath(p4_input.stem) util.del_dir(out_dir) config["out_dir"] = out_dir config["p4_input"] = p4_input result = perform_blackbox_test(config) else: util.check_dir(out_base_dir) for p4_file in list(p4_input.glob("**/*.p4")): out_dir = out_base_dir.joinpath(p4_file.stem) util.del_dir(out_dir) config["out_dir"] = out_dir config["p4_input"] = p4_file result = perform_blackbox_test(config) sys.exit(result)
def main(args): # configure logging logging.basicConfig(filename=args.log_file, format="%(levelname)s:%(message)s", level=logging.INFO, filemode='w') stderr_log = logging.StreamHandler() stderr_log.setFormatter(logging.Formatter("%(levelname)s:%(message)s")) logging.getLogger().addHandler(stderr_log) if args.randomize_input: z3.set_param( "smt.phase_selection", 5, "smt.arith.random_initial_value", True, "sat.phase", "random", ) config = {} config["use_tofino"] = args.use_tofino if args.use_tofino: config["pipe_name"] = "Pipeline_ingress" config["ingress_var"] = "ingress" else: config["pipe_name"] = "ig" config["ingress_var"] = "ig" if args.p4_input: p4_input = Path(args.p4_input) out_base_dir = Path(args.out_dir) else: out_base_dir = Path(args.out_dir).joinpath("rnd_test") util.check_dir(out_base_dir) p4_input = out_base_dir.joinpath("rnd_test.p4") # generate a random program from scratch generate_random_prog(P4RANDOM_BIN, p4_input, config) if os.path.isfile(p4_input): out_dir = out_base_dir.joinpath(p4_input.stem) util.del_dir(out_dir) config["out_dir"] = out_dir config["p4_input"] = p4_input result = perform_blackbox_test(config) else: util.check_dir(out_base_dir) for p4_file in list(p4_input.glob("**/*.p4")): out_dir = out_base_dir.joinpath(p4_file.stem) util.del_dir(out_dir) config["out_dir"] = out_dir config["p4_input"] = p4_file result = perform_blackbox_test(config) sys.exit(result)
def recover(op, count, lowbits, verbose): """State recovery from full output""" print '[x] load' assert count > 0 a,b,c,d = st = raninit() slv = z3.Solver() if verbose: z3.set_param(verbose=10) # print tactics as they're applied qs = [] for i in range(count): st,out = ranval(st) q = z3.BitVec('q%d'%i, 64) slv.add(q == out) qs.append(q) print '[x] ranval iterations' if op=='forward': if 0: # actual state should be 256 mixed bits due to urandom input slv.add(a == 1337, b == 1338, c == 0xbeef, d == 0xdead) else: slv.add(a == 0x7ceb42733f66b473, b == 0x6b44d35a1f639f60, c == 0xead7949879cb1623, d == 0x9565653158395212103) elif op=='reverse': if 0: #slv.add(a == 1337, b == 1338, c == 0xbeef, d == 0xdead) slv.add(qs[4] == 6515443366520749290) slv.add(qs[3] == 15987207590933627957) slv.add(qs[2] == 12139072452908344637) slv.add(qs[1] == 17436066800174026442) slv.add(qs[0] == 400248179) else: # TODO generate these instead of copy-pasting lol q_vals = [ 6985222460364329868, 10544382677601029469, 15438707448398115707, 16064190778767654258, 282720256118252307, 18290176035634059913, 1825954770632955011, 11019636138942255088, 9429738565397434521, 6583642313917153474, 11369469077210583108, 590431549771258938, 291271844620794731, 4009518777267550210, 8383857281027991160 ] # 15 of 'em, considering that output is directly from 1/4th of # state that should be plenty... q_vals.reverse() for i in range(count): slv.add(qs[i] == q_vals[i]) print '[x] constraints' sat_ret = slv.check() print '[x] result:', sat_ret if sat_ret == z3.sat: print(slv.model()) elif sat_ret == z3.unsat: print(slv.unsat_core())
def do_updr(s: Solver) -> None: if utils.args.use_z3_unsat_cores: z3.set_param('smt.core.minimize', True) logic.check_init(s, safety_only=True) fs = updr.Frames(s) try: fs.search() finally: utils.logger.info(f'updr learned {fs.state_count} states (possibly with duplicates)') utils.logger.info(f'updr learned {len(fs.predicates)} predicates (no duplicates)') for x in fs.predicates: utils.logger.info(str(x))
class Problem(solving.Problem): z3.set_param('sat.cardinality.solver', False) # improves (!) performance of cardinality constraints def __init__(self, variable_names: Sequence[str], qualities: Sequence[float]): assert len(variable_names) == len(qualities) # Improve optimizer performance by sorting qualities decreasingly; adapt order of variable names accordingly: qualities, variable_names = zip( *sorted(zip(qualities, variable_names), key=lambda x: -x[0])) self.qualities = qualities self.variables = [expr.Variable(name=x) for x in variable_names] self.constraints = [] self.optimizer = z3.Optimize() # Direct multiplication between bool var and real quality returns wrong type (BoolRef) if quality is 1, # so we use "If" instead (multiplication is transformed to such an expression anyway): objective = z3.Sum([ z3.If(var.get_z3(), q, 0) for (q, var) in zip(qualities, self.get_variables()) ]) self.objective = self.optimizer.maximize(objective) self.optimizer.push() # restore point for state without constraints def get_qualities(self) -> Sequence[float]: return self.qualities def add_constraint(self, constraint: expr.BooleanExpression) -> None: super().add_constraint(constraint) self.optimizer.add(constraint.get_z3( )) # AttributeError if attribute "z3_expr" not set in "constraint" # Remove all constraints def clear_constraints(self) -> None: super().clear_constraints() self.optimizer.pop() # go to restore point (state with no constraints) self.optimizer.push( ) # create new restore point (again, with no constraints) # Run optimization and return result dict def optimize(self) -> Dict[str, Union[float, Sequence[str]]]: self.optimizer.check() # Object value can have different types, depending on whether result is a whole number if self.objective.value().is_int(): # type IntNumRef value = self.objective.value().as_long() else: # type RatNumRef value = self.objective.value().numerator_as_long( ) / self.objective.value().denominator_as_long() model = self.optimizer.model() selected = [ var.get_name() for var in self.get_variables() if str(model[var.get_z3()]) == 'True' ] return { 'objective_value': value, 'num_selected': len(selected), 'selected': selected }
def do_updr(s: Solver) -> None: if utils.args.use_z3_unsat_cores: z3.set_param('smt.core.minimize', True) if logic.check_init(s, safety_only=True, verbose=True) is not None: return if not utils.args.checkpoint_in: fs = updr.Frames(s) else: fs = updr.load_frames(utils.args.checkpoint_in, s) try: fs.search() print('updr found inductive invariant!') except updr.AbstractCounterexample: print('updr found abstract counterexample!') pass
def run(self, args, extra): opts = dict() if args.yaml is not None: opts = parse_yaml_options(args.yaml) for a in extra: k, v = parse_z3_arg(a) opts[k] = v if args.solver == "fp": db = load_horn_db_from_file(args.in_file) z3.set_param(verbose=args.verbose) for tr_lvl in args.tr: z3.enable_trace(tr_lvl) res = chc_solve_with_fp(db, args, opts) print(res) elif args.solver == "cli": chc_solve_with_cli(args.in_file, args, opts) return 0
def keq2(): r_disp, r_accel, r_vi, r_vf, r_time = z3.Reals('d a vi vf t') solver_s = z3.Solver() equations = [ r_disp == r_vi * r_time + (r_accel * r_time **2) / 2, r_vf == r_vi + r_accel * r_time ] problem = [ r_vi == 0.00, r_accel == 6.00, r_time == 4.10 ] solver_s.add(equations + problem) z3.set_param(rational_to_decimal=True) print "Solving problem 2" print solver_s.check() print solver_s.model()
def do_updr(s: Solver) -> None: if utils.args.use_z3_unsat_cores: z3.set_param('smt.core.minimize', True) logic.check_init(s, safety_only=True) if not utils.args.checkpoint_in: fs = updr.Frames(s) else: fs = updr.load_frames(utils.args.checkpoint_in, s) try: fs.search() except updr.AbstractCounterexample: pass finally: utils.logger.info( f'updr learned {fs.state_count} states (possibly with duplicates)') utils.logger.info( f'updr learned {len(fs.predicates)} predicates (no duplicates)')
def mk(cls, using_nla=False, myseed=None): if using_nla: int_theory = 'qfnia' # qfnra real_theory = 'qfnra' else: int_theory = 'qflia' # qflia real_theory = 'qflra' ti = z3.Tactic(int_theory) tr = z3.Tactic(real_theory) if myseed: z3.set_param('smt.arith.random_initial_value', True) p = z3.ParamsRef() p.set("random-seed", myseed) ti = z3.WithParams(ti, p) tr = z3.WithParams(tr, p) t = z3.ParOr(ti, tr) t = z3.TryFor(t, settings.SOLVER_TIMEOUT) return t.solver()
def ResetZ3(): z3._main_ctx = None z3.main_ctx() z3.set_param('smt.random_seed', random.SystemRandom().randint(0, sys.maxint)) z3.set_param('smt.mbqi.max_iterations', 10000) z3.set_param('smt.mbqi.max_cexs', 100)
def setUpClass(cls): # generate a known stable linear system n = 2 zeta = 0.2 # damping factor wn = 2.0 * np.pi * 10.0 # natural frequency h = 0.01 # sampling rate assert 2.0 * np.pi / wn >= 2.0 * h, 'Nyquist is unhappy' # damped oscillator cls.Ac_osc = np.array([[0, 1], [-wn*wn, -2*zeta*wn]]) cls.Ad_osc = expm(h * cls.Ac_osc) # known Metzler system cls.Ac_met = np.array([[-15, 12], [4, -25]]) cls.Ad_met = expm(h * cls.Ac_met) # diagonal system cls.Ac_diag = np.array([[-20, 0], [0, -25]]) cls.Ad_diag = expm(h * cls.Ac_diag) # check that generated examples are already stable for Ad in [cls.Ad_osc, cls.Ad_met, cls.Ad_diag]: assert all([abs(ev) < 0.9 for ev in eigvals(Ad)]) # set up global z3 parameters # parameters from https://stackoverflow.com/a/12516269 z3.set_param('auto_config', False) z3.set_param('smt.case_split', 5) z3.set_param('smt.relevancy', 2)
#!/bin/env python3 from z3 import Solver, BitVec, BitVecVal, set_param # TODO: which of these two syntaxes is correct? #set_param(parallel_enable=True) set_param("parallel.enable", True) prefixes = (b"dozmarbinwansamlitsighidfidlissogdirwacsabwissib" b"rigsoldopmodfoglidhopdardorlorhodfolrintogsilmir" b"holpaslacrovlivdalsatlibtabhanticpidtorbolfosdot" b"losdilforpilramtirwintadbicdifrocwidbisdasmidlop" b"rilnardapmolsanlocnovsitnidtipsicropwitnatpanmin" b"ritpodmottamtolsavposnapnopsomfinfonbanmorworsip" b"ronnorbotwicsocwatdolmagpicdavbidbaltimtasmallig" b"sivtagpadsaldivdactansidfabtarmonranniswolmispal" b"lasdismaprabtobrollatlonnodnavfignomnibpagsopral" b"bilhaddocridmocpacravripfaltodtiltinhapmicfanpat" b"taclabmogsimsonpinlomrictapfirhasbosbatpochactid" b"havsaplindibhosdabbitbarracparloddosbortochilmac" b"tomdigfilfasmithobharmighinradmashalraglagfadtop" b"mophabnilnosmilfopfamdatnoldinhatnacrisfotribhoc" b"nimlarfitwalrapsarnalmoslandondanladdovrivbacpol" b"laptalpitnambonrostonfodponsovnocsorlavmatmipfip") suffixes = (b"zodnecbudwessevpersutletfulpensytdurwepserwylsun" b"rypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnex" b"lunmeplutseppesdelsulpedtemledtulmetwenbynhexfeb" b"pyldulhetmevruttylwydtepbesdexsefwycburderneppur" b"rysrebdennutsubpetrulsynregtydsupsemwynrecmegnet" b"secmulnymtevwebsummutnyxrextebfushepbenmuswyxsym" b"selrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpel" b"syptermebsetdutdegtexsurfeltudnuxruxrenwytnubmed"
from ivy_core import minimize_core, biased_core import ivy_utils as iu import ivy_unitres as ur import logic as lg import sys # Following accounts for Z3 API symbols that are hidden as of Z3-4.5.0 z3_to_ast_array = z3._to_ast_array if '_to_ast_array' in z3.__dict__ else z3.z3._to_ast_array z3_to_expr_ref = z3._to_expr_ref if '_to_expr_ref' in z3.__dict__ else z3.z3._to_expr_ref use_z3_enums = False #z3.set_param('smt.mbqi.trace',True) z3.set_param('smt.macro_finder', True) def set_use_native_enums(t): global use_z3_enums use_z3_enums = t def solver_name(symbol): name = symbol.name if name in iu.polymorphic_symbols: sort = symbol.sort.domain[0].name if sort in ivy_logic.sig.interp and not isinstance( ivy_logic.sig.interp[sort], ivy_logic.EnumeratedSort): return None name += ':' + sort
def ResetZ3(seed): z3._main_ctx = None z3.main_ctx() z3.set_param('smt.random_seed', seed)
from z3 import Int, IntVector, Bool, Optimize, Implies, And, Or, If, sat, set_param from device import qcdevice from input import read_qasm, dependency_extracting import os import time as sys_time import sys from ast import literal_eval import math from info import qiskit_info_after, qiskit_info_original start_time = sys_time.time() set_param("parallel.enable", True) set_param("parallel.threads.max", 64) file_name = sys.argv[1] device_name = sys.argv[2] objective_name = sys.argv[3] # T = literal_eval(sys.argv[3]) device_test = qcdevice(device_name) N = device_test.count_physical_qubit e = device_test.connection_list S = 1 [M, g, gate_spec] = read_qasm(file_name) new_file_name = "result/paper/" + file_name.split('/')[-1].replace('.qasm', "_{}_tbolsq_{}".format(device_name, objective_name))
def ResetZ3(): z3._main_ctx = None z3.main_ctx() z3.set_param('auto_config', False) z3.set_param('smt.mbqi', True) z3.set_param('model.compact', True) z3.set_param('smt.pull_nested_quantifiers', True) z3.set_param('smt.mbqi.max_iterations', 10000) z3.set_param('smt.random_seed', random.SystemRandom().randint(0, sys.maxint))
def main(argv): smt_file = argv[0] z3.set_param('rewriter.div0_ackermann_limit', 1000000000) sparse, factor = calculate(smt_file) print(str(sparse) + "," + str(factor))
def ResetZ3 (): z3._main_ctx = None z3.main_ctx() z3.set_param('smt.random_seed', random.SystemRandom().randint(0, sys.maxint))
import z3 Humain = z3.DeclareSort('Humain') Socrate = z3.Const('Socrate', Humain) is_Mortel = z3.Function('is_Mortel', Humain, z3.BoolSort()) is_Humain = z3.Function('is_Humain', Humain, z3.BoolSort()) s = z3.Solver() x = z3.Const('x', Humain) s.add(z3.ForAll(x, z3.Implies(is_Humain(x), is_Mortel(x)))) s.add(is_Humain(Socrate)) s.add(z3.Not(is_Mortel(Socrate))) print(s.check()) print('-----') z3.set_param(proof=True) Humain = z3.DeclareSort('Humain') Socrate = z3.Const('Socrate', Humain) is_Mortel = z3.Function('is_Mortel', Humain, z3.BoolSort()) is_Humain = z3.Function('is_Humain', Humain, z3.BoolSort()) s = z3.Solver() x, y, z = z3.Consts('x y z', Humain) s.add(z3.ForAll(x, z3.Implies(is_Humain(x), is_Mortel(x)))) s.add(is_Humain(Socrate)) s.add(is_Mortel(Socrate)) print(s.check()) print(s.model())
def main() -> None: resource.setrlimit( resource.RLIMIT_AS, (90 * 10**9, 90 * 10**9) ) # limit RAM usage to 45 GB # TODO: make this a command line argument # TODO: not sure if this is actually the right way to do this (also, what about child processes?) utils.args = parse_args(sys.argv[1:]) if utils.args.log_xml: fmt = '%(message)s' elif utils.args.log_time: fmt = '%(asctime)s %(filename)s:%(lineno)d: %(message)s' else: fmt = '%(filename)s:%(lineno)d: %(message)s' if 'json' in utils.args and utils.args.json: utils.args.log = 'critical' utils.logger.setLevel(getattr(logging, utils.args.log.upper(), None)) handler = logging.StreamHandler(stream=sys.stdout) handler.terminator = '' handler.setFormatter(MyFormatter(fmt)) logging.root.addHandler(handler) # utils.logger.addHandler(handler) with utils.LogTag(utils.logger, 'main', lvl=logging.INFO): if utils.args.print_cmdline: with utils.LogTag(utils.logger, 'options', lvl=logging.INFO): utils.logger.info(' '.join([sys.executable] + sys.argv)) utils.logger.info('Running mypyvy with the following options:') for k, v in sorted(vars(utils.args).items()): utils.logger.info(f' {k} = {v!r}') utils.logger.info('setting seed to %d' % utils.args.seed) z3.set_param('smt.random_seed', utils.args.seed) # utils.logger.info('enable z3 macro finder') # z3.set_param('smt.macro_finder', True) if utils.args.timeout is not None: utils.logger.info('setting z3 timeout to %s' % utils.args.timeout) z3.set_param('timeout', utils.args.timeout) pre_parse_error_count = utils.error_count with open(utils.args.filename) as f: prog = parse_program( f.read(), force_rebuild=utils.args.forbid_parser_rebuild, filename=utils.args.filename) if utils.error_count > pre_parse_error_count: utils.logger.always_print('program has syntax errors.') sys.exit(1) if utils.args.print_program_repr: utils.logger.always_print(repr(prog)) if utils.args.print_program: utils.logger.always_print(str(prog)) pre_resolve_error_count = utils.error_count prog.resolve() if utils.error_count > pre_resolve_error_count: utils.logger.always_print('program has resolution errors.') sys.exit(1) syntax.the_program = prog s = Solver() # initialize common keys s.get_translator(KEY_ONE) s.get_translator(KEY_NEW) s.get_translator(KEY_OLD) utils.args.main(s) utils.logger.info('total number of queries: %s' % s.nqueries) if utils.args.ipython: ipython(s) sys.exit(1 if utils.error_count > 0 else 0)
def main() -> None: # limit RAM usage to 45 GB # TODO: make this a command line argument # TODO: not sure if this is actually the right way to do this (also, what about child processes?) resource.setrlimit(resource.RLIMIT_AS, (90 * 10**9, 90 * 10**9)) utils.args = parse_args(sys.argv[1:]) if utils.args.log_xml: fmt = '%(message)s' elif utils.args.log_time: fmt = '%(asctime)s %(filename)s:%(lineno)d: %(message)s' else: fmt = '%(filename)s:%(lineno)d: %(message)s' if 'json' in utils.args and utils.args.json: utils.args.log = 'critical' utils.logger.setLevel(getattr(logging, utils.args.log.upper(), None)) handler = logging.StreamHandler(stream=sys.stdout) handler.terminator = '' handler.setFormatter(MyFormatter(fmt)) logging.root.addHandler(handler) if utils.args.print_cmdline: utils.logger.always_print(' '.join([sys.executable] + sys.argv)) utils.logger.info('Running mypyvy with the following options:') for k, v in sorted(vars(utils.args).items()): utils.logger.info(f' {k} = {v!r}') utils.logger.info('setting seed to %d' % utils.args.seed) z3.set_param('smt.random_seed', utils.args.seed) z3.set_param('sat.random_seed', utils.args.seed) # utils.logger.info('enable z3 macro finder') # z3.set_param('smt.macro_finder', True) if utils.args.timeout is not None: utils.logger.info('setting z3 timeout to %s' % utils.args.timeout) z3.set_param('timeout', utils.args.timeout) pre_parse_error_count = utils.error_count with open(utils.args.filename) as f: prog = parse_program(f.read(), forbid_rebuild=utils.args.forbid_parser_rebuild, filename=utils.args.filename) if utils.error_count > pre_parse_error_count: utils.logger.always_print('program has syntax errors.') utils.exit(1) if utils.args.print_program is not None: if utils.args.print_program == 'str': to_str: Callable[[Program], str] = str end = '\n' elif utils.args.print_program == 'repr': to_str = repr end = '\n' elif utils.args.print_program == 'faithful': to_str = syntax.faithful_print_prog end = '' elif utils.args.print_program == 'without-invariants': def p(prog: Program) -> str: return syntax.faithful_print_prog(prog, skip_invariants=True) to_str = p end = '' else: assert False utils.logger.always_print(to_str(prog), end=end) pre_typecheck_error_count = utils.error_count typechecker.typecheck_program(prog) if utils.error_count > pre_typecheck_error_count: utils.logger.always_print('program has resolution errors.') utils.exit(1) syntax.the_program = prog s = Solver(use_cvc4=utils.args.cvc4) utils.args.main(s) if utils.args.ipython: ipython(s) utils.exit(1 if utils.error_count > 0 else 0)
def solve(self, goal, lemmas=None): """ Primary function of the NPSolver class. Attempts to prove the goal with respect to given lemmas and the theory defined by the AnnotatedContext in self.annctx. :param goal: z3.BoolRef :param lemmas: set of z3.BoolRef :return: NPSolution """ z3.set_param('smt.random_seed', 0) z3.set_param('sat.random_seed', 0) # TODO: check that the given lemmas are legitimate bound formula instances with their formal parameters from # the foreground sort. options = self.options # Make recursive definition unfoldings recdefs = get_recursive_definition(None, alldefs=True, annctx=self.annctx) recdef_unfoldings = make_recdef_unfoldings(recdefs) # Sometimes we don't need the unfoldings indexed by recdefs untagged_unfoldings = set(recdef_unfoldings.values()) # Add them to the set of axioms and lemmas to instantiate axioms = get_all_axioms(self.annctx) if lemmas is None: lemmas = set() else: # Check that each bound parameter in all the lemmas are of the foreground sort for lemma in lemmas: bound_vars, lemma_body = lemma if not all( is_expr_fg_sort(bound_var, annctx=self.annctx) for bound_var in bound_vars): raise TypeError( 'Bound variables of lemma: {} must be of the foreground sort' .format(lemma_body)) recdef_indexed_lemmas = _sort_by_trigger( lemmas, list(recdef_unfoldings.keys())) if options.instantiation_mode == proveroptions.lean_instantiation_with_lemmas: # Recdefs and lemmas need to be treated separately using 'lean' instantiation fo_abstractions = axioms if options.instantiation_mode == proveroptions.lean_instantiation: # Recdefs need to be treated separately using 'lean' instantiation fo_abstractions = axioms | lemmas else: # If the instantiation isn't the 'lean' kind then all defs are going to be instantiated with all terms fo_abstractions = axioms | untagged_unfoldings | lemmas # All parameters have been set appropriately. Begin constructing instantiations # Negate the goal neg_goal = z3.Not(goal) # Create a solver object and add the goal negation to it z3solver = z3.Solver() z3solver.add(neg_goal) # Keep track of terms in the quantifier-free problem given to the solver initial_terms = get_foreground_terms(neg_goal, annctx=self.annctx) extraction_terms = initial_terms recdef_application_terms = get_recdef_applications(neg_goal, annctx=self.annctx) instantiation_terms = set() # Instantiate and check for provability according to options # Handle manual instantiation mode first if options.instantiation_mode == proveroptions.manual_instantiation: terms_to_instantiate = options.terms_to_instantiate instantiations = instantiate(fo_abstractions, terms_to_instantiate) if instantiations != set(): instantiation_terms = terms_to_instantiate extraction_terms = extraction_terms.union( get_foreground_terms(instantiations, annctx=self.annctx)) z3solver.add(instantiations) if_sat = _solver_check(z3solver) model = z3solver.model() if if_sat else None return NPSolution(if_sat=if_sat, model=model, extraction_terms=extraction_terms, instantiation_terms=instantiation_terms, options=options) # Automatic instantiation modes # stratified instantiation strategy if options.instantiation_mode == proveroptions.depth_one_stratified_instantiation: conservative_fo_abstractions = axioms | untagged_unfoldings tracked_instantiations = instantiate(conservative_fo_abstractions, initial_terms) if tracked_instantiations != set(): instantiation_terms = initial_terms tracked_terms = get_foreground_terms(tracked_instantiations, annctx=self.annctx) extraction_terms = extraction_terms.union(tracked_terms) z3solver.add(tracked_instantiations) untracked_instantiations = instantiate(lemmas, extraction_terms) if untracked_instantiations != set(): instantiation_terms = instantiation_terms.union( extraction_terms) untracked_terms = get_foreground_terms( untracked_instantiations, annctx=self.annctx) extraction_terms = extraction_terms.union(untracked_terms) other_instantiations = instantiate(conservative_fo_abstractions, extraction_terms) z3solver.add(untracked_instantiations) z3solver.add(other_instantiations) if_sat = _solver_check(z3solver) model = z3solver.model() if if_sat else None return NPSolution(if_sat=if_sat, model=model, extraction_terms=extraction_terms, instantiation_terms=instantiation_terms, options=options) # Set up initial values of variables depth_counter = 0 # Keep track of formulae produced by instantiation instantiations = set() # When the instantiation mode is infinite we realistically can't exceed 10^3 instantiations anyway target_depth = 1000 if options.instantiation_mode == proveroptions.infinite_depth else options.depth while depth_counter < target_depth: # Try to prove with available instantiations z3solver.add(instantiations) # If the instantiation mode is fixed depth we can continue instantiating until we get to that depth if options.instantiation_mode != proveroptions.fixed_depth: # Otherwise check satisfiability with current state of instantiations if_sat = _solver_check(z3solver) # If unsat, stop and return NPSolution instance if not if_sat: return NPSolution(if_sat=if_sat, model=None, extraction_terms=extraction_terms, instantiation_terms=instantiation_terms, depth=depth_counter, options=options) # target depth not reached or unsat not reached # Do another round of instantiations. # TODO: optimise instantiations so repeated instantiation is not done. Currently all instantiations # are done in every round. But optimisation is difficult in the presence of multiple arities. instantiation_terms = extraction_terms # Instantiate all basic abstractions instantiations = instantiate(fo_abstractions, instantiation_terms) # Instantiate other abstractions depending on instantiation mode. Typically recdefs and lemmas if options.instantiation_mode in { proveroptions.lean_instantiation, proveroptions.lean_instantiation_with_lemmas }: # Add recursive definition instantiations to the set of all instantiations for recdef, application_terms in recdef_application_terms.items( ): lean_instantiations = instantiate( recdef_unfoldings[recdef], application_terms) instantiations.update(lean_instantiations) if options.instantiation_mode == proveroptions.lean_instantiation_with_lemmas: # Add lemma instantiations to the set of all instantiations for recdef, application_terms in recdef_application_terms.items( ): triggered_lemmas = recdef_indexed_lemmas.get(recdef, []) triggered_instantiations = instantiate( triggered_lemmas, application_terms) instantiations.update(triggered_instantiations) # If the set of instantiations is empty exit the loop if instantiations == set(): instantiation_terms = set() break # Update the variables for the next round depth_counter = depth_counter + 1 new_terms = get_foreground_terms(instantiations, annctx=self.annctx) recdef_application_terms = get_recdef_applications( instantiations, annctx=self.annctx) extraction_terms = extraction_terms.union(new_terms) # Reach this case when depth_counter = target depth, either in fixed_depth or bounded_depth mode. # Final attempt at proving goal z3solver.add(instantiations) if_sat = _solver_check(z3solver) model = z3solver.model() if if_sat else None return NPSolution(if_sat=if_sat, model=model, extraction_terms=extraction_terms, instantiation_terms=instantiation_terms, depth=depth_counter, options=options)
def run_test(adj, fab_dims, wire_lengths={}, debug_prints=True, constraints_gen=place_constraints_2d, model_checker=None, model_printer=print_model_2d): comps = build_graph(adj) if wire_lengths: #use provided wire lengths print('Finding satisfying model with given wire lenths') constraints = constraints_gen(comps, fab_dims, wire_lengths) s = z3.Solver() z3.set_param(timeout=120000) #not working s.add(constraints) limit = 5 #don't let it try forever counter = 0 while s.check() != z3.sat and counter < limit: print('test is unsat') s.reset() wire_lengths.update({max(wire_lengths) + 1, max(wire_lengths) + 2}) print('Resetting with wire_lengths = ', wire_lengths) s.add(constraints_gen(comps, fab_dims, wire_lengths)) counter += 1 if counter < limit: model_printer(s.model(), comps, fab_dims, wire_lengths) return (comps, s.model()) if debug_prints: print('test is sat') if debug_prints and all( model_checker(s.model(), comps, fab_dims, wire_lengths)): model_printer(s.model(), comps, fab_dims, wire_lengths) return (True, s) elif debug_prints: return (False, s) elif all( model_checker(s.model(), comps, fab_dims, wire_lengths, printer=lambda *x: None)): return (True, s) else: return (False, s) else: #no provided wire lengths, optimize the manhattan distance print('No provided wire lengths. Minimizing total L1 norm') constraints, manhattan_dist = place_constraints_opt(comps, fab_dims) s = z3.Optimize() s.add(constraints) h = s.minimize(manhattan_dist) if s.check() != z3.sat: if debug_prints: print('test is unsat') return s if debug_prints: print('test is sat') print('Total L1 Norm = ', s.lower(h)) #print(s.model()) print_model_opt(s.model(), comps, fab_dims) return s
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
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # from __future__ import absolute_import from pysmt.exceptions import SolverAPINotFound try: import z3 except ImportError: raise SolverAPINotFound # Keep array models expressed as values instead of Lambdas # (see https://github.com/Z3Prover/z3/issues/1769) z3.set_param('model_compress', False) from six.moves import xrange import pysmt.typing as types import pysmt.operators as op from pysmt.solvers.solver import (IncrementalTrackingSolver, UnsatCoreSolver, Model, Converter, SolverOptions) from pysmt.solvers.smtlib import SmtLibBasicSolver, SmtLibIgnoreMixin from pysmt.solvers.qelim import QuantifierEliminator from pysmt.walkers import DagWalker from pysmt.exceptions import (SolverReturnedUnknownResultError, SolverNotConfiguredForUnsatCoresError, SolverStatusError, ConvertExpressionError, UndefinedSymbolError, PysmtValueError)
#!/usr/bin/env python3 import z3 from z3 import * import sys import random z3._main_ctx = None z3.main_ctx() z3.set_param('smt.random_seed', random.SystemRandom().randint(0, sys.maxsize)) a = z3.Int('a') b = z3.Int('b') c = z3.Int('c') f = z3.Function('f', IntSort(), IntSort()) s = z3.Solver() # s.add(ForAll([a, b], (c == f(a+b)) == (c == a+f(b)) == (c == f(a)+b))) s.add(ForAll([a, b], f(a + b) == a + f(b))) x = z3.Int('x') y = z3.Int('y') s.add(f(x + y) != x + f(y)) print(s.check())
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # from __future__ import absolute_import from pysmt.exceptions import SolverAPINotFound try: import z3 except ImportError: raise SolverAPINotFound # Keep array models expressed as values instead of Lambdas # (see https://github.com/Z3Prover/z3/issues/1769) z3.set_param('model_compress', False) from six.moves import xrange import pysmt.typing as types import pysmt.operators as op from pysmt.solvers.solver import (IncrementalTrackingSolver, UnsatCoreSolver, Model, Converter, SolverOptions) from pysmt.solvers.smtlib import SmtLibBasicSolver, SmtLibIgnoreMixin from pysmt.solvers.qelim import QuantifierEliminator from pysmt.walkers import DagWalker from pysmt.exceptions import (SolverReturnedUnknownResultError, SolverNotConfiguredForUnsatCoresError, SolverStatusError,
def ResetZ3(): z3._main_ctx = None z3.main_ctx() z3.set_param('smt.random_seed', random.SystemRandom().randint(0, sys.maxint))
from time import time import z3 from .base_types import BasePoint2D, BaseSegment z3.set_param('model.completion', True) def _is_IntVal(val): return val.__class__.__name__ == 'IntVal' class SolverWrapper: def __init__(self): self._sol = None self.fresh_solver() def fresh_solver(self, tactic='default'): if isinstance(tactic, str): tactic = z3.Tactic(tactic) self._sol = tactic.solver() def add(self, *args): self._sol.add(*args) def eval(self, arg): """ Smart evaluator, if base type is passed returns as is, if z3 sort - evaluates, if aggregate object - invokes .eval method """ if isinstance(arg, int): return arg
def ResetZ3 (): z3._main_ctx = None z3.main_ctx() z3.set_param('auto_config', False) z3.set_param('smt.mbqi', True) z3.set_param('model.compact', True) z3.set_param('smt.pull_nested_quantifiers', True) z3.set_param('smt.mbqi.max_iterations', 10000) z3.set_param('smt.random_seed', random.SystemRandom().randint(0, sys.maxint))
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
def ResetZ3 (): z3._main_ctx = None z3.main_ctx() z3.set_param('smt.random_seed', random.SystemRandom().randint(0, sys.maxint)) z3.set_param('smt.mbqi.max_iterations', 10000) z3.set_param('smt.mbqi.max_cexs', 100)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from z3 import Solver, Int, set_param, sat from attacks.abstract_attack import AbstractAttack from lib.rsalibnum import isqrt, next_prime from lib.utils import timeout, TimeoutError from lib.keys_wrapper import PrivateKey set_param('parallel.enable', True) class Attack(AbstractAttack): def __init__(self, timeout=60): super().__init__(timeout) self.speed = AbstractAttack.speed_enum["medium"] 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()
offset is not 0, then the value of any foreground term present in the finite model is its value as given by the smt model, plus the offset. --- fg_universe: the set of all foreground elements present in the finite model. - Logging attributes -- extraction_terms: the terms used for finite model extraction at the time of creation. - Caching attributes -- recompute_offset: whether the model is already offset from the true values in the smt model, or if future offset computations must add to the current offset. Used for 'caching' offset models without needing further offsets unless explicitly specified. Set to 'True' by default, so all offset computations will have an effect. """ import itertools import copy import z3 # model.compact should be turned off to not get lambdas, only actual arrays/sets. z3.set_param('model.compact', False) from naturalproofs.AnnotatedContext import default_annctx from naturalproofs.uct import fgsort, fgsetsort, intsort, intsetsort, boolsort from naturalproofs.decl_api import get_vocabulary, get_uct_signature from naturalproofs.prover_utils import get_foreground_terms from naturalproofs.extensions.finitemodel_utils import transform_fg_universe, collect_fg_universe class FiniteModel: def __init__(self, smtmodel, terms, vocabulary=None, annctx=default_annctx): """
optimizer.assert_exprs(x < 2) #(assert (< x 2)) optimizer.assert_exprs((y - x) > 1) #(assert (> (- y x) 1)) my_max = optimizer.maximize(x + y) #(maximize (+ x y)) my_min = optimizer.minimize(x + y) #optimizer.set("priority", "box") optimizer.check() #(check-sat) print(optimizer.lower(my_min)) print(optimizer.lower(my_max)) print(optimizer.upper(my_min)) print(optimizer.upper(my_max)) print(optimizer.model()) #print(optimizer.statistics()) # In[5]: z3.set_param(verbose=10) optimizer = z3.Optimize() x = z3.Int('x') #(declare-const x Int) y = z3.Int('y') #(declare-const y Int) optimizer.assert_exprs(x < 4) #(assert (< x 4)) optimizer.assert_exprs((y - x) < 1) #(assert (< (- y x) 1)) optimizer.assert_exprs(y < 1) #(assert (< y 1)) optimizer.assert_exprs(y > -10) # In[6]: my_min = optimizer.minimize(x + y) #(minimize (+ x y)) # In[7]: optimizer.check() #(check-sat)
def ResetZ3 (seed): z3._main_ctx = None z3.main_ctx() z3.set_param('smt.random_seed', seed)
import z3 from .r2api import R2API from .esilclasses import * from .esilstate import ESILState, ESILStateManager from .esilsim import ESILSim from time import time z3.set_param('rewriter.hi_fp_unspecified', 'true') class ESILSolver: """ Manage and run symbolic execution of a binary using ESIL :param filename: The path to the target binary :param debug: Print every executed instruction and constraint info :param trace: Trace the execution and emulate with r2's ESIL VM :param optimize: Use z3 Optimizer instead of Solver (slow) :param lazy: Use lazy solving, don't evaluate path satisfiability :param simple: Use simple solver, often faster (default is True) :param pcode: Generate ESIL expressions from PCODE using r2ghidra :param check: Check memory permissions (default is False) >>> esilsolver = ESILSolver("/bin/ls", lazy=True) """ def __init__(self, filename:str = None, **kwargs): self.kwargs = kwargs self.debug = kwargs.get("debug", False) self.trace = kwargs.get("trace", False) self.lazy = kwargs.get("lazy", False) self.pcode = kwargs.get("pcode", False)