def equivalentPairs(invL1, invL2, mturkId): #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. """ z3InvL1 = [esprimaToZ3(x, {}) for x in invL1] z3InvL2 = [esprimaToZ3(x, {}) 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)) res = [(boogieToEsprima(z3_expr_to_boogie(x)), boogieToEsprima(z3_expr_to_boogie(y))) for (x, y) in res] return res
def impliedPairs(invL1, invL2, mturkId): #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 """ z3InvL1 = [esprimaToZ3(x, {}) for x in invL1] z3InvL2 = [esprimaToZ3(x, {}) 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)) res = [(boogieToEsprima(z3_expr_to_boogie(x)), boogieToEsprima(z3_expr_to_boogie(y))) for (x, y) in res] return res
def simplifyInv(inv, mturkId): #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 """ boogieInv = esprimaToBoogie(inv, {}) noDivBoogie = divisionToMul(boogieInv) z3_inv = expr_to_z3(noDivBoogie, AllIntTypeEnv()) print z3_inv, boogieInv simpl_z3_inv = simplify(z3_inv, arith_lhs=True) simpl_boogie_inv = z3_expr_to_boogie(simpl_z3_inv) return boogieToEsprima(simpl_boogie_inv)
def tryAndVerify(levelSet, levelId, invs, mturkId, individualMode): """ Given a level (levelSet, levelId) and a set of invaraints invs do: 1) Find all invariants OldI that were not DEFINITELY false from the last time we tried to verify this level (getLastVerResult) 2) Try and verify the level using S = OldI + invs. This is done by calling tryAndVerifyLvl. For more on that see comment in tryAndVerifyLvl 3) Return object containing: overfitted - all invariants in invs not implied by precondition nonind - all invariants in invs that are not inductive sound - all invariants in invs that are sound post_ctrex - any safety counterexamples to the "sound" invariants. If this set is empty, then the level is verified. direct_ctrex - any safety counterexamples to ALL of the passed in invs (not just the sound ones). This is used by the 'rounds' game mode to generate red rows for the next level. """ s = sessionF() if (levelSet not in traces): raise Exception("Unkonwn level set " + str(levelSet)) if (levelId not in traces[levelSet]): raise Exception("Unkonwn trace " + str(levelId) + \ " in levels " + str(levelSet)) if (len(invs) == 0): raise Exception("No invariants given") lvl = traces[levelSet][levelId] if ('program' not in lvl): # Not a boogie level - error raise Exception("Level " + str(levelId) + " " + \ str(levelSet) + " not a dynamic boogie level.") workerId, _, _ = mturkId print repr(set) userInvs = set([esprimaToBoogie(x, {}) for x in invs]) otherInvs = set([]) lastVer = getLastVerResult(levelSet, levelId, s, workerId=(workerId if individualMode else None)) if (lastVer): otherInvs = otherInvs.union( [parseExprAst(x) for x in lastVer["sound"]]) otherInvs = otherInvs.union( [parseExprAst(x) for x in lastVer["nonind"]]) ((overfitted, _), (nonind, _), sound, violations) =\ tryAndVerifyLvl(lvl, userInvs, otherInvs, args.timeout) # See if the level is solved solved = len(violations) == 0 fix = lambda x: _from_dict(lvl['variables'], x, 0) if (not solved): bbs = lvl["program"] loop = lvl["loop"] direct_ctrexs = loopInvSafetyCtrex(loop, otherInvs.union(userInvs),\ bbs, args.timeout) else: direct_ctrexs = [] # Convert all invariants from Boogie to esprima expressions, and # counterexamples to arrays # from dictionaries overfitted = [(boogieToEsprima(inv), fix(v.endEnv())) for (inv, v) in overfitted] nonind = [(boogieToEsprima(inv), (fix(v.startEnv()), fix(v.endEnv()))) for (inv, v) in nonind] sound = [boogieToEsprima(inv) for inv in sound] safety_ctrexs = [fix(v.startEnv()) for v in violations] direct_ctrexs = [fix(v) for v in direct_ctrexs] res = (overfitted, nonind, sound, safety_ctrexs, direct_ctrexs) payl = { "lvlset": levelSet, "lvlid": levelId, "overfitted": nodups([str(esprimaToBoogie(x[0], {})) for x in overfitted]), "nonind": nodups([str(esprimaToBoogie(inv, {})) for (inv, _) in nonind]), "sound": nodups([str(esprimaToBoogie(inv, {})) for inv in sound]), "post_ctrex": safety_ctrexs, "direct_ctrex": direct_ctrexs } addEvent("verifier", "VerifyAttempt", time(), args.ename, \ "localhost", payl, s, mturkId) return res
def loadLvl(levelSet, lvlId, mturkId, individualMode=False): #pylint: disable=unused-argument """ Load a given level. """ if (levelSet not in traces): raise Exception("Unkonwn level set " + levelSet) if (lvlId not in traces[levelSet]): raise Exception("Unkonwn trace " + lvlId + " in levels " + levelSet) lvl = traces[levelSet][lvlId] if ('program' in lvl): # This is a boogie level - don't return the program/loop and other book # keeping lvl = { 'lvlSet': levelSet, 'id': lvlId, 'variables': lvl['variables'], 'data': lvl['data'], 'exploration_state': lvl['exploration_state'], 'hint': lvl['hint'], 'goal': lvl['goal'], 'support_pos_ex': lvl['support_pos_ex'], 'support_neg_ex': lvl['support_neg_ex'], 'support_ind_ex': lvl['support_ind_ex'], 'multiround': lvl['multiround'], } if args.colSwap: nCols = len(lvl["variables"]) if nCols not in columnSwaps: raise Exception("No column swap for %d columns" % nCols) nSwaps = (nCols + 1) // 2 # swaps are 0 to nSwaps - 1 inclusive session = sessionF() colSwaps = [0] * nSwaps allInvs(session, enames=[args.ename], lvlsets=[curLevelSetName], lvls=[lvlId], colSwaps=colSwaps) sortKeys = colSwaps if individualMode: workerId = mturkId[0] colSwaps = [0] * nSwaps allInvs(session, enames=[args.ename], lvlsets=[curLevelSetName], lvls=[lvlId], workers=[workerId], colSwaps=colSwaps) sortKeys = zip(colSwaps, sortKeys) nSwap = sorted(zip(sortKeys, range(nSwaps)), key=lambda x: x[0])[0][1] lvl["colSwap"] = nSwap lvl["variables"] = swapColumns(lvl["variables"], nSwap) lvl["data"] = [[swapColumns(row, nSwap) for row in rows] for rows in lvl["data"]] lvl["startingInvs"] = [] if args.replay: # Only show players their own invariants, even if individual mode is off invs = allInvs(session, enames=[args.ename], lvlsets=[curLevelSetName], lvls=[lvlId], workers=[workerId]) lvl["startingInvs"] = [(inv[0], boogieToEsprima(parseExprAst(inv[1]))) for inv in invs] return lvl