def tryAndVerifyWithSplitterPreds( fun: Function, old_sound_invs: Set[AstExpr], boogie_invs: Set[AstExpr], splitterPreds: List[AstExpr], partialInvs: List[AstExpr], timeout: Optional[int] = None) -> TryAndVerifyResult: """ Wrapper around tryAndVerify_impl that adds implication with the splitter predicates to all candidate invariants. Returns ((p1_overfit, p2_overfit), (p1_nonindg, p2_nonind), sound, violations) Where p1_overfit, p2_ovefit are lists of pairs of overfittted invariants and their respective counterexamples from passes 1 and 2 p1_nonind, p2_nonind are lists of pairs of noninductive invariants and their respective counterexamples from passes 1 and 2 sound is a set of sound invariants violations is a list of any safety violations permitted by the sound invariants """ initial_sound = old_sound_invs.union(partialInvs) boogieTypeEnv = fun.getTypeEnv() z3TypeEnv = boogieToZ3TypeEnv(boogieTypeEnv) # First lets find the invariants that are sound without implication p1_overfitted, p1_nonind, p1_sound, violations =\ tryAndVerify_impl(fun, initial_sound, boogie_invs, timeout) p1_sound = \ set([x for x in p1_sound \ if not conservative_tautology(expr_to_z3(x, z3TypeEnv))]) # Next lets add implication to all unsound invariants from first pass # Also add manually specified partialInvs unsound: List[AstExpr] = [ inv_ctr_pair[0] for inv_ctr_pair in p1_overfitted + p1_nonind ] candidate_precedents: List[AstExpr] = \ [ ast_and(pSet) for pSet in nonempty(powerset(splitterPreds)) ] p2_invs: List[AstExpr] = [ AstBinExpr(precc, "==>", inv) for precc in candidate_precedents for inv in unsound ] p2_invs += partialInvs p2_invs = \ list(set([ x for x in p2_invs \ if not conservative_tautology(expr_to_z3(x, z3TypeEnv)) ])) # And look for any new sound invariants p2_overfitted, p2_nonind, p2_sound, violations = \ tryAndVerify_impl(fun, p1_sound.union(set(partialInvs)), \ p2_invs, timeout) sound = p1_sound.union(p2_sound) return ((p1_overfitted, p2_overfitted), \ (p1_nonind, p2_nonind), \ sound, \ violations)
def equiv(boogie1, boogie2): [p1, p2] = [expr_to_z3(pred, AllIntTypeEnv()) for pred in [boogie1, boogie2]] solv = getSolver() solv.add(Not(p1 == p2)) res = solv.check() return res == unsat
def simplifyInv(inv: EsprimaNode, typeEnv: JSONTypeEnv, mturkId: MturkIdT) -> EsprimaNode: #pylint: disable=unused-argument """ Given an invariant inv return its 'simplified' version. We treat that as the canonical version of an invariant. Simplification is performed by z3 """ boogieEnv = jsonToTypeEnv(typeEnv) z3Env = boogieToZ3TypeEnv(boogieEnv) boogieInv = esprimaToBoogie(inv, {}) noDivBoogie = divisionToMul(boogieInv) z3_inv = expr_to_z3(noDivBoogie, z3Env) simpl_z3_inv = ccast(simplify(z3_inv, arith_lhs=True), z3.ExprRef) simpl_boogie_inv = z3_expr_to_boogie(simpl_z3_inv) return boogieToEsprima(simpl_boogie_inv)
exit(1) additionalInvs = {} if args.additionalInvs: with open(args.additionalInvs) as f: r = csv.reader(f, delimiter=",") for row in r: if not row: continue invs = [] for invstr in invlist.split(";"): if not len(invstr.strip()): continue try: inv = parseExprAst(invstr) if tautology(expr_to_z3(inv, AllIntTypeEnv())): print( "Dropping additional invariant (tautology): ", inv) continue except RuntimeError: # Some invariants are too large to parse print("Dropping additional invariant (parse): ", inv) continue except Unknown: # Timeouts could be valid invariants pass invs.append(inv) additionalInvs[lvlName] = invs print("ADDITIONAL INVARIANTS LOADED FOR LVLS:", \
if (endsWithNumP.match(lvl_name)): origName = justEnd.split(lvl_name)[0] originalToSplitM[origName] = originalToSplitM.get(origName, []) +\ [ lvl_name ] splitToOriginal[lvl_name] = origName print("Checking splitter predicates non-ovrelapping") for origName in list(originalToSplitM.keys()): # For now we assume each split level has a single splitterPred preds = [ unique(lvls[x]["splitterPreds"]) for x in originalToSplitM[origName] ] for i in range(0, len(preds)): for j in range(i+1, len(preds)): if (not unsatisfiable(expr_to_z3(bast.ast_and([preds[i], preds[j]]), AllIntTypeEnv()))): print("Predicates ", preds[i], "and", preds[j], "from split of ", \ origName, "are not independent") print("Checking conjunction of partial predicates is a solution") for origName in list(originalToSplitM.keys()): # For now we assume each split level has a single splitterPred preds = [ lvls[x]["partialInv"] for x in originalToSplitM[origName] ] if (len(preds) == 1): print("Skipping ", origName, "- only 1 split level (no other side of split)") continue conj = bast.ast_and(preds); lvl = lvls[originalToSplitM[origName][0]] try: (overfit, nonind, sound, violations) = verify(lvl, [conj]) if (not len(violations) == 0):