def test_consts(): ''' Check that there are no errors creating constants Instantiate two identical constants and check that they're not equal expecting unsat of course. Also checking that there are no unhandled cases or exceptions. ''' for name in bv_solvers: s = smt(name) s.SetLogic('QF_BV') a = s.TheoryConst(s.BitVec(4), 5) b = s.TheoryConst(s.BitVec(4), 5) s.Assert(a != b) assert not s.CheckSat(), "Expected unsat for simple constant test. Solver={}".format(name) consts = [(s.Int, 2), (s.Real, 4.5)] for name, t in itertools.product(all_logic_solvers, consts): s = smt(name) sort, const = t a = s.TheoryConst(sort(), const) b = s.TheoryConst(sort(), const) s.Assert(a != b) assert not s.CheckSat(), "Expected unsat for simple constant test. Solver={}".format(name)
def test_unsat_array(): ''' Simple example demonstrating array axiom ''' for name in all_logic_solvers: s = smt(name) s.SetLogic('QF_ABV') bvsort8 = s.ConstructSort(s.BitVec, 8) bvsort4 = s.ConstructSort(s.BitVec, 4) arrsort = s.ConstructSort(s.Array, bvsort8, bvsort4) A = s.DeclareConst('A', arrsort) bvidx = s.DeclareConst("bvidx", bvsort8) bv_d1 = s.DeclareConst("bv_d1", bvsort4) bv_d2 = s.DeclareConst("bv_d2", bvsort4) newA = s.ApplyFun(s.Store, A, bvidx, bv_d1) s.Assert(s.ApplyFun(s.Not, s.ApplyFun(s.Equals, bv_d1, bv_d2))) bvatidx = s.ApplyFun(s.Select, newA, bvidx) s.Assert(s.ApplyFun(s.Equals, bvatidx, bv_d2)) assert not s.CheckSat()
def test_definefun(): # z3 does not support function macros through api for name in ["CVC4", "Boolector"]: s = smt(name) s.SetLogic("QF_BV") s.SetOption("produce-models", "true") bv1s = s.Symbol("bv1s", s.BitVec(4)) bv2s = s.Symbol("bv2s", s.BitVec(4)) f = s.DefineFun("f", [bv1s, bv2s], bv1s + bv2s) bv1 = s.DeclareConst("bv1", s.BitVec(4)) bv2 = s.DeclareConst("bv2", s.BitVec(4)) bv3 = s.DeclareConst("bv3", s.BitVec(4)) s.Assert(bv1 == 4) s.Assert(f(bv1, bv2) == bv3) assert s.CheckSat() bv1v = s.GetValue(bv1).as_int() bv2v = s.GetValue(bv2).as_int() bv3v = s.GetValue(bv3).as_int() assert bv3v == bv1v + bv2v
def test_sat_array(): ''' Simple array test ''' for name in all_logic_solvers: s = smt(name) s.SetLogic('QF_ABV') s.SetOption("produce-models", 'true') bvsort8 = s.ConstructSort(s.BitVec, 8) bvsort4 = s.ConstructSort(s.BitVec, 4) arrsort = s.ConstructSort(s.Array, bvsort8, bvsort4) A = s.DeclareConst('A', arrsort) bvidx = s.DeclareConst("bvidx", bvsort8) bvidx2 = s.DeclareConst("bvidx2", bvsort8) bv_d1 = s.DeclareConst("bv_d1", bvsort4) bv_d2 = s.DeclareConst("bv_d2", bvsort4) A1 = s.ApplyFun(s.Store, A, bvidx, bv_d1) A2 = s.ApplyFun(s.Store, A1, bvidx2, bv_d2) bvidxp2 = s.ApplyFun(s.BVAdd, bvidx, s.TheoryConst(bvsort8, 2)) s.Assert(s.ApplyFun(s.Equals, bvidx2, bvidxp2)) bv_d2sh1 = s.ApplyFun(s.BVLshr, bv_d2, s.TheoryConst(bvsort4, 1)) s.Assert(s.ApplyFun(s.Equals, bv_d1, bv_d2sh1)) s.CheckSat() av = s.GetValue(A2).as_list() # returns list of tuples
def test_uf(): ''' Simple check demonstrating an axiom of uninterpreted function (set-option :produce-models true) (set-logic QF_UF) (declare-fun a () Bool) (declare-fun b () Bool) (declare-fun c () Bool) (declare-fun f (Bool) Bool) (assert (= (f a) b)) (assert (= (f a) c)) (assert (not (= b c))) (check-sat) ''' for name in all_logic_solvers: s = smt(name) s.SetLogic('QF_UF') a = s.DeclareConst("a", s.Bool()) b = s.DeclareConst("b", s.Bool()) c = s.DeclareConst("c", s.Bool()) f = s.DeclareFun("f", [s.Bool()], s.Bool()) s.Assert(f(a) == b) s.Assert(f(a) == c) s.Assert(b != c) assert not s.CheckSat(), "Expecting unsat"
def relaxed_seq(solvers): print('Demonstrating the sequential code benchmark with relaxed setting') print('Expecting unsat') for n in solvers: s = smt(n) s.SetLogic('QF_BV') s.SetOption('produce-models', 'true') x_0 = s.DeclareConst('x_0', s.BitVec(32)) x_1 = s.DeclareConst('x_1', s.BitVec(32)) x_2 = s.DeclareConst('x_2', s.BitVec(32)) y_0 = s.DeclareConst('y_0', s.BitVec(32)) y_1 = s.DeclareConst('y_1', s.BitVec(32)) s.Assert(x_1 == x_0 + y_0) s.Assert(y_1 == x_1 - y_0) s.Assert(x_2 == x_1 - y_1) s.Assert(s.Not(s.And(x_2 == y_0, y_1 == x_0))) if s.CheckSat(): print('Relaxed sequential encoding with {} found sat'.format(n)) else: print('Relaxed sequential encoding with {} found unsat'.format(n)) assert not s.Sat, 'Expected unsat' print()
def test_r_ops(): for name in bv_solvers: s = smt(name) s.SetOption('produce-models', 'true') s.SetLogic('QF_BV') bvsort8 = s.BitVec(8) x1 = s.DeclareConst('x1', bvsort8) x2 = s.DeclareConst('x2', bvsort8) x3 = s.DeclareConst('x3', bvsort8)
def test_bv_boolops(): ''' Sets bv1 = 00001111 bv2 = 11110000 bv3 = 01010101 Then computes: bv1 and bv2 bv2 or bv3 not bv3 ''' for name in bv_solvers: s = smt(name) s.SetLogic('QF_BV') s.SetOption('produce-models', 'true') bvand = s.BVAnd bvor = s.BVOr bvnot = s.BVNot bvsort = s.BitVec(8) bv1 = s.DeclareConst('bv1', bvsort) bv2 = s.DeclareConst('bv2', bvsort) bv3 = s.DeclareConst('bv3', bvsort) bvresult = bvand(bv1, bv2) bvresult2 = bvor(bv2, bv3) bvnotresult = bvnot(bv3) assert bvresult2.sort == s.BitVec(8) if name != 'Boolector': # Boolector is streamlined/optimized and does not support querying opt assert bvresult2.op == bvor # Assert formulas s.Assert(bv1 == 15) s.Assert(bv2 == 240) s.Assert(bv3 == 85) # check satisfiability s.CheckSat() # now query for the values bvr1 = s.GetValue(bvresult) bvr2 = s.GetValue(bvresult2) bvnr = s.GetValue(bvnotresult) assert bvr1.as_int() == 0 assert bvr2.as_int() == 245 assert bvnr.as_int() == 170
def test_bv128(): for name in bv_solvers: s = smt(name) s.SetOption('produce-models', 'true') s.SetLogic('QF_BV') bv = s.DeclareConst('bv', s.BitVec(128)) import sys bignum = s.TheoryConst(s.BitVec(128), sys.maxsize) s.Assert(s.BVUgt(bv, bignum)) s.CheckSat() v = s.GetValue(bv) try: v.as_bitstr() except Exception: assert False, 'Issue representing bit vector of width 128'
def test_bv_extract(): ''' Simple bitvector example based on CVC4 extract.cpp example ''' for name in bv_solvers: s = smt(name, strict=True) # create bitvector type of width 32 bvsort = s.ConstructSort(s.BitVec, 32) s.SetLogic('QF_BV') x = s.DeclareConst('x', bvsort) ext_31_1 = s.ConstructFun(s.Extract, 31, 1) x_31_1 = s.ApplyFun(ext_31_1, x) ext_30_0 = s.ConstructFun(s.Extract, 30, 0) x_30_0 = s.ApplyFun(ext_30_0, x) ext_31_31 = s.ConstructFun(s.Extract, 31, 31) x_31_31 = s.ApplyFun(ext_31_31, x) ext_0_0 = s.ConstructFun(s.Extract, 0, 0) x_0_0 = s.ApplyFun(ext_0_0, x) assert x_31_1.sort == x_30_0.sort assert x_31_31.sort == x_0_0.sort assert x_31_1.sort == s.BitVec(31) eq = s.ApplyFun(s.Equals, x_31_1, x_30_0) if name != 'Boolector': # boolector does not keep string representation of formulas print('Asserting', eq) # Boolector is streamlined/optimized and does not keep track of op assert x_31_31.op == s.Extract(31, 31) s.Assert(eq) eq2 = s.ApplyFun(s.Equals, x_31_31, x_0_0) s.Assert(eq2) s.CheckSat() assert s.Sat # in fact it's actually valid
def test_bv_arithops(): ''' Set bv1 = 0001 bv2 = 0010 bv3 = 0101 Then compute: bv1 + bv2 bv2*bv3 bv3 >> 1 ''' for name in bv_solvers: s = smt(name) s.SetLogic('QF_BV') s.SetOption('produce-models', 'true') bvmul = s.BVMul bvsort = s.BitVec(4) bv1 = s.DeclareConst('bv1', bvsort) bv2 = s.DeclareConst('bv2', bvsort) bv3 = s.DeclareConst('bv3', bvsort) bvsum = bv1 + bv2 bvprod = bvmul(bv2, bv3) bvshifted = bv3 >> 1 # make Assertions s.Assert(bv1 == 1) s.Assert(bv2 == 2) s.Assert(bv3 == 5) # check satisfiability s.CheckSat() bvsumr = s.GetValue(bvsum) bvprodr = s.GetValue(bvprod) bvshiftedr = s.GetValue(bvshifted) # still figuring out how to get z3 and boolector to print s-lib format for results # assert bvsumr.__repr__() == '3' or bvsumr.__repr__() == '0bin0011' # assert bvprodr.__repr__() == '10' or bvprodr.__repr__() == '0bin1010' # assert bvshiftedr.as_int() == 2 assert bvsumr.as_int() == 3 assert bvprodr.as_int() == 10 assert bvshiftedr.as_int() == 2
def strict_seq(solvers): print('Demonstrating the sequential code benchmark with strict setting') print('Expecting unsat') for n in solvers: # initialize an smt object with the name of the solver # This is the api that you interact with s = smt(n, strict=True) s.SetLogic('QF_BV') s.SetOption('produce-models', 'true') bvsort32 = s.ConstructSort(s.BitVec, 32) x_0 = s.DeclareConst('x_0', bvsort32) x_1 = s.DeclareConst('x_1', bvsort32) x_2 = s.DeclareConst('x_2', bvsort32) y_0 = s.DeclareConst('y_0', bvsort32) y_1 = s.DeclareConst('y_1', bvsort32) s.Assert(s.ApplyFun(s.Equals, x_1, s.ApplyFun(s.BVAdd, x_0, y_0))) s.Assert(s.ApplyFun(s.Equals, y_1, s.ApplyFun(s.BVSub, x_1, y_0))) s.Assert(s.ApplyFun(s.Equals, x_2, s.ApplyFun(s.BVSub, x_1, y_1))) x2eqy0 = s.ApplyFun(s.Equals, x_2, y_0) y1eqx0 = s.ApplyFun(s.Equals, y_1, x_0) assert y1eqx0.sort == s.Bool() or \ n == 'Boolector' and y1eqx0.sort == s.BitVec(1) # boolector does not distinguish between bool and BV(1) s.Assert(s.ApplyFun(s.Not, s.ApplyFun(s.And, x2eqy0, y1eqx0))) if s.CheckSat(): print('Strict sequential encoding with {} found sat'.format(n)) else: print('Strict sequential encoding with {} found unsat'.format(n)) assert not s.Sat, 'Expected unsat' print()
def __init__(self, fabric, design, solver_str, seed=1): self._fabric = fabric self._design = design self._place_state = BiDict() self._route_state = BiMultiDict() self._place_vars = dict() self._route_vars = BiDict() self._smt_solver = True if solver_str in ilp_solvers: self._place_solver = ilp_solvers[solver_str]() self._smt_solver = False else: self._place_solver = smt(solver_str) # set options self._place_solver.SetOption('produce-models', 'true') self._place_solver.SetLogic('QF_UFBV') self._place_solver.SetOption('random-seed', seed) # use best settings per solver if solver_str == 'CVC4': self._place_solver.SetOption('bitblast', 'eager') self._place_solver.SetOption('bv-sat-solver', 'cryptominisat') self._route_solver = Solver_monosat() self._route_solver.set_option('random-seed', seed) # set up region self._region = fabric.region for module in design.modules: r = self._region.make_subregion(module.name) # kinda hackish need to make rules dictionary # so r.sizes can be safely mutated directly r.set_size({d: 0 for d in r.size}) r.set_position({d: SYMBOLIC for d in r.position}) r.set_category({d: SYMBOLIC for d in r.category}) self._place_state[module] = r
def test_bv_extract(): ''' Simple bitvector example based on CVC4 extract.cpp example ''' for name in bv_solvers: s = smt(name) s.SetLogic('QF_BV') # create bitvector type of width 32 bvsort = s.ConstructSort(s.BitVec, 32) x = s.DeclareConst('x', bvsort) ext_31_1 = s.ConstructFun(s.Extract, 31, 1) x_31_1 = ext_31_1(x) x_31_31 = s.Extract(31, 31, x) # You can also use slicing notation x_30_0 = x[30:0] # or if you just want one bit, use it as an index x_0_0 = x[0] assert x_31_1.sort == x_30_0.sort assert x_31_31.sort == x_0_0.sort if name != 'Boolector': # Boolector is streamlined/optimized and does not keep track of op assert x_31_1.op == s.Extract(31, 1) assert x_31_1.sort == s.BitVec(31) print('Asserting x_31_1 == x_30_0') s.Assert(x_31_1 == x_30_0) eq2 = x_31_31 == x_0_0 s.Assert(eq2) s.CheckSat() assert s.Sat # in fact it's actually valid
def test_bv_multdivide(): ''' Simple bitvector example with multiply and divide operators ''' for name in bv_solvers: print(name) s = smt(name) s.SetLogic("QF_BV") s.SetOption("produce-models", 'true') x = s.DeclareConst('x', s.BitVec(16)) y = s.DeclareConst('y', s.BitVec(16)) s.Assert(3 * x + y == 16) s.Assert(y / 5 == 2) s.Assert(y % 8 == 2) s.CheckSat() assert s.GetValue(x).as_int() == 2 assert s.GetValue(y).as_int() == 10
def test_incremental(): ''' Simple example demonstrating incremental mode ''' for name in bv_solvers: s = smt(name) s.SetLogic('QF_BV') s.SetOption('incremental', 'true') b1 = s.DeclareConst("b1", s.BitVec(4)) b2 = s.DeclareConst("b2", s.BitVec(4)) s.Assert(s.BVUlt(b1, b2)) assert s.CheckSat(), 'Expecting satisfiable' s.Assert(s.BVUlt(b2, b1)) assert not s.CheckSat(), 'Expecting unsat'
def test_bv_ops(): ''' bitvector example using overloaded operators ''' for name in bv_solvers: s = smt(name) s.SetLogic('QF_BV') s.SetOption('produce-models', 'true') bvuge = s.BVUge And = s.And bv8 = s.BitVec(8) bv1 = s.DeclareConst('bv1', bv8) bv2 = s.DeclareConst('bv2', s.BitVec(8)) c = [bvuge(bv1, 1)] bvs = [bv1, bv2] for i in range(3, 11): bvs.append(s.DeclareConst('bv{}'.format(i), bv8)) for b1, b2, b3 in zip(bvs, bvs[1:], bvs[2:]): c.append(b1 + b2 == b3) s.Assert(And(c)) s.Assert(((bvs[9] << 4) >> 4) == bvs[6]) s.Assert(bvs[5] == 3) s.Assert(bvs[8] - 6 == 7) r = s.CheckSat() assert r bvvals = [s.GetValue(bv).as_int() for bv in bvs] for b1, b2, b3 in zip(bvvals, bvvals[1:], bvvals[2:]): assert b1 + b2 == b3
def test_distinct(): # Currently only implemented in Z3 and CVC4 for n in ["CVC4", "Z3"]: s = smt(n) s.SetOption('produce-models', 'true') s.SetLogic('QF_BV') bvsort8 = s.BitVec(8) x1 = s.DeclareConst('x1', bvsort8) x2 = s.DeclareConst('x2', bvsort8) x3 = s.DeclareConst('x3', bvsort8) s.Assert(s.Distinct([x1, x2, x3])) assert s.CheckSat() x1val = s.GetValue(x1).as_int() x2val = s.GetValue(x2).as_int() x3val = s.GetValue(x3).as_int() assert x1val != x2val and x1val != x3val and x2val != x3val
def __init__( self, cgra: MRRG, design: Design, solver_str: str, seed: int = 0, incremental: bool = False, duplicate_const: bool = False, duplicate_all: bool = False, ): if duplicate_all: for op in design.operations: op.allow_duplicate() elif duplicate_const: for op in design.operations: if op.opcode == 'const': op.allow_duplicate() self._cgra = cgra self._design = design self._incremental = incremental self._solver = solver = smt(solver_str) self._solver_opts = solver_opts = [('random-seed', seed), ('produce-models', 'true')] if incremental: solver_opts.append(('incremental', 'true')) if solver_str == 'CVC4': if incremental: solver_opts.append(('bv-sat-solver', 'cryptominisat')) else: solver_opts.append(('bv-sat-solver', 'cadical')) #solver_opts.append(('bitblast', 'eager')) self._init_solver() self._vars = Modeler(solver) self._model = None
def test_uf(): ''' Simple check demonstrating an axiom of uninterpreted function (set-option :produce-models true) (set-logic QF_UF) (declare-fun a () Bool) (declare-fun b () Bool) (declare-fun c () Bool) (declare-fun f (Bool) Bool) (assert (= (f a) b)) (assert (= (f a) c)) (assert (not (= b c))) (check-sat) ''' for name in all_logic_solvers: s = smt(name, strict=True) s.SetLogic('QF_UF') a = s.DeclareFun("a", [], s.Bool()) # you can also use the shortcut DeclareConst for zero-arity functions b = s.DeclareConst("b", s.Bool()) c = s.DeclareConst("c", s.Bool()) f = s.DeclareFun("f", [s.Bool()], s.Bool()) s.Assert(s.ApplyFun(s.Equals, s.ApplyFun(f, a), b)) s.Assert(s.ApplyFun(s.Equals, s.ApplyFun(f, a), c)) s.Assert(s.ApplyFun(s.Not, s.ApplyFun(s.Equals, b, c))) assert not s.CheckSat(), "Expecting unsat"
def test_pushpop(): ''' Same simple example but with push and pop ''' for name in all_logic_solvers: s = smt(name) s.SetLogic('QF_BV') s.SetOption('incremental', 'true') b1 = s.DeclareConst("b1", s.BitVec(4)) b2 = s.DeclareConst("b2", s.BitVec(4)) s.Assert(s.BVUlt(b1, b2)) assert s.CheckSat(), 'Expecting satisfiable' s.Push() s.Assert(s.BVUlt(b2, b1)) assert not s.CheckSat(), 'Expecting unsat' s.Pop() assert s.CheckSat(), 'Expecting sat again'
def strict_example(solvers): print('Demonstrating a more complex example in strict mode\n') for n in solvers: print('Solving with {}'.format(n)) s = smt(n, strict=True) s.SetLogic('QF_BV') s.SetOption('produce-models', 'true') bv_list = [] # declare a BitVec sort of width 8 bvsort8 = s.ConstructSort(s.BitVec, 8) # declare a BitVec sort of width 4 bvsort4 = s.ConstructSort(s.BitVec, 4) # declare an extract function ext3_0 = s.ConstructFun(s.Extract, 3, 0) ext7_4 = s.ConstructFun(s.Extract, 7, 4) for i in range(10): bv_list.append(s.DeclareConst('bv{}'.format(i), bvsort8)) for b1, b2 in zip(bv_list[:4], bv_list[1:]): b1_7_4 = s.ApplyFun(ext7_4, b1) b2_3_0 = s.ApplyFun(ext3_0, b2) b17_4eqb23_0 = s.ApplyFun(s.Equals, b1_7_4, b2_3_0) s.Assert(b17_4eqb23_0) for b1, b2 in zip(bv_list[4:], bv_list[5:]): b1_3_0 = s.ApplyFun(ext3_0, b1) # you can query the sort of terms assert b1_3_0.sort == s.BitVec(4) b1_3_0lshift1 = s.ApplyFun(s.BVShl, b1_3_0, s.TheoryConst(bvsort4, 1)) b2_7_4 = s.ApplyFun(ext7_4, b2) s.Assert(s.ApplyFun(s.Equals, b1_3_0lshift1, b2_7_4)) bv9plus1 = s.ApplyFun(s.BVAdd, bv_list[9], s.TheoryConst(bvsort8, 1)) s.Assert(s.ApplyFun(s.Equals, bv9plus1, s.TheoryConst(bvsort8, 1))) bv8minusbv5 = s.ApplyFun(s.BVSub, bv_list[8], bv_list[5]) bv8minusbv5ashr = s.ApplyFun(s.BVAshr, bv8minusbv5, s.TheoryConst(bvsort8, 2)) s.Assert( s.ApplyFun(s.Equals, bv8minusbv5ashr, s.TheoryConst(bvsort8, 4))) bv3andbv2 = s.ApplyFun(s.BVAnd, bv_list[3], bv_list[2]) s.Assert(s.ApplyFun(s.BVUge, bv3andbv2, s.TheoryConst(bvsort8, 7))) bv7orbv8 = s.ApplyFun(s.BVOr, bv_list[7], bv_list[8]) s.Assert(s.ApplyFun(s.BVUgt, bv7orbv8, s.TheoryConst(bvsort8, 8))) if s.CheckSat(): for i in range(10): # get value returns a term with the value assigned val = s.GetValue(bv_list[i]) print('bv{}: 0b{}'.format(i, val.as_bitstr()), val.as_int()) print('Show that extract constraints are satisfied') for b1, b2 in zip(bv_list[:4], bv_list[1:]): val1 = s.GetValue(s.Extract(7, 4, b1)) val2 = s.GetValue(ext3_0(b2)) if n != 'Boolector': print(val1.op, b1, '= 0b{}'.format(val1.as_bitstr()) + ',', val2.op, b2, '= 0b{}'.format(val2.as_bitstr())) else: print(b1, '= 0b{}'.format(val1.as_bitstr()) + ',', b2, '= 0b{}'.format(val2.as_bitstr())) print()
def test_bv_boolops(): ''' Sets bv1 = 00001111 bv2 = 11110000 bv3 = 01010101 Then computes: bv1 and bv2 bv2 or bv3 not bv3 ''' for name in bv_solvers: s = smt(name, strict=True) bvand = s.BVAnd bvor = s.BVOr bvnot = s.BVNot Equals = s.Equals bvsort = s.BitVec(8) s.SetLogic('QF_BV') s.SetOption('produce-models', 'true') bv1 = s.DeclareConst('bv1', bvsort) bv2 = s.DeclareConst('bv2', bvsort) bv3 = s.DeclareConst('bv3', bvsort) bvresult = s.DeclareConst('bvresult', bvsort) bvresult2 = s.DeclareConst('bvresult2', bvsort) bvnotresult = s.DeclareConst('bvnotresult', bvsort) bv1andbv2 = s.ApplyFun(bvand, bv1, bv2) bv2orbv3 = s.ApplyFun(bvor, bv2, bv3) notbv3 = s.ApplyFun(bvnot, bv3) assert bv2orbv3.sort == s.BitVec(8) if name != 'Boolector': assert bv2orbv3.op == bvor bvresulteq = s.ApplyFun(Equals, bvresult, bv1andbv2) bvresult2eq = s.ApplyFun(Equals, bvresult2, bv2orbv3) bvnotresulteq = s.ApplyFun(Equals, bvnotresult, notbv3) assert bvnotresulteq.sort == s.Bool( ) or bvnotresulteq.sort == s.BitVec(1) fifteen = s.TheoryConst(bvsort, 15) twoforty = s.TheoryConst(bvsort, 240) eightyfive = s.TheoryConst(bvsort, 85) bv1eq = s.ApplyFun(Equals, bv1, fifteen) bv2eq = s.ApplyFun(Equals, bv2, twoforty) bv3eq = s.ApplyFun(Equals, bv3, eightyfive) # Assert formulas s.Assert(bvresulteq) s.Assert(bvresult2eq) s.Assert(bvnotresulteq) s.Assert(bv1eq) s.Assert(bv2eq) s.Assert(bv3eq) # check satisfiability s.CheckSat() # now query for the values bvr1 = s.GetValue(bvresult) bvr2 = s.GetValue(bvresult2) bvnr = s.GetValue(bvnotresult) # make Assertions about values # still figuring out how to get z3 and boolector to print s-lib format for results # assert bvr1.__repr__() == '(_ bv0 8)' or bvr1.__repr__() == '#x00' # assert bvr2.__repr__() == '(_ bv245 8)' or bvr2.__repr__() == '#xf5' # assert bvnr.__repr__() == '(_ bv170 8)' or bvnr.__repr__() == '#xaa' assert bvr1.as_int() == 0 assert bvr2.as_int() == 245 assert bvnr.as_int() == 170
def test_bv_arithops(): ''' Set bv1 = 0001 bv2 = 0010 bv3 = 0101 Then compute: bv1 + bv2 bv2*bv3 bv3 >> 1 ''' for name in bv_solvers: s = smt(name, strict=True) bvadd = s.BVAdd bvmul = s.BVMul bvlshr = s.BVLshr Equals = s.Equals bvsort = s.BitVec(4) s.SetLogic('QF_BV') s.SetOption('produce-models', 'true') bv1 = s.DeclareConst('bv1', bvsort) bv2 = s.DeclareConst('bv2', bvsort) bv3 = s.DeclareConst('bv3', bvsort) one = s.TheoryConst(bvsort, 1) two = s.TheoryConst(bvsort, 2) five = s.TheoryConst(bvsort, 5) bv1eq = s.ApplyFun(Equals, bv1, one) bv2eq = s.ApplyFun(Equals, bv2, two) bv3eq = s.ApplyFun(Equals, bv3, five) bvsum = s.DeclareConst('bvsum', bvsort) bvprod = s.DeclareConst('bvprod', bvsort) bvshifted = s.DeclareConst('bvshifted', bvsort) bvsumval = s.ApplyFun(bvadd, bv1, bv2) bvprodval = s.ApplyFun(bvmul, bv2, bv3) bvshiftedval = s.ApplyFun(bvlshr, bv3, one) bvsumeq = s.ApplyFun(Equals, bvsum, bvsumval) bvprodeq = s.ApplyFun(Equals, bvprod, bvprodval) bvshiftedeq = s.ApplyFun(Equals, bvshifted, bvshiftedval) #make Assertions s.Assert(bv1eq) s.Assert(bv2eq) s.Assert(bv3eq) s.Assert(bvsumeq) s.Assert(bvprodeq) s.Assert(bvshiftedeq) # check satisfiability s.CheckSat() bvsumr = s.GetValue(bvsum) bvprodr = s.GetValue(bvprod) bvshiftedr = s.GetValue(bvshifted) # still figuring out how to get z3 and boolector to print s-lib format for results # assert bvsumr.__repr__() == '(_ bv3 4)' or bvsumr.__repr__() == '#x3' # assert bvprodr.__repr__() == '(_ bv10 4)' or bvprodr.__repr__() == '#xa' # assert bvshiftedr.as_int() == 2 assert bvsumr.as_int() == 3 assert bvprodr.as_int() == 10 assert bvshiftedr.as_int() == 2
def __init__(self, fabric, design, solver_str, seed=1): self._fabric = fabric self._design = design assert design.layers <= fabric.layers, \ "The layers in the design should be a subset of the layers available in the fabric." self._place_state = BiDict() self._route_state = BiMultiDict() self._place_vars = dict() self._route_vars = BiDict() self._smt_solver = True self._solver_str = solver_str if solver_str in ilp_solvers: self._place_solver = ilp_solvers[solver_str]() self._smt_solver = False else: self._place_solver = smt(solver_str) # set options self._place_solver.SetOption('produce-models', 'true') self._place_solver.SetLogic('QF_UFBV') self._place_solver.SetOption('random-seed', seed) # use best settings per solver if self._solver_str == 'CVC4': self._place_solver.SetOption('bitblast', 'eager') self._place_solver.SetOption('bv-sat-solver', 'cryptominisat') self._route_solver = Solver_monosat() self._route_solver.set_option('random-seed', seed) # set up region self._region = Region.from_frabic('CGRA', self.fabric) for module in design.modules: r = self._region.make_subregion(module.name) # kinda hackish need to make rules dictionary # so r.sizes can be safely mutated directly r.set_size({d: 0 for d in r.size}) r.set_position({d: SYMBOLIC for d in r.position}) for d in r.category: if d == fabric.layers_dim: r.set_category({d: module.layer.value}) elif module.resource == Resource.Reg and d == fabric.tracks_dim: r.set_category({d: SYMBOLIC}) elif module.resource == Resource.IO and d == fabric.io_groups_dim: r.set_category({d: SYMBOLIC}) else: r.set_category({d: None}) self._place_state[module] = r # Gather some info about the pnr problem # info is a named tuple with design info and fabric info # each of those are dicts with resource --> number self._info = namedtuple("info", "design fabric")(defaultdict(int), defaultdict(int)) for m in design.modules: self._info.design[m.resource] += 1 self._info.design["total modules"] += 1 self._info.design["total ties"] = len(design.ties) for res, locs in fabric.locations.items(): self._info.fabric[res] = len(locs) # check that there are enough resources in fabric to place design if self._info.fabric[res] < self._info.design[res]: raise RuntimeError( "There are not enough {}s in fabric to support the design". format(res.name))
def relaxed_example(solvers): print('Demonstrating a more complex example in relaxed mode\n') for n in solvers: print('Solving with {}'.format(n)) s = smt(n) s.SetLogic('QF_BV') s.SetOption('produce-models', 'true') bv_list = [] ext3_0 = s.Extract(3, 0) for i in range(10): bv_list.append(s.DeclareConst('bv{}'.format(i), s.BitVec(8))) for b1, b2 in zip(bv_list[:4], bv_list[1:]): # show slicing for bit vector extracts and callable functions s.Assert(b1[7:4] == ext3_0(b2)) for b1, b2 in zip(bv_list[4:], bv_list[5:]): # show calling Extract directly b1_3_0 = s.Extract(3, 0, b1) assert b1_3_0.sort == s.BitVec(4) s.Assert((b1_3_0 << 1) == s.Extract(7, 4, b2)) # demonstrate building up a list of constraints c = [] # Many common operators are overloaded c.append(bv_list[9] + 1 == 5) c.append((bv_list[8] - bv_list[5]) >> 2 == 4) # BV comparison operators are not yet overloaded # I was worried about it being unclear whether it is signed or unsigned # comparison c.append(s.BVUge(bv_list[3] & bv_list[2], 7)) c.append(s.BVUgt(bv_list[7] | bv_list[8], 8)) # can call Assert on a list of constraints # This is the same as looping through the list # and calling Assert on each element s.Assert(c) if s.CheckSat(): for i in range(10): val = s.GetValue(bv_list[i]) print('bv{}: 0b{}'.format(i, val.as_bitstr()), val.as_int()) print('Show that extract constraints are satisfied') for b1, b2 in zip(bv_list[:4], bv_list[1:]): val1 = s.GetValue(b1[7:4]) val2 = s.GetValue(ext3_0(b2)) if n != 'Boolector': print(val1.op, b1, '= 0b{}'.format(val1.as_bitstr()) + ',', val2.op, b2, '= 0b{}'.format(val2.as_bitstr())) else: print(b1, '= 0b{}'.format(val1.as_bitstr()) + ',', b2, '= 0b{}'.format(val2.as_bitstr())) print()