示例#1
0
 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)
示例#2
0
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)
示例#3
0
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)
示例#4
0
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())
示例#5
0
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))
示例#6
0
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
        }
示例#7
0
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
示例#8
0
    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
示例#9
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()
示例#10
0
文件: mypyvy.py 项目: aatxe/mypyvy
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)')
示例#11
0
    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()
示例#12
0
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)
示例#13
0
    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)
示例#14
0
#!/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"
示例#15
0
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
示例#16
0
def ResetZ3(seed):
    z3._main_ctx = None
    z3.main_ctx()
    z3.set_param('smt.random_seed', seed)
示例#17
0
文件: newsmt.py 项目: Cwickniss/OLSQ
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))

示例#18
0
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))
示例#19
0
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))
示例#20
0
def ResetZ3 ():
    z3._main_ctx = None
    z3.main_ctx()
    z3.set_param('smt.random_seed', random.SystemRandom().randint(0, sys.maxint))
示例#21
0
文件: 1 intro.py 项目: valeporti/imt
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())
示例#22
0
文件: mypyvy.py 项目: jrkoenig/mypyvy
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)
示例#23
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)
示例#24
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)
示例#25
0
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
示例#26
0
    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
示例#27
0
文件: z3.py 项目: alebugariu/pysmt
#   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)
示例#28
0
#!/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())
示例#29
0
文件: z3.py 项目: pysmt/pysmt
#   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,
示例#30
0
def ResetZ3():
    z3._main_ctx = None
    z3.main_ctx()
    z3.set_param('smt.random_seed',
                 random.SystemRandom().randint(0, sys.maxint))
示例#31
0
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
示例#32
0
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))
示例#33
0
    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
示例#34
0
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)
示例#35
0
#!/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()
示例#36
0
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):
        """
示例#37
0
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)
示例#38
0
def ResetZ3 (seed):
    z3._main_ctx = None
    z3.main_ctx()
    z3.set_param('smt.random_seed', seed)
示例#39
0
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)