def equivalentPairs( invL1: List[EsprimaNode], invL2: List[EsprimaNode], typeEnv: JSONTypeEnv, mturkId: MturkIdT ) -> List[Tuple[EsprimaNode, EsprimaNode]]: #pylint: disable=unused-argument """ Given lists of invariants invL1, invL2, return all pairs (I1, I2) where I1 <==> I2, I1 \in invL1, I2 \in invL2 Not currently in use. """ boogieEnv: BoogieTypeEnv = jsonToTypeEnv(typeEnv) z3Env: Z3TypeEnv = boogieToZ3TypeEnv(boogieEnv) z3InvL1 = [esprimaToZ3(x, z3Env) for x in invL1] z3InvL2 = [esprimaToZ3(x, z3Env) for x in invL2] res = [] for x in z3InvL1: for y in z3InvL2: try: equiv = equivalent(x, y) except Unknown: equiv = False # Conservative assumption if (equiv): res.append((x, y)) return [(boogieToEsprima(z3_expr_to_boogie(x)), boogieToEsprima(z3_expr_to_boogie(y))) for (x, y) in res]
def impliedPairs( invL1: List[EsprimaNode], invL2: List[EsprimaNode], typeEnv: JSONTypeEnv, mturkId: MturkIdT ) -> List[Tuple[EsprimaNode, EsprimaNode]]: #pylint: disable=unused-argument """ Given lists of invariants invL1, invL2, return all pairs (I1, I2) where I1 ==> I2, I1 \in invL1, I2 \in invL2 Used by game.html """ boogieEnv = jsonToTypeEnv(typeEnv) z3Env = boogieToZ3TypeEnv(boogieEnv) z3InvL1 = [esprimaToZ3(x, z3Env) for x in invL1] z3InvL2 = [esprimaToZ3(x, z3Env) for x in invL2] res = [] for x in z3InvL1: for y in z3InvL2: try: impl = implies(x, y) except Unknown: impl = False # Conservative assumption if (impl): res.append((x, y)) return [(boogieToEsprima(z3_expr_to_boogie(x)), boogieToEsprima(z3_expr_to_boogie(y))) for (x, y) in res]
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 isTautology(inv: EsprimaNode, typeEnv: JSONTypeEnv, mturkId: MturkIdT): #pylint: disable=unused-argument """ Check whether the invariant inv is a tautology. Used by game.html """ boogieEnv = jsonToTypeEnv(typeEnv) z3Env = boogieToZ3TypeEnv(boogieEnv) try: res = (tautology(esprimaToZ3(inv, z3Env))) return res except Unknown: return False # Conservative assumption
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)