def test_generalization3(self): root = RootCtx(args=[x, int_bag], state_vars=[]) ctx1 = UnderBinder(root, y, int_bag, RUNTIME_POOL) ctx2 = UnderBinder(ctx1, z, ESingleton(y).with_type(TBag(y.type)), RUNTIME_POOL) gen = ctx2.generalize({z}) assert gen is ctx2
def queries_equivalent(q1: Query, q2: Query, state_vars: [EVar], extern_funcs: {str: TFunc}, assumptions: Exp = ETRUE): """Determine whether two queries always return the same result. This function also checks that the two queries have semantically equivalent preconditions. Checking the preconditions is necessary to ensure semantic equivalence of the queries: a query object should be interpreted to mean "if my preconditions hold then I compute and return my body expression". If two queries do not have semantically equivalent preconditions, then there might be cases where one is obligated to return a value and the other has no defined behavior. """ with task("checking query equivalence", q1=q1.name, q2=q2.name): if q1.ret.type != q2.ret.type: return False q1args = dict(q1.args) q2args = dict(q2.args) if q1args != q2args: return False checker = solver_for_context(context=RootCtx( state_vars=state_vars, args=[EVar(a).with_type(t) for (a, t) in q1.args], funcs=extern_funcs), assumptions=assumptions) q1a = EAll(q1.assumptions) q2a = EAll(q2.assumptions) return checker.valid(EEq(q1a, q2a)) and checker.valid( EImplies(q1a, EEq(q1.ret, q2.ret)))
def test_enumerator_fingerprints(self): """ The enumerator should always give us fingerprints in the context we asked for. """ x = EVar("x").with_type(INT) ctx = RootCtx(args=(x, ), state_vars=()) enumerator = Enumerator(examples=[{ "x": 0 }, { "x": 1 }], cost_model=CostModel()) inner_ctx = UnderBinder( ctx, EVar("y").with_type(INT), EBinOp( ESingleton(ZERO).with_type(INT_BAG), "+", ESingleton(ONE).with_type(INT_BAG)).with_type(INT_BAG), RUNTIME_POOL) fingerprint_lens = set() for info in enumerator.enumerate_with_info(inner_ctx, 0, RUNTIME_POOL): fingerprint_lens.add(len(info.fingerprint)) print(info) assert len(fingerprint_lens) == 1, fingerprint_lens
def test_repair_regression01(self): e = EBinOp(EMapKeys(EMakeMap2(EVar('conns').with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), ELambda(EVar('_var17561').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), EBool(True).with_type(TBool()))).with_type(TMap(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))), TBool()))).with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), '-', EMapKeys(ELet(EUnaryOp('the', EMap(EFilter(EVar('conns').with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), ELambda(EVar('c').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), EBinOp(EGetField(EVar('c').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), 'conn_iface').with_type(TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), '==', EVar('i').with_type(TNative('mongo::executor::ConnectionPool::ConnectionInterface*'))).with_type(TBool()))).with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), ELambda(EVar('c').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), EVar('c').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))))).with_type(TList(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))))).with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), ELambda(EVar('c').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), EMakeMap2(EBinOp(EBinOp(EVar('conns').with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), '-', ESingleton(EVar('c').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))).with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))))).with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), '+', ESingleton(EMakeRecord((('conn_state', EEnumEntry('READY').with_type(TEnum(('READY', 'PROCESSING', 'CHECKED_OUT')))), ('conn_host', EGetField(EVar('c').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), 'conn_host').with_type(TNative('mongo::HostAndPort'))), ('conn_iface', EGetField(EVar('c').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), 'conn_iface').with_type(TNative('mongo::executor::ConnectionPool::ConnectionInterface*'))), ('conn_next_refresh', ECall('after', (EVar('lastUsed').with_type(TNative('mongo::Date_t')), EVar('refreshRequirement').with_type(TNative('mongo::Milliseconds')))).with_type(TNative('mongo::Date_t'))), ('conn_returned', EVar('now').with_type(TNative('mongo::Date_t'))), ('conn_last_used', EVar('retId').with_type(TInt())), ('conn_dropped', EGetField(EVar('c').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), 'conn_dropped').with_type(TBool())))).with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))).with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))))).with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), ELambda(EVar('_var17561').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), EBool(True).with_type(TBool()))).with_type(TMap(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))), TBool())))).with_type(TMap(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))), TBool()))).with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))))).with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))) context = RootCtx(state_vars=OrderedSet([EVar('minConnections').with_type(TInt()), EVar('maxConnections').with_type(TInt()), EVar('maxConnecting').with_type(TInt()), EVar('refreshTimeout').with_type(TNative('mongo::Milliseconds')), EVar('refreshRequirement').with_type(TNative('mongo::Milliseconds')), EVar('hostTimeout').with_type(TNative('mongo::Milliseconds')), EVar('conns').with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), EVar('reqs').with_type(TBag(TRecord((('rq_callback', TNative('mongo::executor::ConnectionPool::GetConnectionCallback*')), ('rq_expiration', TNative('mongo::Date_t')), ('rq_host', TNative('mongo::HostAndPort')))))), EVar('_idleHosts').with_type(TBag(TRecord((('host_id', TNative('mongo::HostAndPort')), ('host_timeout', TNative('mongo::Date_t')))))), EVar('retId').with_type(TInt())]), args=OrderedSet([EVar('i').with_type(TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), EVar('lastUsed').with_type(TNative('mongo::Date_t')), EVar('now').with_type(TNative('mongo::Date_t'))]), funcs=OrderedDict([('eternity', TFunc((), TNative('mongo::Date_t'))), ('after', TFunc((TNative('mongo::Date_t'), TNative('mongo::Milliseconds')), TNative('mongo::Date_t'))), ('nullConn', TFunc((), TNative('mongo::executor::ConnectionPool::ConnectionInterface*'))), ('nullReq', TFunc((), TNative('mongo::executor::ConnectionPool::GetConnectionCallback*')))])) assert not exp_wf(e, context=context, pool=RUNTIME_POOL) extra_state = [EVar('reqs').with_type(TBag(TRecord((('rq_callback', TNative('mongo::executor::ConnectionPool::GetConnectionCallback*')), ('rq_expiration', TNative('mongo::Date_t')), ('rq_host', TNative('mongo::HostAndPort')))))), EVar('conns').with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), EVar('hostTimeout').with_type(TNative('mongo::Milliseconds')), EVar('refreshRequirement').with_type(TNative('mongo::Milliseconds')), EVar('retId').with_type(TInt()), EMakeMap2(EVar('conns').with_type(TBag(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))))), ELambda(EVar('_var17561').with_type(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool())))), EBool(True).with_type(TBool()))).with_type(TMap(TRecord((('conn_state', TEnum(('READY', 'PROCESSING', 'CHECKED_OUT'))), ('conn_host', TNative('mongo::HostAndPort')), ('conn_iface', TNative('mongo::executor::ConnectionPool::ConnectionInterface*')), ('conn_next_refresh', TNative('mongo::Date_t')), ('conn_returned', TNative('mongo::Date_t')), ('conn_last_used', TInt()), ('conn_dropped', TBool()))), TBool()))] e_prime = repair_well_formedness(e, context, extra_state) assert exp_wf(e_prime, context=context, pool=RUNTIME_POOL)
def test_generalization2(self): root = RootCtx(args=[x, int_bag], state_vars=[]) ctx1 = UnderBinder(root, y, int_bag, RUNTIME_POOL) ctx2 = UnderBinder(ctx1, z, int_bag, RUNTIME_POOL) gen = ctx2.generalize({z}) assert gen is not ctx2 assert gen == UnderBinder(root, z, int_bag, RUNTIME_POOL)
def test_heap_wf(self): e = EHeapPeek2(EStateVar(EMakeMinHeap(EVar('xs'), ELambda(EVar('_var21501'), EVar('_var21501'))))) assert retypecheck(e, env={ "xs": INT_BAG, "_var21501": INT}) state_vars = OrderedSet([EVar('xs').with_type(TBag(TInt()))]) args = OrderedSet([EVar('x').with_type(TInt())]) pool = RUNTIME_POOL assert exp_wf(e, context=RootCtx(args=args, state_vars=state_vars), pool=pool)
def test_replace_different_typed_numeric_literal(self): f = ELambda(x, x) e = ENum(1.0).with_type(FLOAT) needle = ENum(1).with_type(INT) replacement = ENum(0).with_type(INT) ctx = RootCtx(args=(), state_vars=()) res = replace(e, ctx, RUNTIME_POOL, needle, ctx, RUNTIME_POOL, replacement) assert res == e assert res.type == FLOAT
def test_mutate_preserves_statevar(self): x = EVar("x").with_type(INT) e = EBinOp(EStateVar(x), "+", ONE) assert retypecheck(e) s = SAssign(x, EBinOp(x, "+", ONE).with_type(INT)) e2 = strip_EStateVar(inc.mutate(e, s)) e2 = repair_well_formedness(e2, context=RootCtx(state_vars=[x], args=[])) print(pprint(e)) print(pprint(e2)) assert e2 == EBinOp(EBinOp(EStateVar(x), "+", ONE), "+", ONE)
def test_let(self): e1 = ELet(ZERO, ELambda(x, x)) root_ctx = RootCtx(args=(), state_vars=()) assert retypecheck(e1) n = 0 for ee, ctx, pool in shred(e1, root_ctx, RUNTIME_POOL): if ee == x: e2 = replace(e1, root_ctx, RUNTIME_POOL, x, ctx, pool, ZERO) assert e2 == ELet(ZERO, ELambda(x, ZERO)) n += 1 assert n == 1
def test_heap_enumeration(self): xs = EVar("xs").with_type(INT_BAG) context = RootCtx(state_vars=[xs]) cost_model = CostModel() def not_min_or_max(e, *args, **kwargs): # forbid min/max to ensure that heap operations get cached if isinstance(e, EArgMin) or isinstance(e, EArgMax): return False return True enumerator = Enumerator(examples=[{ "xs": Bag(()) }, { "xs": Bag((1, 2)) }, { "xs": Bag((1, 1)) }], cost_model=cost_model, check_wf=not_min_or_max) with save_property(accelerate, "value"): accelerate.value = False print("-" * 20 + " Looking for xs...") found_xs = False for e in enumerator.enumerate(context, 0, STATE_POOL): print(pprint(e)) if e == xs: assert retypecheck(deep_copy(e)) found_xs = True print("^^^ FOUND") assert found_xs print("-" * 20 + " Looking for heap construction...") found_make_heap = False for e in enumerator.enumerate(context, 1, STATE_POOL): print(pprint(e)) if isinstance(e, EMakeMinHeap) or isinstance(e, EMakeMaxHeap): assert retypecheck(deep_copy(e)) found_make_heap = True print("^^^ FOUND") assert found_make_heap print("-" * 20 + " Looking for heap usage...") found_heap_peek = False for e in enumerator.enumerate(context, 2, RUNTIME_POOL): print(pprint(e)) if isinstance(e, EHeapPeek) or isinstance(e, EHeapPeek2): assert retypecheck(deep_copy(e)) found_heap_peek = True print("^^^ FOUND") assert found_heap_peek
def run(self): print("STARTING IMPROVEMENT JOB {}".format(self.q.name)) os.makedirs(log_dir.value, exist_ok=True) with open(os.path.join(log_dir.value, "{}.log".format(self.q.name)), "w", buffering=LINE_BUFFER_MODE) as f: sys.stdout = f print("STARTING IMPROVEMENT JOB {}".format(self.q.name)) print(pprint(self.q)) if nice_children.value: os.nice(20) ctx = RootCtx( state_vars=self.state, args=[EVar(v).with_type(t) for (v, t) in self.q.args], funcs=self.funcs) cost_model = CostModel(funcs=ctx.funcs(), assumptions=EAll(self.assumptions), freebies=self.freebies, ops=self.ops) try: for expr in itertools.chain( (self.q.ret, ), core.improve(target=self.q.ret, assumptions=EAll(self.assumptions), context=ctx, hints=self.hints, stop_callback=lambda: self.stop_requested, cost_model=cost_model, ops=self.ops)): new_rep, new_ret = unpack_representation(expr) self.k(new_rep, new_ret) print("PROVED OPTIMALITY FOR {}".format(self.q.name)) except core.StopException: print("stopping synthesis of {}".format(self.q.name)) return
def test_estatevar_ctx(self): xs = EVar("xs").with_type(INT_BAG) x = EVar("x").with_type(INT) y = EVar("y").with_type(BOOL) e = EMap(xs, ELambda(x, EStateVar(y))) ctx = RootCtx(args=(xs, ), state_vars=(y, )) assert retypecheck(e) for ee, ctx, pool in shred(e, ctx): if ee == y: assert isinstance(ctx, RootCtx) e = replace(e, ctx, RUNTIME_POOL, y, ctx, STATE_POOL, T) assert e == EMap(xs, ELambda(x, EStateVar(T))), pprint(e)
def test_hint_instantation(self): x = EVar("x").with_type(INT) y = EVar("y").with_type(INT) z = EVar("z").with_type(INT) hint = ECall("f", (x, )).with_type(INT) context = UnderBinder(RootCtx(args=[x]), v=y, bag=ESingleton(x).with_type(TBag(x.type)), bag_pool=RUNTIME_POOL) cost_model = CostModel() f = lambda a: a + 1 enumerator = Enumerator(examples=[{ "x": 1, "f": f }, { "x": 100, "f": f }], hints=[(hint, context, RUNTIME_POOL)], cost_model=cost_model) results = [] for ctx in (context, context.parent(), UnderBinder(context, v=z, bag=ESingleton(y).with_type(TBag(y.type)), bag_pool=RUNTIME_POOL), UnderBinder(context.parent(), v=z, bag=ESingleton(x).with_type(TBag(y.type)), bag_pool=RUNTIME_POOL), UnderBinder(context.parent(), v=y, bag=ESingleton(ONE).with_type(INT_BAG), bag_pool=RUNTIME_POOL)): print("-" * 30) found = False for e in enumerator.enumerate(ctx, 0, RUNTIME_POOL): print(" -> {}".format(pprint(e))) found = found or alpha_equivalent(e, hint) print("found? {}".format(found)) results.append(found) assert all(results)
def check_discovery(spec, expected, state_vars=[], args=[], examples=[], assumptions=ETRUE): ctx = RootCtx(state_vars=state_vars, args=args) for r in improve(spec, assumptions=assumptions, context=ctx, examples=examples): print("GOT RESULT ==> {}".format(pprint(r))) if isinstance(expected, Exp): if alpha_equivalent(r, expected): return True elif expected(r): return True return False
def test_state_pool_boundary(self): """ When enumerating expressions, we shouldn't ever enumerate state expressions in a context where some binders are runtime variables. """ class TestEnumerator(Enumerator): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.state_enumerations = 0 def _enumerate_core(self, context, size, pool): print("_enumerate_core({}, {}, {})".format( context, size, pool)) if pool == STATE_POOL: self.state_enumerations += 1 return super()._enumerate_core(context, size, pool) state_bag = EVar("state").with_type(INT_BAG) context = RootCtx(state_vars=[state_bag], args=[EVar("arg").with_type(INT)]) enumerator = TestEnumerator(examples=[{ "state": Bag([10]), "arg": 10 }, { "state": Bag([20]), "arg": 30 }], cost_model=CostModel()) for e in enumerator.enumerate(context, 1, RUNTIME_POOL): pass for e in enumerator.enumerate( UnderBinder(context, EVar("x").with_type(INT), EStateVar(state_bag).with_type(state_bag.type), RUNTIME_POOL), 1, RUNTIME_POOL): pass assert enumerator.state_enumerations == 1
def test_pool_affects_alpha_equivalence(self): e = EMap(EEmptyList().with_type(INT_BAG), ELambda(x, ONE)) root_ctx = RootCtx(args=(), state_vars=()) assert retypecheck(e) c1 = [] for ee, ctx, pool in shred(e, root_ctx, RUNTIME_POOL): if ee == ONE: c1.append(ctx) assert len(c1) == 1 c1 = c1[0] c2 = [] for ee, ctx, pool in shred(e, root_ctx, STATE_POOL): if ee == ONE: c2.append(ctx) assert len(c2) == 1 c2 = c2[0] assert c1 != c2 assert not c1.alpha_equivalent(c2)
def test_shred_minheap(self): f = ELambda(x, x) e = EMakeMinHeap(EEmptyList().with_type(INT_BAG), f).with_type(TMinHeap(INT, f)) ctx = RootCtx(args=(), state_vars=()) list(shred(e, ctx))
def context_for_method(self, m: Method) -> Context: """Construct a context describing expressions in the given method.""" return RootCtx(state_vars=self.abstract_state, args=[EVar(a).with_type(t) for (a, t) in m.args], funcs=self.extern_funcs)
def test_generalization1(self): root = RootCtx(args=[x, int_bag], state_vars=[]) ctx = UnderBinder(root, y, int_bag, RUNTIME_POOL) assert ctx.generalize({x}) is root