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 _helper_check_examples(self, solver_name): for (f, _, satisfiability, logic) in get_example_formulae(): if not logic.quantifier_free: continue if satisfiability == False: with UnsatCoreSolver(name=solver_name, unsat_cores_mode="named") as solver: if logic not in solver.LOGICS: continue clauses = [f] if f.is_and(): clauses = f.args() for i, c in enumerate(clauses): solver.add_assertion(c, "a%d" % i) try: r = solver.solve() self.assertFalse(r) except SolverReturnedUnknownResultError: if QF_BV <= logic: continue # Unsat-core support for QF_UFBV might be # incomplete else: raise core = solver.get_named_unsat_core() self.assertTrue(len(core) <= len(clauses)) for k in core.values(): self.assertIn(k, clauses) self.assertTrue(is_unsat(And(core.values()), logic=logic))
def _helper_check_examples(self, solver_name): for (f, _, satisfiability, logic) in get_example_formulae(): if not logic.quantifier_free: continue if satisfiability == False: with UnsatCoreSolver(name=solver_name, unsat_cores_mode="named") as solver: if logic not in solver.LOGICS: continue clauses = [f] if f.is_and(): clauses = f.args() for i,c in enumerate(clauses): solver.add_assertion(c, "a%d" % i) try: r = solver.solve() self.assertFalse(r) except SolverReturnedUnknownResultError: if QF_BV <= logic: continue # Unsat-core support for QF_UFBV might be # incomplete else: raise core = solver.get_named_unsat_core() self.assertTrue(len(core) <= len(clauses)) for k in core.values(): self.assertIn(k, clauses) self.assertTrue(is_unsat(And(core.values()), logic=logic))
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 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 generate_false_path(path_condition): false_path = None while path_condition.is_and(): constraint = path_condition.arg(1) constraint_str = str(constraint.serialize()) if "angelic!bool" in constraint_str: constraint = generate_false_constraint(constraint) elif false_path is None: return if false_path is None: false_path = constraint else: false_path = And(false_path, constraint) path_condition = path_condition.arg(0) false_path = And(false_path, path_condition) if is_unsat(false_path): false_path = None return false_path
def check_path_feasibility(chosen_control_loc, new_path, index): """ This function will check if a selected path is feasible ppc : partial path conditoin at chosen control loc chosen_control_loc: branch location selected for flip returns satisfiability of the negated path """ result = False if chosen_control_loc != values.CONF_LOC_PATCH: result = not is_unsat(new_path) else: result = is_sat(new_path) if result: return True, index else: emitter.data("Path is not satisfiable at " + str(chosen_control_loc), new_path) return False, index
def merge_space(partition_list, path_condition, specification): merged_space = get_sorted_space(partition_list) len_partition = len(merged_space) partition_id = 0 count_iteration = 0 if len_partition == 1: return partition_list while len_partition > 1: partition_a = merged_space[partition_id % len_partition] if not partition_a: merged_space.remove(partition_a) continue partition_b = merged_space[(partition_id + 1) % len_partition] merged_partition = merge_two_partitions(partition_a, partition_b) if merged_partition: dimension_list = list(merged_partition.keys()) dimension_name = dimension_list[0] if "const_" in dimension_name: partition_constraints = smt2.generate_constraint_for_patch_partition( merged_partition) else: partition_constraints = smt2.generate_constraint_for_input_partition( merged_partition) if is_unsat( And(partition_constraints, And(path_condition, Not(specification)))): insert_index = merged_space.index(partition_a) merged_space.remove(partition_a) merged_space.remove(partition_b) merged_space.insert(insert_index, merged_partition) len_partition = len(merged_space) count_iteration = 0 partition_id = (partition_id + 1) % len_partition if count_iteration == len_partition: break count_iteration = count_iteration + 1 return merged_space
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_bv(self): mgr = get_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(ValueError): # Negative numbers are not supported BV(-1, 10) with self.assertRaises(ValueError): # 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) #s_one = BV(-1, 32) bcustom = Symbol("bc", BVType(42)) self.assertIsNotNone(hexample) self.assertIsNotNone(bcustom) #self.assertIsNotNone(s_one) self.assertEqual(bcustom.bv_width(), 42) self.assertEqual(hexample.constant_value(), 16) #self.assertEqual(str(s_one), "-1_32") not_zero32 = mgr.BVNot(zero) not_b128 = mgr.BVNot(b128) f1 = Equals(not_zero32, b32) f2 = Equals(not_b128, big) #print(f1) #print(f2) self.assertTrue(is_sat(f1, logic=QF_BV)) self.assertTrue(is_sat(f2, logic=QF_BV)) zero_and_one = mgr.BVAnd(zero, one) zero_or_one = mgr.BVOr(zero, one) zero_xor_one = mgr.BVXor(zero, one) zero_xor_one.simplify() self.assertTrue(zero_xor_one.is_bv_op()) # print(zero_and_one) # print(zero_or_one) # print(zero_xor_one) 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(TypeError): 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(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))) #print(extraction) ult = mgr.BVULT(zero, one) neg = mgr.BVNeg(one) self.assertTrue(is_valid(ult, logic=QF_BV), ult) test_eq = Equals(neg, one) self.assertTrue(is_unsat(test_eq, logic=QF_BV)) # print(ult) # print(neg) f = zero addition = mgr.BVAdd(f, one) multiplication = mgr.BVMul(f, one) udiv = mgr.BVUDiv(f, one) 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) # print(addition) # print(multiplication) # print(udiv) three = mgr.BV(3, 32) two = mgr.BV(2, 32) reminder = mgr.BVURem(three, two) shift_l_a = mgr.BVLShl(one, one) 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))) # print(reminder) # print(shift_l_a) # print(shift_l_b) shift_r_a = mgr.BVLShr(one, one) shift_r_b = mgr.BVLShr(one, 1) self.assertEqual(shift_r_a, shift_r_b) self.assertTrue(is_valid(Equals(shift_r_a, zero))) rotate_l = mgr.BVRol(one, 3) rotate_r = mgr.BVRor(rotate_l, 3) self.assertTrue(is_valid(Equals(one, rotate_r))) # print(rotate_l) # print(rotate_r) zero_ext = mgr.BVZExt(one, 64) signed_ext = mgr.BVSExt(one, 64) 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)) # print(zero_ext) # print(signed_ext) 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(ValueError): mgr.SBV(2, 2) with self.assertRaises(ValueError): 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(ValueError): mgr.BV(4, 2) # No negative number allowed with self.assertRaises(ValueError): mgr.BV(-1, 2) # SBV should behave as BV for positive numbers self.assertEqual(mgr.SBV(10, 16), mgr.BV(10, 16)) return
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: print(f.serialize())
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: print(f.serialize())
def check_input_feasibility(index, patch_constraint, new_path): check_sat = And(new_path, patch_constraint) result = not is_unsat(check_sat) return result, index
def isUnsat(symbolicExpression): if isinstance(symbolicExpression, bool) or symbolicExpression.is_Boolean: return not symbolicExpression expression, type = Solver.getConvertedExpression(symbolicExpression) return pysmt.is_unsat(expression)