def test_conversion_of_fractions_in_z3(self): self.assertValid(Equals(Real(Fraction(1,9)), Div(Real(1), Real(9))), solver_name="msat") self.assertValid(Equals(Real(Fraction(1,9)), Div(Real(1), Real(9))), solver_name="z3")
def __post_init__(self): w, h = self.w, self.h spacing = self.spacing factory = self.factory constraints = self.constraints grid = [[factory() for _ in range(w)] for _ in range(h)] # align rows and columns for row in grid: constraints.append(top_align(row)) for col in range(w): constraints.append(left_align(row[col] for row in grid)) # establish spacing between grid elements first_row = grid[0] first_col = [row[0] for row in grid] for a, b in zip(first_row, first_row[1:]): constraints.append(Equals(b.bounds.left_edge, a.bounds.right_edge + spacing)) for a, b in zip(first_col, first_col[1:]): constraints.append(Equals(b.bounds.top_edge, a.bounds.bottom_edge + spacing)) # flatten the grid and store it self.shapes.extend(shape for row in grid for shape in row)
def test_btor_get_non_bool_value(self): with Solver(name="btor") as s: x = Symbol("x", BVType(16)) s.add_assertion(Equals(x, BV(1, 16))) self.assertTrue(s.solve()) self.assertEqual(s.get_value(Equals(x, BV(1, 16))), TRUE()) self.assertEqual(s.get_value(BVAdd(x, BV(1, 16))), BV(2, 16))
def add_relu_eager_constraint(self): # Eager lemma encoding for relus zero = Real(0) for r, relu_in in self.relus: self.formulae.append(Implies(GT(relu_in, zero), Equals(r, relu_in))) self.formulae.append(Implies(LE(relu_in, zero), Equals(r, zero)))
def k_sequence_WH(m, K, K_seq_len=100, count=100): k_seq = [Symbol('x_%i' % i, INT) for i in range(K_seq_len)] domain = And([Or(Equals(x, Int(0)), Equals(x, Int(1))) for x in k_seq]) K_window = And([ LE(Plus(k_seq[t:min(K_seq_len, t + K)]), Int(m)) for t in range(max(1, K_seq_len - K + 1)) ]) formula = And(domain, K_window) solver = Solver(name='yices', incremental=True, random_seed=randint(2 << 30)) solver.add_assertion(formula) for _ in range(count): result = solver.solve() if not result: solver = Solver(name='z3', incremental=True, random_seed=randint(2 << 30)) solver.add_assertion(formula) solver.solve() model = solver.get_model() model = array(list(map(lambda x: model.get_py_value(x), k_seq)), dtype=bool) yield model solver.add_assertion( Or([NotEquals(k_seq[i], Int(model[i])) for i in range(K_seq_len)]))
def test_str_to_int(self): f = Equals(StrToInt(String("1")), Int(1)) self.assertValid(f) f = Equals(StrToInt(String("-55")), Int(-1)) self.assertValid(f) f = Equals(StrToInt(String("pippo")), Int(-1)) self.assertValid(f)
def break_dfa_symmetry_bfs(x, y, sigma, prefixes_r, h): epsilon_i = prefixes_r[()] assert epsilon_i == 0 constraints = [] constraints.append(Equals(x[epsilon_i], Int(1))) t = [[Symbol(f"t_{i}_{j}", BOOL) for j in range(h)] for i in range(h)] p = [[Symbol(f"p_{i}_{j}", BOOL) for j in range(h)] for i in range(h)] for i, j in it.combinations(range(h), 2): constraints.append(Iff( t[i][j], Or(*(Equals(Select(y[l], Int(i+1)), Int(j+1)) for l in range(len(sigma)))) )) constraints.append(Iff( p[j][i], And( t[i][j], *(Not(t[k][j]) for k in range(i)) ) )) for j in range(1, h): constraints.append(Or(*(p[j][k] for k in range(j)))) for k, i, j in it.combinations(range(h-1), 3): constraints.append(Implies(p[j][i], Not(p[j+1][k]))) assert len(sigma) == 2 for i, j in it.combinations(range(h-1), 2): constraints.append(Implies(And(p[j][i], p[j+1][i]), Equals(Select(y[0], Int(i+1)), Int(j+1)))) return constraints
def process(): varA = Symbol("A") varB = Symbol("B") f = And(varA, Not(varB)) print(f) print(is_sat(f)) hello = [Symbol(s, INT) for s in "hello"] world = [Symbol(s, INT) for s in "world"] letters = set(hello + world) domains = And(And(LE(Int(1), l), GE(Int(10), l)) for l in letters) print(domains,'domain') sum_hello = Plus(hello) sum_world = Plus(world) problem = And(Equals(sum_hello, sum_world), Equals(sum_hello, Int(36))) formula = And(domains, problem) print("Serialization of the formula:") print(formula) print(formula.serialize()) print(is_sat(formula)) print(get_model(formula))
def main(): # Example Transition System (SMV-like syntax) # # VAR x: integer; # y: integer; # # INIT: x = 1 & y = 2; # # TRANS: next(x) = x + 1; # TRANS: next(y) = y + 2; x, y = [Symbol(s, INT) for s in "xy"] nx, ny = [next_var(Symbol(s, INT)) for s in "xy"] example = TransitionSystem(variables=[x, y], init=And(Equals(x, Int(1)), Equals(y, Int(2))), trans=And(Equals(nx, Plus(x, Int(1))), Equals(ny, Plus(y, Int(2))))) # A true invariant property: y = x * 2 true_prop = Equals(y, Times(x, Int(2))) # A false invariant property: x <= 10 false_prop = LE(x, Int(10)) for prop in [true_prop, false_prop]: check_property(example, prop) print("")
def resize_bvs(self, formula): """ Resize the bitvector variables wrt to the maximum domain size """ subs_map = {} for (fvar, max_value) in self.fvars_maxval.iteritems(): old_enc_var = self.fvars2encvars.lookup_a(fvar) bv_size = self.get_size(max_value+1) new_enc_var = FreshSymbol(BVType(bv_size)) self.fvars2encvars.add(fvar, new_enc_var) val2val = self.fvars2values[fvar] for i in range(max_value + 1): old_value = BV(i, SymbolicGrounding.MAX_BV) new_value = BV(i, bv_size) fval = val2val.lookup_b(old_value) val2val.add(fval, new_value) old_f = Equals(old_enc_var, old_value) new_f = Equals(new_enc_var, new_value) subs_map[old_f] = new_f formula = substitute(formula, subs_map) return formula
def belongs_and_unique(idx): disequal = [Or(Not(Equals(v, output_amt[idx])), Equals(output_party[k], Int(party)))\ for (k, v) in filter(lambda x: x[0] != idx, output_amt.items())] return And(Equals(output_party[idx], Int(party)), And(disequal))
def test_btor_get_array_element(self): with Solver(name="btor") as s: x = Symbol("a", ArrayType(BVType(16), BVType(16))) s.add_assertion(Equals(Select(x, BV(1, 16)), BV(1, 16))) s.add_assertion(Equals(Select(x, BV(2, 16)), BV(3, 16))) self.assertTrue(s.solve()) self.assertEqual(s.get_value(Select(x, BV(1, 16))), BV(1, 16)) self.assertIsNotNone(s.get_value(x))
def sym_exec_rsicv_add(rs1, rs2, rd, regs): rs1_val = Ite(Equals(rs1, BitVecVal(0, 5)), BitVecVal(0, 32), Select(regs, rs1)) rs2_val = Ite(Equals(rs2, BitVecVal(0, 5)), BitVecVal(0, 32), Select(regs, rs2)) res = BVAdd(rs1_val, rs2_val) regs_n = Store(regs, rd, res) return Ite(Equals(rd, BitVecVal(0, 5)), regs, regs_n)
def test_div_by_0(self): varA = Symbol('A', REAL) varB = Symbol('B', REAL) f = And(Equals(varA, varB), Not(Equals(Div(varA, Real(0)), Div(varB, Real(0))))) self.assertUnsat(f)
def test_div_pow(self): x = FreshSymbol(REAL) f = Equals(Times(Real(4), Pow(x, Real(-1))), Real(2)) self.assertTrue(is_sat(f)) f = Equals(Div(Real(4), x), Real(2)) self.assertTrue(is_sat(f, solver_name="z3")) f = Equals(Times(x, x), Real(16)) self.assertTrue(is_sat(f))
def test_ackermannization_unary(self): self.env.enable_infix_notation = True a, b = (Symbol(x, INT) for x in "ab") f, g, h = (Symbol(x, FunctionType(INT, [INT])) for x in "fgh") formula1 = Not(Equals(f(g(h(a))), f(g(h(b))))) formula2 = Equals(a, b) formula = And(formula1, formula2) self._verify_ackermannization(formula)
def test_ackermannization_pairwise(self): self.env.enable_infix_notation = True a, b, c, d = (Symbol(x, INT) for x in "abcd") f = Symbol("f", FunctionType(INT, [INT])) formula = And(Not(Equals(f(b), f(c))), Equals(f(a), f(b)), Equals(f(c), f(d)), Equals(a, d)) self.assertUnsat(formula) formula_ack = Ackermannizer().do_ackermannization(formula) self.assertUnsat(formula_ack)
def check_table_energies_exact(self, graph, decision_variables, h, J): """For a given ising problem, check that the table gives the correct energies when linear and quadratic energies are specified exactly. """ # determine the aux variables aux_variables = tuple(v for v in graph if v not in decision_variables) # now generate a theta that sets linear and quadratic equal to h, J linear_ranges = {v: (bias, bias) for v, bias in h.items()} quadratic_ranges = {edge: (bias, bias) for edge, bias in J.items()} # and now the table table = Table(graph, decision_variables, linear_ranges, quadratic_ranges) # ok, time to do some energy calculations for config in itertools.product((-1, 1), repeat=len(decision_variables)): spins = dict(zip(decision_variables, config)) # first we want to know the minimum classical energy energy = float('inf') for aux_config in itertools.product((-1, 1), repeat=len(aux_variables)): aux_spins = dict(zip(aux_variables, aux_config)) aux_spins.update(spins) aux_energy = ising_energy(h, J, aux_spins) if aux_energy < energy: energy = aux_energy # collect assertions assertions = table.assertions theta = table.theta # so we can set the offset directly # table assertions by themselves should be SAT self.assertSat(And(assertions)) # ok, does the exact energy calculated by the table match? table_energy = table.energy(spins, break_aux_symmetry=False) for offset in [0, -.5, -.3, -.1, .23, 1, 106]: self.assertSat(And([Equals(table_energy, limitReal(energy + offset)), And(assertions), Equals(theta.offset, limitReal(offset))]), msg='exact energy equality is not SAT') self.assertUnsat(And([Not(Equals(table_energy, limitReal(energy + offset))), And(assertions), Equals(theta.offset, limitReal(offset))]), msg='exact energy inequality is not UNSAT') # how about the upper bound? table_energy_upperbound = table.energy_upperbound(spins) for offset in [-.5, -.3, -.1, 0, .23, 1, 106]: self.assertSat(And([GE(table_energy_upperbound, limitReal(energy + offset)), And(assertions), Equals(theta.offset, limitReal(offset))]), msg='energy upperbound is not SAT')
def find_all_moves(p): logger.debug("finding all possible moves for %s" % p.name) options = [] for r, row in enumerate(board): for c, cell in enumerate(row): if not Equals( board[r][c], p.value) in solver.assertions: # if not already played options.append(Equals(cell, p.value)) return options
def add_relu_simplex_friendly_eager(self): # Eager lemma encoding for relus zero = Real(0) for relu_out, relu_in in self.relus: #Introduce f = relu_out - relu_in f = FreshSymbol(REAL) self.formulae.append(Equals(f, Minus(relu_out, relu_in))) self.formulae.append(Implies(GT(relu_in, zero), Equals(f, zero))) self.formulae.append( Implies(LE(relu_in, zero), Equals(relu_out, zero)))
def score_output( idx ): #how many other outputs in the same amount that do not belong to us? outputs_equal_not_ours = [And(Equals(v, output_amt[idx]), Not(Equals(output_party[k], output_party[idx])))\ for (k, v) in filter(lambda x: x[0] != idx, output_amt.items())] score = Plus([bool_to_int(x) for x in outputs_equal_not_ours]) anonymityset_constraints.add(Equals(output_score[idx], score)) return score
def exec_Branch(self, instr: Branch, st): taken = { BranchCond.CC: lambda: Equals(st.C, BitVecVal(0, 1)), BranchCond.CS: lambda: Equals(st.C, BitVecVal(1, 1)), BranchCond.EQ: lambda: Equals(st.Z, BitVecVal(1, 1)), BranchCond.NE: lambda: Equals(st.Z, BitVecVal(0, 1)), }[instr.cond]() if instr.offset >= 0: taken_pc = BVAdd(st.PC, BitVecVal(instr.offset + 1, 16)) else: taken_pc = BVSub(st.PC, BitVecVal((-instr.offset) + 1, 16)) return st, (taken, taken_pc)
def translate(self): """Create SMT expressions for bounding the parameters of an output port to be within the constraints defined by the user :param str name: Name of the port to be constrained :returns: None -- no issues with translating the port parameters to SMT """ incoming_channels = self.get_incoming_channels() if len(incoming_channels) <= 0: raise ValueError("Port %s must have 1 or more connections" % self.get_name()) # Currently don't support this, and I don't think it would be the case # in real circuits, an output port is considered the end of a branch outgoing_channels = self.get_outgoing_channels() if len(outgoing_channels) != 0: raise ValueError("Cannot have channels out of output port %s" % self.get_name()) # Since input is just a specialized node, call translate node self.exprs.append(Node.Node().translate(self)) #TODO: test this # Calculate flow rate for this port based on pressure and channels out # if not specified by user if not self.get_min_flow_rate(name): # The flow rate at this node is the sum of the flow rates of the # the channel coming in (I think, should be verified) total_flow_in = [] for incoming_channel in incoming_channels: # TODO: This is where the flow rate calls to the input nodes get triggered self.exprs.append(incoming_channel) total_flow_in.append(incoming_channel.get_flow_rate()) if len(total_flow_in) == 1: # only one incoming channel self.exprs.append( Equals(self.get_flow_rate(), total_flow_in[0])) else: self.exprs.append( Equals(self.get_flow_rate(), Plus(total_flow_in))) self.expers.append(incomming_channel.translate()) # Once it gets back from translating we can get the flow rate total_flow_in.append(channel_in.get_channel_flow_rate()) ''' Here iterate over the incoming channels and call translate over them for incomming_channel in self.incoming_channels: self.expers.append(incomming_channel.translate()) # Once it gets back from translating we can get the flow rate total_flow_in.append(channel_in.get_channel_flow_rate()) ''' return self.exprs
def k_sequence_WH_worst_case(m, K, K_seq_len=100, count=100): k_seq = [Symbol('x_%i' % i, INT) for i in range(K_seq_len)] domain = And([Or(Equals(x, Int(0)), Equals(x, Int(1))) for x in k_seq]) K_window = And([ LE(Plus(k_seq[t:min(K_seq_len, t + K)]), Int(m)) for t in range(max(1, K_seq_len - K + 1)) ]) violate_up = And([ GT(Plus(k_seq[t:min(K_seq_len, t + K)]), Int(m - 1)) for t in range(max(1, K_seq_len - K + 1)) ]) def violate_right_generator(n): return And([ GT(Plus(k_seq[t:min(K_seq_len, t + K + n)]), Int(m)) for t in range(max(1, K_seq_len - (K + n) + 1)) ]) right_shift = 1 formula = And(domain, K_window, violate_up, violate_right_generator(right_shift)) solver = Solver(name='z3', incremental=True, random_seed=randint(2 << 30)) solver.add_assertion(formula) solver.z3.set('timeout', 5 * 60 * 1000) solutions = And() for _ in range(count): while right_shift + K < K_seq_len: try: result = solver.solve() except BaseException: result = None if not result: solver = Solver(name='z3', incremental=True, random_seed=randint(2 << 30)) right_shift += 1 solver.z3.set('timeout', 5 * 60 * 1000) solver.add_assertion( And(solutions, domain, K_window, violate_up, violate_right_generator(right_shift))) else: break try: model = solver.get_model() except BaseException: break model = array(list(map(lambda x: model.get_py_value(x), k_seq)), dtype=bool) yield model solution = Or( [NotEquals(k_seq[i], Int(model[i])) for i in range(K_seq_len)]) solutions = And(solutions, solution) solver.add_assertion(solution)
def test_complex_types(self): with self.assertRaises(PysmtTypeError): # Not(Store(Array<Real,BV8>(8d_0), 1.0, 8d_5) = # Store(Array<Int,BV8>(8d_0), 1, 8d_5)) Not( Equals(Store(Array(REAL, BV(0, 8)), Real(1), BV(5, 8)), Store(Array(INT, BV(0, 8)), Int(1), BV(5, 8)))) nested_a = Symbol("a_arb_aii", ArrayType(ArrayType(REAL, BV8), ARRAY_INT_INT)) with self.assertRaises(PysmtTypeError): # This is wrong, because the first elemnt of Array must be a Type Equals(nested_a, Array(Array(REAL, BV(0, 8)), Array(INT, Int(7))))
def test_get_atoms_array_select(self): a = Symbol("a", ArrayType(INT, BOOL)) x = Symbol("x", INT) p = Symbol("p", BOOL) phi = And(Iff(Select(a, x), p), Equals(x, Int(1))) atoms = phi.get_atoms() self.assertEqual(len(atoms), 3) self.assertIn(Select(a, x), atoms) self.assertIn(p, atoms) self.assertIn(Equals(x, Int(1)), atoms)
def test_integer(self): x = FreshSymbol(INT) f = Equals(Times(x, x), Int(2)) with Solver(name="z3") as s: self.assertFalse(s.is_sat(f)) # f = Equals(Times(Int(4), Pow(x, Int(-1))), Int(2)) # self.assertTrue(is_sat(f, solver_name="z3")) f = Equals(Div(Int(4), x), Int(2)) self.assertTrue(is_sat(f, solver_name="z3")) f = Equals(Times(x, x), Int(16)) self.assertTrue(is_sat(f))
def evenly_spaced(start_point, end_point, shapes): n = len(shapes) assert n > 1 constraints = [] for i in range(n): if shapes[i] is None: continue j = n - i - 1 x = (start_point.x * j + end_point.x * i) / (n - 1) y = (start_point.y * j + end_point.y * i) / (n - 1) constraints.append(Equals(shapes[i].x, x)) constraints.append(Equals(shapes[i].y, y)) return And(constraints)
def test_copy(self): linear_ranges = defaultdict(lambda: (-2., 2.)) quadratic_ranges = defaultdict(lambda: (-1., 1.)) graph = nx.complete_graph(5) theta = Theta.from_graph(graph, linear_ranges, quadratic_ranges) cp_theta = theta.copy() # should all point to the same for v, bias in theta.linear.items(): self.assertSat(Equals(bias, cp_theta.linear[v])) self.assertUnsat(Not(Equals(bias, cp_theta.linear[v])))
def convert(self, abstract=False): for i in range(self.nnet.inputSize): x = Symbol("x%d" % i, REAL) self.input_vars.append(x) for i in range(self.nnet.outputSize): y = Symbol("y%d" % i, REAL) self.output_vars.append(y) # for i,v in enumerate(self.input_vars): # # normalized # m = self.nnet.mins[i] # l = GE(self.input_vars[i], # Real((m - self.nnet.means[i])/self.nnet.ranges[i])) # self.formulae.append(l) # # normalized # m = self.nnet.maxes[i] # l = LE(self.input_vars[i], # Real((m - self.nnet.means[i])/self.nnet.ranges[i])) # self.formulae.append(l) prev_layer_result = self.input_vars.copy() layer_result = [] zero = Real(0) self.relus_level.append(set()) for l in range(self.nnet.numLayers - 1): self.relus_level.append(set()) for ls in range(self.nnet.layerSizes[l + 1]): r = self.dot(self.nnet.weights[l][ls], prev_layer_result) r = Plus(r, Real(float(self.nnet.biases[l][ls]))) relu_in = FreshSymbol(REAL) self.formulae.append(Equals(relu_in, r)) if abstract: relu_out = FreshSymbol(REAL) r = relu_out self.relus.append((relu_out, relu_in)) self.relus_level[l + 1].add((relu_out, relu_in)) else: r = Max(relu_in, zero) layer_result.append(r) prev_layer_result = layer_result.copy() layer_result.clear() for i, y in enumerate(self.output_vars): o = self.dot(self.nnet.weights[-1][i], prev_layer_result) o = Plus(o, Real(float(self.nnet.biases[-1][i]))) # # undo normalization # o = Times(o, Real(self.nnet.ranges[-1])) # o = Plus(o, Real(self.nnet.means[-1])) self.formulae.append(Equals(y, o)) self.parse_violation(self.violation_path)
def test_bv(self): mgr = self.env.formula_manager BV = mgr.BV # Constants one = BV(1, 32) zero = BV(0, 32) big = BV(127, 128) binary = BV("111") binary2 = BV("#b111") binary3 = BV(0b111, 3) # In this case we need to explicit the width self.assertEqual(binary, binary2) self.assertEqual(binary2, binary3) self.assertEqual(one, mgr.BVOne(32)) self.assertEqual(zero, mgr.BVZero(32)) # Type Equality self.assertTrue(BV32 != BV128) self.assertFalse(BV32 != BV32) self.assertFalse(BV32 == BV128) self.assertTrue(BV32 == BV32) with self.assertRaises(PysmtValueError): # Negative numbers are not supported BV(-1, 10) with self.assertRaises(PysmtValueError): # Number should fit in the width BV(10, 2) # Variables b128 = Symbol("b", BV128) # BV1, BV8 etc. are defined in pysmt.typing b32 = Symbol("b32", BV32) hexample = BV(0x10, 32) bcustom = Symbol("bc", BVType(42)) self.assertIsNotNone(hexample) self.assertIsNotNone(bcustom) self.assertEqual(bcustom.bv_width(), 42) self.assertEqual(hexample.constant_value(), 16) not_zero32 = mgr.BVNot(zero) not_b128 = mgr.BVNot(b128) self.assertTrue(not_b128.is_bv_not()) f1 = Equals(not_zero32, b32) f2 = Equals(not_b128, big) self.assertTrue(is_sat(f1, logic=QF_BV)) self.assertTrue(is_sat(f2, logic=QF_BV)) zero_and_one = mgr.BVAnd(zero, one) self.assertTrue(zero_and_one.is_bv_and()) zero_or_one = mgr.BVOr(zero, one) self.assertTrue(zero_or_one.is_bv_or()) zero_xor_one = mgr.BVXor(zero, one) self.assertTrue(zero_xor_one.is_bv_xor()) zero_xor_one.simplify() self.assertTrue(zero_xor_one.is_bv_op()) f1 = Equals(zero_and_one, b32) f2 = Equals(zero_or_one, b32) f3 = Equals(zero_xor_one, b32) f4 = Equals(zero_xor_one, one) self.assertTrue(is_sat(f1, logic=QF_BV), f1) self.assertTrue(is_sat(f2, logic=QF_BV), f2) self.assertTrue(is_sat(f3, logic=QF_BV), f3) self.assertTrue(is_valid(f4, logic=QF_BV), f4) with self.assertRaises(PysmtTypeError): mgr.BVAnd(b128, zero) f = mgr.BVAnd(b32, zero) f = mgr.BVOr(f, b32) f = mgr.BVXor(f, b32) f = Equals(f, zero) self.assertTrue(is_sat(f, logic=QF_BV), f) zero_one_64 = mgr.BVConcat(zero, one) one_zero_64 = mgr.BVConcat(one, zero) one_one_64 = mgr.BVConcat(one, one) self.assertTrue(one_one_64.is_bv_concat()) self.assertFalse(one_one_64.is_bv_and()) self.assertTrue(zero_one_64.bv_width() == 64) f1 = Equals(mgr.BVXor(one_zero_64, zero_one_64), one_one_64) self.assertTrue(is_sat(f1, logic=QF_BV), f1) # MG: BV indexes grow to the left. # This is confusing and we should address this. extraction = mgr.BVExtract(zero_one_64, 32, 63) self.assertTrue(is_valid(Equals(extraction, zero))) ult = mgr.BVULT(zero, one) self.assertTrue(ult.is_bv_ult()) neg = mgr.BVNeg(one) self.assertTrue(neg.is_bv_neg()) self.assertTrue(is_valid(ult, logic=QF_BV), ult) test_eq = Equals(neg, one) self.assertTrue(is_unsat(test_eq, logic=QF_BV)) f = zero addition = mgr.BVAdd(f, one) self.assertTrue(addition.is_bv_add()) multiplication = mgr.BVMul(f, one) self.assertTrue(multiplication.is_bv_mul()) udiv = mgr.BVUDiv(f, one) self.assertTrue(udiv.is_bv_udiv()) self.assertTrue(is_valid(Equals(addition, one), logic=QF_BV), addition) self.assertTrue(is_valid(Equals(multiplication, zero), logic=QF_BV), multiplication) self.assertTrue(is_valid(Equals(udiv, zero), logic=QF_BV), udiv) three = mgr.BV(3, 32) two = mgr.BV(2, 32) self.assertEqual(3, three.bv2nat()) reminder = mgr.BVURem(three, two) self.assertTrue(reminder.is_bv_urem()) shift_l_a = mgr.BVLShl(one, one) self.assertTrue(shift_l_a.is_bv_lshl()) shift_l_b = mgr.BVLShl(one, 1) self.assertTrue(is_valid(Equals(reminder, one)), reminder) self.assertEqual(shift_l_a, shift_l_b) self.assertTrue(is_valid(Equals(shift_l_a, two))) shift_r_a = mgr.BVLShr(one, one) self.assertTrue(shift_r_a.is_bv_lshr()) shift_r_b = mgr.BVLShr(one, 1) self.assertEqual(shift_r_a, shift_r_b) self.assertTrue(is_valid(Equals(shift_r_a, zero))) ashift_r_a = mgr.BVAShr(one, one) ashift_r_b = mgr.BVAShr(one, 1) self.assertEqual(ashift_r_a, ashift_r_b) self.assertTrue(ashift_r_a.is_bv_ashr()) rotate_l = mgr.BVRol(one, 3) self.assertTrue(rotate_l.is_bv_rol()) rotate_r = mgr.BVRor(rotate_l, 3) self.assertTrue(rotate_r.is_bv_ror()) self.assertTrue(is_valid(Equals(one, rotate_r))) zero_ext = mgr.BVZExt(one, 64) self.assertTrue(zero_ext.is_bv_zext()) signed_ext = mgr.BVSExt(one, 64) self.assertTrue(signed_ext.is_bv_sext()) signed_ext2 = mgr.BVSExt(mgr.BVNeg(one), 64) self.assertNotEqual(signed_ext2, signed_ext) self.assertTrue(is_valid(Equals(zero_ext, signed_ext), logic=QF_BV)) x = Symbol("x") g = And(x, mgr.BVULT(zero, one)) res = is_sat(g, logic=QF_BV) self.assertTrue(res) model = get_model(g, logic=QF_BV) self.assertTrue(model[x] == TRUE()) gt_1 = mgr.BVUGT(zero, one) gt_2 = mgr.BVULT(one, zero) self.assertEqual(gt_1, gt_2) gte_1 = mgr.BVULE(zero, one) gte_2 = mgr.BVUGE(one, zero) self.assertEqual(gte_1, gte_2) self.assertTrue(is_valid(gte_2, logic=QF_BV)) ide = Equals(mgr.BVNeg(BV(10, 32)), mgr.SBV(-10, 32)) self.assertValid(ide, logic=QF_BV) # These should work without exceptions mgr.SBV(-2, 2) mgr.SBV(-1, 2) mgr.SBV(0, 2) mgr.SBV(1, 2) # Overflow and Underflow with self.assertRaises(PysmtValueError): mgr.SBV(2, 2) with self.assertRaises(PysmtValueError): mgr.SBV(-3, 2) # These should work without exceptions mgr.BV(0, 2) mgr.BV(1, 2) mgr.BV(2, 2) mgr.BV(3, 2) # Overflow with self.assertRaises(PysmtValueError): mgr.BV(4, 2) # No negative number allowed with self.assertRaises(PysmtValueError): mgr.BV(-1, 2) # SBV should behave as BV for positive numbers self.assertEqual(mgr.SBV(10, 16), mgr.BV(10, 16)) # Additional is_bv_* tests f = mgr.BVSub(one, one) self.assertTrue(f.is_bv_sub()) f = mgr.BVSLT(one, one) self.assertTrue(f.is_bv_slt()) f = mgr.BVSLE(one, one) self.assertTrue(f.is_bv_sle()) f = mgr.BVComp(one, one) self.assertTrue(f.is_bv_comp()) f = mgr.BVSDiv(one, one) self.assertTrue(f.is_bv_sdiv()) f = mgr.BVSRem(one, one) self.assertTrue(f.is_bv_srem()) f = mgr.BVULE(one, one) self.assertTrue(f.is_bv_ule())
def test_trivial_true_times(self): x,y,z = (Symbol(name, REAL) for name in "xyz") f = Equals(Times(x, z, y), Times(z, y, x)) self.assertEqual(f.simplify(), TRUE())