def generate_strict_cnf(domain, and_count, or_count, half_space_count): half_spaces = [generate_half_space_sample(domain, len(domain.real_vars)) for _ in range(half_space_count)] candidates = [domain.get_symbol(v) for v in domain.bool_vars] + half_spaces candidates += [smt.Not(c) for c in candidates] formulas = [] iteration = 0 max_iterations = 100 * and_count while len(formulas) < and_count: if iteration >= max_iterations: return generate_strict_cnf(domain, and_count, or_count, half_space_count) iteration += 1 formula_candidates = [c for c in candidates] random.shuffle(formula_candidates) formula = [] try: while len(formula) < or_count: next_term = formula_candidates.pop(0) if len(formula) == 0 or smt.is_sat(~smt.Or(*formula) & next_term): formula.append(next_term) except IndexError: continue if len(formulas) == 0 or smt.is_sat(~smt.And(*[smt.Or(*f) for f in formulas]) & smt.Or(*formula)): formulas.append(formula) return smt.And(*[smt.Or(*f) for f in formulas])
def refine_input_partition(path_condition, assertion, input_partition, is_multi_dimension): input_constraints = generator.generate_constraint_for_input_partition(input_partition) path_constraints = And(path_condition, input_constraints) is_exist_check = And(path_constraints, Not(assertion)) is_always_check = And(path_constraints, assertion) refined_partition_list = [] if is_sat(is_always_check): if is_sat(is_exist_check): concrete_count = 1 for parameter in input_partition: dimension = len( range(input_partition[parameter]['lower-bound'], input_partition[parameter]['upper-bound'] + 1)) concrete_count = concrete_count * dimension if concrete_count > 1: break if concrete_count == 1: return refined_partition_list partition_model = generator.generate_model(is_exist_check) partition_model, is_multi_dimension = extractor.extract_input_list(partition_model) partition_list = generator.generate_partition_for_input_space(partition_model, input_partition, is_multi_dimension) for partition in partition_list: if refined_partition_list: refined_partition_list = refined_partition_list + refine_input_partition(path_condition, assertion, partition, is_multi_dimension) else: refined_partition_list = refine_input_partition(path_condition, assertion, partition, is_multi_dimension) else: refined_partition_list.append(input_partition) return refined_partition_list
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 test_shortcuts(self): for (expr, _, sat_res, logic) in get_example_formulae(): if not logic <= QF_UFLIRA: continue res = is_sat(expr, portfolio=["z3", "cvc4", "msat"]) self.assertEqual(res, sat_res, expr) with self.assertRaises(ValueError): is_sat(TRUE(), portfolio=["supersolver"])
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 _verify_ackermannization(self, formula): ackermannization = Ackermannizer() ack = ackermannization.do_ackermannization(formula) #verify that there are no functions in ack atoms = ack.get_atoms() for atom in atoms: for arg in atom.args(): self.assertFalse(arg.is_function_application()) #verify that ack and formula are equisat formula_sat = is_sat(formula) ack_sat = is_sat(ack) self.assertTrue(formula_sat == ack_sat)
def test_logic_as_string(self): self.assertEqual(convert_logic_from_string("QF_LRA"), QF_LRA) with self.assertRaises(UndefinedLogicError): convert_logic_from_string("PAPAYA") self.assertIsNone(convert_logic_from_string(None)) x = Symbol("x") self.assertTrue(is_sat(x, logic="QF_LRA")) with self.assertRaises(UndefinedLogicError): is_sat(x, logic="PAPAYA") self.assertTrue(is_sat(x, logic=None)) self.assertTrue(is_sat(x))
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 test_is_sat(self): varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) f = And(varA, Not(varB)) g = f.substitute({varB: varA}) res = is_sat(g, logic=QF_BOOL) self.assertFalse(res, "Formula was expected to be UNSAT") for solver in get_env().factory.all_solvers(): res = is_sat(g, solver_name=solver) self.assertFalse(res, "Formula was expected to be UNSAT")
def test_conversion_error(self): from pysmt.type_checker import SimpleTypeChecker add_dwf = get_env().add_dynamic_walker_function create_node = get_env().formula_manager.create_node # Create a node that is not supported by any solver idx = op.new_node_type() x = Symbol("x") add_dwf(idx, SimpleTypeChecker, SimpleTypeChecker.walk_bool_to_bool) invalid_node = create_node(idx, args=(x,x)) for sname in get_env().factory.all_solvers(logic=QF_BOOL): with self.assertRaises(ConvertExpressionError): is_sat(invalid_node, solver_name=sname, logic=QF_BOOL)
def test_conversion_error(self): from pysmt.type_checker import SimpleTypeChecker add_dwf = get_env().add_dynamic_walker_function create_node = get_env().formula_manager.create_node # Create a node that is not supported by any solver idx = op.new_node_type() x = Symbol("x") add_dwf(idx, SimpleTypeChecker, SimpleTypeChecker.walk_bool_to_bool) invalid_node = create_node(idx, args=(x, x)) for sname in get_env().factory.all_solvers(logic=QF_BOOL): with self.assertRaises(ConvertExpressionError): is_sat(invalid_node, solver_name=sname, logic=QF_BOOL)
def test_logic_as_string(self): self.assertEqual(convert_logic_from_string("QF_LRA"), QF_LRA) if PY2: self.assertEqual(convert_logic_from_string(unicode("QF_LRA")), QF_LRA) with self.assertRaises(UndefinedLogicError): convert_logic_from_string("PAPAYA") self.assertIsNone(convert_logic_from_string(None)) x = Symbol("x") self.assertTrue(is_sat(x, logic="QF_LRA")) with self.assertRaises(UndefinedLogicError): is_sat(x, logic="PAPAYA") self.assertTrue(is_sat(x, logic=None)) self.assertTrue(is_sat(x))
def main(argv): inputfile = '' usage = 'Usage: cab.py -i <inputfile> [options]' options = ( 'Options are:\n\t--debug, -d \n\t\ttoggles printing of debug messages.\n\t' + '--smtinterpol\n\t\ttoggles usage of smtinterpol solver for interpolation.' ) man = '%s\n\n%s' % (usage, options) try: opts, args = getopt.getopt(argv, 'hi:d', ['input=', 'debug']) except getopt.GetoptError: print(man) sys.exit(2) for opt, arg in opts: if opt == '-h': print(man) sys.exit(2) elif opt in ('-i', '--input'): inputfile = arg elif opt in ('-d', '--debug'): logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) if logging.DEBUG < logging.root.level: logging.basicConfig(level=logging.WARNING) g = Game.read(inputfile) res, n = g.solve(0) if is_sat(res): print('Player REACH wins.') else: print('Player SAFE wins.') print('Number of visited subgames: ' + str(n))
def overlaps(i,j): """ Returns True if two instructions i,j overlap in their encoding. TODO: Add operand constraints into the solver formula. """ if(i.pseudo or j.pseudo): return False ILEN=32 instr = Symbol("instr" , BVType(width=ILEN)) imask = Symbol("imask" , BVType(width=ILEN)) imatch = Symbol("imatch" , BVType(width=ILEN)) jmask = Symbol("jmask" , BVType(width=ILEN)) jmatch = Symbol("jmatch" , BVType(width=ILEN)) domains = And([ EQ(imask , BV(i.mask() ,width=ILEN)), EQ(imatch, BV(i.match(),width=ILEN)), EQ(jmask , BV(j.mask() ,width=ILEN)), EQ(jmatch, BV(j.match(),width=ILEN)) ]) problem = And([ EQ(instr & imask, imatch), EQ(instr & jmask, jmatch) ]) formula = And(domains, problem) return is_sat(formula)
def test_examples_z3(self): for (f, validity, satisfiability, logic) in get_example_formulae(): v = is_valid(f, solver_name='z3', logic=logic) s = is_sat(f, solver_name='z3', logic=logic) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f)
def check_patch_feasibility(assertion, var_relationship, patch_constraint, path_condition, index): # TODO path_constraint = And(path_condition, patch_constraint) patch_score = 0 is_under_approx = None is_over_approx = None result = True if assertion: if is_sat(path_constraint): if is_loc_in_trace(values.CONF_LOC_BUG): patch_score = 2 is_under_approx = not is_unsat(And(path_constraint, Not(assertion))) if values.DEFAULT_REFINE_METHOD in ["under-approx", "overfit"]: if is_under_approx: emitter.debug("removing due to universal quantification") result = False negated_path_condition = values.NEGATED_PPC_FORMULA path_constraint = And(negated_path_condition, patch_constraint) is_over_approx = not is_unsat(And(path_constraint, assertion)) if values.DEFAULT_REFINE_METHOD in ["over-approx", "overfit"]: if is_over_approx: emitter.debug("removing due to existential quantification") result = False else: patch_score = 1 # else: # specification = And(path_condition, Not(patch_constraint)) # existential_quantification = is_unsat(And(specification, assertion)) # result = existential_quantification return result, index, patch_score, is_under_approx, is_over_approx
def checkSatisfiability(self, postFixList): propStack = Stack() p = re.compile('[a-zA-Z0-1]') for op in postFixList: if op == 'ID' or p.match(op): propStack.push(Symbol(op)) elif op in ['NOT', '!']: propStack.push(Not(propStack.pop())) elif op in ['AND', '/\\', ',', 'COMMA']: p2 = propStack.pop() p1 = propStack.pop() propStack.push(And(p1, p2)) elif op in ['OR', '\\/']: p2 = propStack.pop() p1 = propStack.pop() propStack.push(Or(p1, p2)) elif op in ['IFF', '<=>']: p2 = propStack.pop() p1 = propStack.pop() propStack.push(Iff(p1, p2)) elif op in ['IMPLIES', '=>']: p2 = propStack.pop() p1 = propStack.pop() propStack.push(Implies(p1, p2)) print("propStack size: ", propStack.size()) if propStack.size() == 1: p3 = propStack.pop() # print ("Expression for satisfiability:", p3) print("Is sat or not : ", is_sat(p3)) else: print("Error while checking Is sat or not")
def refine_for_under_approx(patch_formula, path_condition, patch_space, p_specification): parameter_constraint = smt2.generate_constraint_for_patch_space(patch_space) patch_space_constraint = patch_formula if parameter_constraint: patch_space_constraint = And(patch_formula, parameter_constraint) path_feasibility = And(path_condition, And(patch_space_constraint, p_specification)) path_constraint = And(path_condition, patch_formula) if values.VALID_INPUT_SPACE: input_space_constraint = Not(smt2.generate_constraint_for_input_space(values.VALID_INPUT_SPACE)) path_feasibility = And(path_condition, And(patch_space_constraint, input_space_constraint)) path_constraint = And(And(path_condition, input_space_constraint), patch_formula) # invalid input range is used to check for violations refined_patch_space = patch_space is_under_approx = False if is_sat(path_feasibility): is_under_approx = True if values.DEFAULT_REFINE_METHOD in ["under-approx", "overfit"]: emitter.debug("refining for universal quantification") if parameter_constraint: refined_patch_space = refine_parameter_space(path_constraint, patch_space, p_specification) is_under_approx = False else: refined_patch_space = None return refined_patch_space, is_under_approx
def test_get_logic_in_is_sat(self): varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) f = And(varA, Not(varB)) res = is_sat(f, logic=AUTO) self.assertTrue(res)
def test_examples_by_logic(self): for (f, validity, satisfiability, logic) in get_example_formulae(): if len(get_env().factory.all_solvers(logic=logic)) > 0: v = is_valid(f, logic=logic) s = is_sat(f, logic=logic) self.assertEqual(validity, v, f.serialize()) self.assertEqual(satisfiability, s, f.serialize())
def test_examples_yices(self): for (f, validity, satisfiability, logic) in get_example_formulae(): if not logic.quantifier_free: continue v = is_valid(f, solver_name='yices', logic=logic) s = is_sat(f, solver_name='yices', logic=logic) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f)
def test_exactly_one_is_sat(self): symbols = [ self.mgr.Symbol("s%d"%i, BOOL) for i in range(5) ] c = self.mgr.ExactlyOne(symbols) all_zero = self.mgr.And([self.mgr.Iff(s, self.mgr.Bool(False)) for s in symbols]) test_zero = self.mgr.And(c, all_zero) self.assertFalse(is_sat(test_zero, logic=QF_BOOL), "ExactlyOne should not allow all symbols to be False")
def _std_examples(self, qe, target_logic): for (f, validity, satisfiability, logic) in get_example_formulae(): if logic != target_logic: continue qf = qe.eliminate_quantifiers(f) s = is_sat(qf) v = is_valid(qf) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f)
def test_examples_btor(self): for (f, validity, satisfiability, logic) in get_example_formulae(): if not logic.quantifier_free: continue try: v = is_valid(f, solver_name='btor', logic=logic) s = is_sat(f, solver_name='btor', logic=logic) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f) except NoSolverAvailableError: pass #Skip tests for unsupported logic
def test_examples_msat(self): for (f, validity, satisfiability, logic) in get_example_formulae(): if not logic.quantifier_free: continue if not logic.theory.linear: continue if logic.theory.strings: continue v = is_valid(f, solver_name='msat', logic=logic) s = is_sat(f, solver_name='msat', logic=logic) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f)
def test_div_pow(self): x = FreshSymbol(REAL) f = Equals(Times(Real(4), Pow(x, Real(-1))), Real(2)) try: self.assertTrue(is_sat(f)) except SolverReturnedUnknownResultError: pass f = Equals(Div(Real(4), x), Real(2)) try: self.assertTrue(is_sat(f, solver_name="z3")) except SolverReturnedUnknownResultError: pass f = Equals(Times(x, x), Real(16)) try: self.assertTrue(is_sat(f)) except SolverReturnedUnknownResultError: pass
def test_default_logic_in_is_sat(self): factory = get_env().factory factory.default_logic = QF_BOOL self.assertEquals(factory.default_logic, QF_BOOL) varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) f = And(varA, Not(varB)) res = is_sat(f) self.assertTrue(res)
def do_examples(self, logic): conv = CNFizer() for example in EXAMPLE_FORMULAS: if example.logic != logic: continue cnf = conv.convert_as_formula(example.expr) self.assertValid(Implies(cnf, example.expr), logic=logic) res = is_sat(cnf, logic=logic) self.assertEqual(res, example.is_sat)
def do_examples(self, logic): conv = CNFizer() for example in get_example_formulae(): if example.logic != logic: continue cnf = conv.convert_as_formula(example.expr) self.assertValid(Implies(cnf, example.expr), logic=logic) res = is_sat(cnf, logic=logic) self.assertEqual(res, example.is_sat)
def test_examples_btor(self): for (f, validity, satisfiability, logic) in get_example_formulae(): if not logic.quantifier_free: continue if logic.theory.strings: continue if logic.theory.integer_arithmetic: continue if logic.theory.real_arithmetic: continue if logic.theory.custom_type: continue v = is_valid(f, solver_name='btor', logic=logic) s = is_sat(f, solver_name='btor', logic=logic) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f)
def test_examples_z3(self): for (f, validity, satisfiability, logic) in get_example_formulae(): try: v = is_valid(f, solver_name='z3', logic=logic) s = is_sat(f, solver_name='z3', logic=logic) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f) except NoSolverAvailableError: # Trying to solve a logic that mathsat does not support theory = logic.theory assert theory.strings
def test_examples_cvc4(self): for (f, validity, satisfiability, logic) in get_example_formulae(): try: if not logic.quantifier_free: continue v = is_valid(f, solver_name='cvc4', logic=logic) s = is_sat(f, solver_name='cvc4', logic=logic) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f) except SolverReturnedUnknownResultError: # CVC4 does not handle quantifiers in a complete way self.assertFalse(logic.quantifier_free)
def sample_comp_literal(self, var): while True: k = int(self.rand_gen.choice([-1, 1])) b = float(self.rand_gen.uniform(0, 1)) f = And(self.primal.get_full_formula(), Equals(Times(Real(k), var), Real(b))) if is_sat(f, solver_name=self.smt_solver): # we should actually check SAT for both (kx <= b) and (kx > b) break return LE(Times(Real(k), var), Real(b))
def test_examples(self): for n in self.all_solvers: with Solver(name=n) as solver: for (f, validity, satisfiability, logic) in \ get_example_formulae(): try: get_closer_logic(solver.LOGICS, logic) except NoLogicAvailableError: continue v = is_valid(f, solver_name=n, logic=logic) s = is_sat(f, solver_name=n, logic=logic) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f)
def test_examples_by_logic(self): for (f, validity, satisfiability, logic) in get_example_formulae(): if len(get_env().factory.all_solvers(logic=logic)) > 0: try: v = is_valid(f, logic=logic) s = is_sat(f, logic=logic) self.assertEqual(validity, v, f.serialize()) self.assertEqual(satisfiability, s, f.serialize()) except SolverReturnedUnknownResultError: s = Solver(logic=logic) print(s, logic, f) self.assertFalse(logic.quantifier_free, "Unkown result are accepted only on "\ "Quantified formulae")
def test_examples_cvc4(self): for (f, validity, satisfiability, logic) in get_example_formulae(): if not logic.theory.linear: continue if logic.theory.arrays_const: continue try: v = is_valid(f, solver_name='cvc4', logic=logic) s = is_sat(f, solver_name='cvc4', logic=logic) self.assertEqual(validity, v, f) self.assertEqual(satisfiability, s, f) except SolverReturnedUnknownResultError: # CVC4 does not handle quantifiers in a complete way self.assertFalse(logic.quantifier_free) except NoSolverAvailableError: # Logic is not supported by CVC4 pass
def check_property(system, prop): """Interleaves BMC and K-Ind to verify the property.""" print("Checking property %s..." % prop) for b in xrange(100): f = get_bmc(system, prop, b) print(" [BMC] Checking bound %d..." % (b+1)) if is_sat(f): print("--> Bug found at step %d" % (b+1)) return f = get_k_induction(system, prop, b) print(" [K-IND] Checking bound %d..." % (b+1)) if is_unsat(f): print("--> The system is safe!") return
def _smtlib_cnf(self, filename, logic, res_is_sat): reset_env() conv = CNFizer() smtfile = os.path.join(SMTLIB_DIR, filename) assert os.path.exists(smtfile) expr = get_formula_fname(smtfile) if not logic.quantifier_free: with self.assertRaises(NotImplementedError): conv.convert_as_formula(expr) return cnf = conv.convert_as_formula(expr) self.assertValid(Implies(cnf, expr), logic=logic) res = is_sat(cnf, logic=logic) self.assertEqual(res, res_is_sat)
def test_examples(self): for name in self.all_solvers: for example in get_example_formulae(): f = example.expr try: v = is_valid(f, solver_name=name) s = is_sat(f, solver_name=name) self.assertEqual(example.is_valid, v, f) self.assertEqual(example.is_sat, s, f) except NoSolverAvailableError: # The solver does not support the specified logic continue except UnknownSolverAnswerError: # MathSAT does not deal with UF with boolean args. # This is handled via the native API, but not via the # SMT-LIB Wrapper self.assertTrue(name == "mathsat.solver.sh", name)
def test_tactics_z3(self): from z3 import Tactic, Then from pysmt.shortcuts import Iff my_tactic = Then(Tactic('simplify'), Tactic('propagate-values'), Tactic('elim-uncnstr')) for (f, validity, satisfiability, logic) in get_example_formulae(): if not logic.theory.linear: continue if not logic.quantifier_free: continue if logic.theory.bit_vectors: continue s = Solver(name='z3') z3_f = s.converter.convert(f) simp_z3_f = my_tactic(z3_f) simp_f = s.converter.back(simp_z3_f.as_expr()) v = is_valid(simp_f) s = is_sat(simp_f) self.assertEqual(v, validity, (f, simp_f)) self.assertEqual(s, satisfiability, (f, simp_f))
And(ExactlyOne(color(i, c) for c in Color) for i in Houses), And(ExactlyOne(nat(i, c) for c in Nat) for i in Houses), And(ExactlyOne(pet(i, c) for c in Pet) for i in Houses), And(ExactlyOne(drink(i, c) for c in Drink) for i in Houses), And(ExactlyOne(smoke(i, c) for c in Smoke) for i in Houses), ) problem = And(domain, facts) model = get_model(problem) if model is None: print("UNSAT") # We first check whether the constraints on the domain and problem # are satisfiable in isolation. assert is_sat(facts) assert is_sat(domain) assert is_unsat(problem) # In isolation they are both fine, rules from both are probably # interacting. # # The problem is given by a nesting of And(). # conjunctive_partition can be used to obtain a "flat" # structure, i.e., a list of conjuncts. # from pysmt.rewritings import conjunctive_partition conj = conjunctive_partition(problem) ucore = get_unsat_core(conj) print("UNSAT-Core size '%d'" % len(ucore)) for f in ucore:
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())
from pysmt.shortcuts import And, Symbol, LE, GE, Int, Equals, Plus, Times, is_sat, get_model from pysmt.typing import INT 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]) sum_hello = Plus(hello) sum_world = Plus(world) problem = And(Equals(sum_hello, sum_world), Equals(sum_hello, Int(25))) formula = And(domains, problem) print("Serialization of the formula:") print(formula) print("Checking Satisfiability:") print(is_sat(formula))
# Checking satisfiability of a formula. # # This example shows: # 1. How to build a formula # 2. How to perform substitution # 3. Printing # 4. Satisfiability checking from pysmt.shortcuts import Symbol, And, Not, is_sat varA = Symbol("A") # Default type is Boolean varB = Symbol("B") f = And([varA, Not(varB)]) g = f.substitute({varB:varA}) res = is_sat(f) assert res # SAT print("f := %s is SAT? %s" % (f, res)) res = is_sat(g) print("g := %s is SAT? %s" % (g, res)) assert not res # UNSAT
# This example requires Z3 and MathSAT to be installed (but you can # replace MathSAT with any other solver for QF_LRA) # # This examples shows how to: # 1. Define Real valued constants using floats and fractions # 2. Perform quantifier elimination # 3. Pass results from one solver to another # from pysmt.shortcuts import Symbol, Or, ForAll, GE, LT, Real, Plus from pysmt.shortcuts import qelim, is_sat from pysmt.typing import REAL x, y, z = [Symbol(s, REAL) for s in "xyz"] f = ForAll([x], Or(LT(x, Real(5.0)), GE(Plus(x, y, z), Real((17,2))))) # (17,2) ~> 17/2 print("f := %s" % f) #f := (forall x . ((x < 5.0) | (17/2 <= (x + y + z)))) qf_f = qelim(f, solver_name="z3") print("Quantifier-Free equivalent: %s" % qf_f) #Quantifier-Free equivalent: (7/2 <= (z + y)) res = is_sat(qf_f, solver_name="msat") print("SAT check using MathSAT: %s" % res) #SAT check using MathSAT: True
# The first example shows how to use multiple solvers in the with the # is_sat shortcut # from pysmt.shortcuts import is_sat # We enable logging to see what is going on behind the scenes: import logging _info = logging.getLogger(__name__).info logging.basicConfig(level=logging.DEBUG) # A solver set is an iterable of solver names or pairs of # solvers+options (See next example) _info("Example 1: is_sat") solvers_set = ["z3", "yices", "msat"] res = is_sat(f, portfolio=solvers_set) assert res is True # Behind the scenes, pySMT launched 3 processes and solved the # expression in parallel. # # The is_sat shortcut is useful for prototyping and exploration, but # we typically need more control over the solver. The Portfolio class # behaves as a solver and as such implements most of the methods of a # regular solver. from pysmt.shortcuts import Portfolio from pysmt.logics import QF_UFLIRA # The options given to the Portfolio will be passed to all solvers, in # particular, we are enabling incrementality and model generation.