def test_strictrewriter(self): tree = L.p(''' S.add(1) S.remove(2) o.f = v del o.g m.assignkey(k, v) m.delkey(j) ''') tree = StrictUpdateRewriter.run(tree) exp_tree = L.p(''' if (1 not in S): S.add(1) if (2 in S): S.remove(2) if hasattr(o, 'f'): del o.f o.f = v if hasattr(o, 'g'): del o.g if (k in m): m.delkey(k) m.assignkey(k, v) if (j in m): m.delkey(j) ''') self.assertEqual(tree, exp_tree)
def test_inc_relmatch(self): spec = AuxmapSpec('R', Mask('bu')) tree = L.p(''' R.add((1, 2)) print(setmatch(R, 'bu', 1)) ''') tree = inc_relmatch(tree, self.manager, spec) exp_tree = L.p(''' _m_R_out = Map() def _maint__m_R_out_add(_e): (v1_1, v1_2) = _e if (v1_1 not in _m_R_out): _m_R_out.assignkey(v1_1, set()) _m_R_out[v1_1].add(v1_2) def _maint__m_R_out_remove(_e): (v2_1, v2_2) = _e _m_R_out[v2_1].remove(v2_2) if _m_R_out[v2_1].isempty(): _m_R_out.delkey(v2_1) with MAINT(_m_R_out, 'after', 'R.add((1, 2))'): R.add((1, 2)) _maint__m_R_out_add((1, 2)) print(_m_R_out.imglookup(1)) ''') self.assertEqual(tree, exp_tree)
def test_update_topair(self): tree = L.p(''' x.add(y) T.add(x) o.foo = 4 print(o.foo) del o.foo o.bar = 5 m.assignkey(k, v) m.delkey(k) ''') tree = UpdateToPairTransformer.run(tree, True, {'foo'}, True, ['T']) exp_use_mset = True exp_fields = {'foo', 'bar'} exp_use_maprel = True exp_tree = L.p(''' _M = MSet() _F_foo = FSet() _MAP = MAPSet() _M.add((x, y)) T.add(x) _F_foo.add((o, 4)) print(o.foo) _F_foo.remove((o, o.foo)) o.bar = 5 _MAP.add((m, k, v)) _MAP.remove((m, k, m[k])) ''') self.assertEqual(tree, exp_tree)
def test_updaterewriter(self): tree = L.p(''' R.add((x, y)) S.remove((o.f, v)) T.add(z) T.remove((3 + 5, 4)) U.add(foo(x)) M.assignkey(k, v.g) M.assignkey(o.f, v.g) M.delkey(o.f) o.f.add(x) ''') tree = UpdateRewriter.run(tree, self.manager.namegen) exp_tree = L.p(''' R.add((x, y)) v1 = (o.f, v) S.remove(v1) T.add(z) T.remove((3 + 5, 4)) v2 = foo(x) U.add(v2) v3 = v.g M.assignkey(k, v3) v4 = o.f v5 = v.g M.assignkey(v4, v5) v6 = o.f M.delkey(v6) v7 = o.f v7.add(x) ''') self.assertEqual(tree, exp_tree)
def test_transform(self): comp = L.pe('COMP({z for (x, y) in R for (y, z) in S}, [x], ' '{"impl": "inc"})') tree = L.p(''' R.add(1) print(COMP) ''', subst={'COMP': comp}) tree = transform_all_queries(tree, self.manager) tree = L.elim_deadfuncs(tree, lambda n: n.startswith('_maint_')) exp_tree = L.p(''' Comp1 = RCSet() def _maint_Comp1_R_add(_e): Comment("Iterate {(v1_x, v1_y, v1_z) : (v1_x, v1_y) in deltamatch(R, 'bb', _e, 1), (v1_y, v1_z) in S}") (v1_x, v1_y) = _e for v1_z in setmatch(S, 'bu', v1_y): if ((v1_x, v1_z) not in Comp1): Comp1.add((v1_x, v1_z)) else: Comp1.incref((v1_x, v1_z)) with MAINT(Comp1, 'after', 'R.add(1)'): R.add(1) _maint_Comp1_R_add(1) print(setmatch(Comp1, 'bu', x)) ''') self.assertEqual(tree, exp_tree)
def test_filter_comps(self): join = self.make_join( 'for (a, b) in R for (b, c) in S for (c, d) in _M') comp1 = L.pe( 'COMP({(a, b, c, d) for (a, b) in deltamatch(S, "bb", e, 1) for (b, c) in S for (c, d) in _M}, ' '[], {})') comp2 = L.pe( 'COMP({(a, b, c, d) for (a, b) in R for (b, c) in S for (c, d) in deltamatch(_M, "bb", e, 1)}, ' '[], {})') tree = L.p(''' print(COMP1) print(COMP2) ''', subst={'COMP1': comp1, 'COMP2': comp2}) ds = make_structures(join.clauses, 'Q', singletag=False, subdem_tags=True) tree, ds = filter_comps(tree, CF, ds, [comp1, comp2], True, augmented=False, subdem_tags=True) struct_names = [s.name for s in ds.tags + ds.filters + ds.usets] exp_tree = L.p(''' print(COMP({(a, b, c, d) for (a, b) in deltamatch(S, 'bb', e, 1) for (b, c) in Q_dS for (c, d) in _M}, [], {})) print(COMP({(a, b, c, d) for (a, b) in R for (b, c) in Q_dS for (c, d) in deltamatch(Q_d_M, 'bb', e, 1) for (c, d) in Q_d_M}, [], {})) ''') exp_struct_names = ['Q_Tb1', 'Q_dS', 'Q_Tc', 'Q_d_M'] self.assertEqual(tree, exp_tree) self.assertCountEqual(struct_names, exp_struct_names)
def test_arityfinder(self): comp1 = L.pe('COMP({x for x in S}, [], {})') comp2 = L.pe('COMP({y for y in C1}, [], {})', subst={'C1': comp1}) tree = L.p(''' print(C2) ''', subst={'C2': comp2}) arity = SubqueryArityFinder.run(tree, comp1) self.assertEqual(arity, 1) comp3 = L.pe('COMP({(x, x) for x in S}, [], {})') comp4 = L.pe('COMP({z for (z, z) in C3}, [], {})', subst={'C3': comp3}) tree = L.p(''' print(C4, C4) ''', subst={'C4': comp4}) arity = SubqueryArityFinder.run(tree, comp3) self.assertEqual(arity, 2) comp5 = L.pe('COMP({z for (z, z) in C1}, [], {})', subst={'C1': comp1}) tree = L.p(''' print(C5) ''', subst={'C5': comp5}) arity = SubqueryArityFinder.run(tree, comp1) self.assertEqual(arity, False) tree = L.p(''' print(C2, C1) ''', subst={'C2': comp2, 'C1': comp1}) arity = SubqueryArityFinder.run(tree, comp1) self.assertEqual(arity, False)
def test_deltamatch(self): code = L.p('deltamatch(R, "bbw", e, 1)') code = DeltaMatchRewriter.run(code) exp_code = L.p(''' ({e} if (setmatch(R, 'bbw', (e[0], e[1])).getref(()) == 1) else {}) ''') self.assertEqual(code, exp_code)
def test_minmax(self): tree = L.p(''' max({1} | {x for x in R} | S) max({1} & {1, 2}) ''') tree = MinMaxRewriter.run(tree) exp_tree = L.p(''' max2(max2(1), max({x for x in R}), max(S)) max({1} & {1, 2}) ''') self.assertEqual(tree, exp_tree)
def test_updateflattener(self): tree = L.p(''' R.add((1, (2, 3))) ''') tree = UpdateFlattener.run(tree, 'R', self.tuptype, self.manager.namegen) exp_tree = L.p(''' _tv1 = (1, (2, 3)) _ftv1 = (_tv1[0], _tv1[1][0], _tv1[1][1]) R.add(_ftv1) ''') self.assertEqual(tree, exp_tree)
def test_flatten_tuples(self): tree = L.p(''' print(COMP({(a, c) for (a, (b, c)) in R}, [], {})) ''') tree = flatten_tuples(tree) exp_tree = L.p(''' print(COMP({(a, c) for (a, _tup1) in R for (_tup1, b, c) in _TUP2}, [], {})) ''') self.assertEqual(tree, exp_tree)
def test_macroupdaterewriter(self): tree = L.p(''' A.update(B) A.intersection_update(B) A.difference_update(B) A.symmetric_difference_update(B) A.assign_update(B) A.clear() A.mapassign_update(B) A.mapclear() ''') tree = MacroUpdateRewriter.run(tree) exp_tree = L.p(''' for _upelem in B: if (_upelem not in A): A.add(_upelem) for _upelem in list(A): if (_upelem not in B): A.remove(_upelem) for _upelem in list(B): if (_upelem in A): A.remove(_upelem) for _upelem in list(B): if (_upelem in A): A.remove(_upelem) else: A.add(_upelem) if A is not B: while (len(A) > 0): _upelem = next(iter(A)) A.remove(_upelem) for _upelem in B: A.add(_upelem) while (len(A) > 0): _upelem = next(iter(A)) A.remove(_upelem) if (A is not B): while (len(A) > 0): _upkey = next(iter(A)) A.delkey(_upkey) for (_upkey, _upval) in B.items(): A.assignkey(_upkey, _upval) while (len(A) > 0): _upkey = next(iter(A)) A.delkey(_upkey) ''') self.assertEqual(tree, exp_tree)
def test_aggr(self): tree = L.p(''' print(sum(x, {})) print(sum(o.f, {})) print(sum(o[a.b].f, {})) ''') tree = AggregatePreprocessor.run(tree) exp_tree = L.p(''' print(sum(COMP({_e for _e in x}, [x], {}), {})) print(sum(COMP({_e for _e in o.f}, [o], {}), {})) print(sum(COMP({_e for _e in o[a.b].f}, [o, a], {}), {})) ''') self.assertEqual(tree, exp_tree)
def transform_source(source, *, nopts=None, qopts=None): """Like transform_ast, but from source code to source code.""" tree = L.p(source) tree, manager = transform_ast(tree, nopts=nopts, qopts=qopts) result = L.ts(tree) manager.stats['lines'] = get_loc_source(result) return result, manager
def test_flatten(self): ST, TT, OT = L.SetType, L.TupleType, L.ObjType self.manager.vartypes = {'R': ST(TT([OT('A'), TT([OT('B'), OT('C')])]))} code = L.p(''' R.add((1, (2, 3))) print(COMP({x for x in S for (x, (y, z)) in R}, [], {})) ''') code = flatten_relations(code, ['R'], self.manager) exp_code = L.p(''' _tv1 = (1, (2, 3)) _ftv1 = (_tv1[0], _tv1[1][0], _tv1[1][1]) R.add(_ftv1) print(COMP({x for x in S for (x, y, z) in R}, [], {})) ''') exp_vartypes = {'R': ST(TT([OT('A'), OT('B'), OT('C')]))} self.assertEqual(code, exp_code) self.assertEqual(self.manager.vartypes, exp_vartypes)
def test_flatten(self): ST, TT, OT = L.SetType, L.TupleType, L.ObjType self.manager.vartypes = { 'R': ST(TT([OT('A'), TT([OT('B'), OT('C')])])) } code = L.p(''' R.add((1, (2, 3))) print(COMP({x for x in S for (x, (y, z)) in R}, [], {})) ''') code = flatten_relations(code, ['R'], self.manager) exp_code = L.p(''' _tv1 = (1, (2, 3)) _ftv1 = (_tv1[0], _tv1[1][0], _tv1[1][1]) R.add(_ftv1) print(COMP({x for x in S for (x, y, z) in R}, [], {})) ''') exp_vartypes = {'R': ST(TT([OT('A'), OT('B'), OT('C')]))} self.assertEqual(code, exp_code) self.assertEqual(self.manager.vartypes, exp_vartypes)
def test_preprocess(self): tree = L.p(''' x = 1 {y for (x, y) in R} COMP({y for (x, y) in R}, [y], {'impl': 'auxonly'}) ''') given_opts = ({'obj_domain': False}, {'{y for (x, y) in R}': {'impl': 'inc'}}) tree, opman = preprocess_tree( self.manager, tree, given_opts) exp_tree = L.p(''' x = 1 COMP({y for (x, y) in R}, [x], {'impl': 'inc'}) COMP({y for (x, y) in R}, [y], {'impl': 'auxonly'}) ''') exp_nopts = {'obj_domain': False} self.assertEqual(tree, exp_tree) self.assertEqual(opman.nopts, exp_nopts)
def test_relationfinder(self): tree = L.p(''' R = incoq.runtime.Set() S = set() T = 5 ''') res = RelationFinder.run(tree) exp_res = ['R', 'S'] self.assertCountEqual(res, exp_res) tree = L.p(''' R = Set() S = Set() T = Set() for x in R: S.add({(x, y) for y in R}) print(T) ''') res = RelationFinder.run(tree) exp_res = ['R', 'S'] self.assertCountEqual(res, exp_res)
def test_inc_relcomp_noparams(self): comp = L.pe('COMP({(x, y) for (x, y) in S}, [], {})') tree = L.p(''' S.add((1, 2)) print(COMP) ''', subst={'COMP': comp}) tree = inc_relcomp(tree, self.manager, comp, 'Q') exp_tree = L.p(''' Q = RCSet() def _maint_Q_S_add(_e): for (v1_x, v1_y) in COMP({(v1_x, v1_y) for (v1_x, v1_y) in deltamatch(S, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v1_x, v1_y)', '_deltaop': 'add', '_deltarel': 'S', 'impl': 'auxonly'}): Q.add((v1_x, v1_y)) def _maint_Q_S_remove(_e): for (v2_x, v2_y) in COMP({(v2_x, v2_y) for (v2_x, v2_y) in deltamatch(S, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v2_x, v2_y)', '_deltaop': 'remove', '_deltarel': 'S', 'impl': 'auxonly'}): Q.remove((v2_x, v2_y)) with MAINT(Q, 'after', 'S.add((1, 2))'): S.add((1, 2)) _maint_Q_S_add((1, 2)) print(Q) ''') self.assertEqual(tree, exp_tree)
def test_deadcode(self): tree = L.p(''' A = Set() B = Set() C = Set() for x in A: B.add(y) C.add(z) print(C) ''') tree = eliminate_deadcode(tree, obj_domain_out=True) exp_tree = L.p(''' A = Set() pass C = Set() for x in A: pass C.add(z) print(C) ''') self.assertEqual(tree, exp_tree)
def test_auxonly_relcomp(self): comp1 = L.pe('COMP({(y, z) for (x, y) in R for (y, z) in S}, [x], {})') comp2 = L.pe('COMP({z for (x, y) in R for (y, z) in S}, [x], {})') tree = L.p(''' R.add((1, 2)) for (y, z) in COMP1: pass for z in COMP2: pass ''', subst={ 'COMP1': comp1, 'COMP2': comp2 }) tree = impl_auxonly_relcomp(tree, self.manager, comp1, 'Q1') tree = impl_auxonly_relcomp(tree, self.manager, comp2, 'Q2') exp_tree = L.p(''' def query_Q2(x): 'x -> {z : (x, y) in R, (y, z) in S}' result = set() for y in setmatch(R, 'bu', x): for z in setmatch(S, 'bu', y): if (z not in result): result.add(z) return result R.add((1, 2)) Comment('Iterate x -> {(y, z) : (x, y) in R, (y, z) in S}') for y in setmatch(R, 'bu', x): for z in setmatch(S, 'bu', y): pass for z in query_Q2(x): pass ''') self.assertEqual(tree, exp_tree)
def test_update_toobj(self): tree = L.p(''' _M = MSet() _F_foo = FSet() _M.add((x, y)) _F_foo.remove((o, o.foo)) _M.add(w) _F_foo.add(w) _MAP.add((m, k, v)) _MAP.remove(z) ''') tree = UpdateToObjTransformer.run(tree, self.manager.namegen) exp_tree = L.p(''' x.add(y) del o.foo v1_cont, v1_item = w v1_cont.add(v1_item) v2_cont, v2_item = w v2_cont.foo = v2_item m[k] = v v3_map, v3_key, v3_value = z del v3_map[v3_key] ''') self.assertEqual(tree, exp_tree)
def test_auxonly_relcomp(self): comp1 = L.pe( 'COMP({(y, z) for (x, y) in R for (y, z) in S}, [x], {})') comp2 = L.pe( 'COMP({z for (x, y) in R for (y, z) in S}, [x], {})') tree = L.p(''' R.add((1, 2)) for (y, z) in COMP1: pass for z in COMP2: pass ''', subst={'COMP1': comp1, 'COMP2': comp2}) tree = impl_auxonly_relcomp(tree, self.manager, comp1, 'Q1') tree = impl_auxonly_relcomp(tree, self.manager, comp2, 'Q2') exp_tree = L.p(''' def query_Q2(x): 'x -> {z : (x, y) in R, (y, z) in S}' result = set() for y in setmatch(R, 'bu', x): for z in setmatch(S, 'bu', y): if (z not in result): result.add(z) return result R.add((1, 2)) Comment('Iterate x -> {(y, z) : (x, y) in R, (y, z) in S}') for y in setmatch(R, 'bu', x): for z in setmatch(S, 'bu', y): pass for z in query_Q2(x): pass ''') self.assertEqual(tree, exp_tree)
def test_pairdomain(self): tree = L.p(''' S.add(o) T.add(o) o.a = 5 print(COMP({x.a.b[c] for x in S if x in T}, [S, T], {})) ''') tree = to_pairdomain(tree, self.manager, ['T']) exp_tree = L.p(''' _M = MSet() _F_a = FSet() _F_b = FSet() _MAP = MAPSet() _M.add((S, o)) T.add(o) _F_a.add((o, 5)) print(COMP({m_x_a_b_k_c for (S, x) in _M if x in T for (x, x_a) in _F_a for (x_a, x_a_b) in _F_b for (x_a_b, c, m_x_a_b_k_c) in _MAP}, [S, T], {})) ''') self.assertEqual(tree, exp_tree) tree = to_objdomain(tree, self.manager) exp_tree = L.p(''' S.add(o) T.add(o) o.a = 5 print(COMP({x.a.b[c] for x in S if x in T}, [S, T], {})) ''') self.assertEqual(tree, exp_tree)
def test_arityfinder(self): comp1 = L.pe('COMP({x for x in S}, [], {})') comp2 = L.pe('COMP({y for y in C1}, [], {})', subst={'C1': comp1}) tree = L.p(''' print(C2) ''', subst={'C2': comp2}) arity = SubqueryArityFinder.run(tree, comp1) self.assertEqual(arity, 1) comp3 = L.pe('COMP({(x, x) for x in S}, [], {})') comp4 = L.pe('COMP({z for (z, z) in C3}, [], {})', subst={'C3': comp3}) tree = L.p(''' print(C4, C4) ''', subst={'C4': comp4}) arity = SubqueryArityFinder.run(tree, comp3) self.assertEqual(arity, 2) comp5 = L.pe('COMP({z for (z, z) in C1}, [], {})', subst={'C1': comp1}) tree = L.p(''' print(C5) ''', subst={'C5': comp5}) arity = SubqueryArityFinder.run(tree, comp1) self.assertEqual(arity, False) tree = L.p(''' print(C2, C1) ''', subst={ 'C2': comp2, 'C1': comp1 }) arity = SubqueryArityFinder.run(tree, comp1) self.assertEqual(arity, False)
def test_queryfinder(self): code = L.p(''' print(setmatch(R, 'bu', a)) print(setmatch(R, 'ub', a)) print(setmatch(R, 'bu', b)) print(setmatch({(1, 2)}, 'bu', 1)) S.add((3, 4, 5)) print(S.smlookup('bbu', (3, 4))) ''') auxmap_specs = RelmatchQueryFinder.run(code) exp_specs = {AuxmapSpec('R', Mask('bu')), AuxmapSpec('R', Mask('ub')), AuxmapSpec('S', Mask('bbu'))} self.assertCountEqual(auxmap_specs, exp_specs)
def test_inc_relcomp_uset(self): comp = L.pe('COMP({z for (x, y) in R for (y, z) in S}, [x], ' '{"uset_mode": "all"})') tree = L.p(''' T.add(e) print(COMP) ''', subst={'COMP': comp}) tree = inc_relcomp(tree, self.manager, comp, 'Q') exp_tree = L.p(''' Q = RCSet() def _maint_Q__U_Q_add(_e): for (v1_x, v1_y, v1_z) in COMP({(v1_x, v1_y, v1_z) for v1_x in deltamatch(_U_Q, 'b', _e, 1) for (v1_x, v1_y) in R for (v1_y, v1_z) in S}, [], {'_deltaelem': '_e', '_deltalhs': 'v1_x', '_deltaop': 'add', '_deltarel': '_U_Q', 'impl': 'auxonly'}): if ((v1_x, v1_z) not in Q): Q.add((v1_x, v1_z)) else: Q.incref((v1_x, v1_z)) def _maint_Q__U_Q_remove(_e): for (v2_x, v2_y, v2_z) in COMP({(v2_x, v2_y, v2_z) for v2_x in deltamatch(_U_Q, 'b', _e, 1) for (v2_x, v2_y) in R for (v2_y, v2_z) in S}, [], {'_deltaelem': '_e', '_deltalhs': 'v2_x', '_deltaop': 'remove', '_deltarel': '_U_Q', 'impl': 'auxonly'}): if (Q.getref((v2_x, v2_z)) == 1): Q.remove((v2_x, v2_z)) else: Q.decref((v2_x, v2_z)) def _maint_Q_R_add(_e): for (v3_x, v3_y, v3_z) in COMP({(v3_x, v3_y, v3_z) for v3_x in _U_Q for (v3_x, v3_y) in deltamatch(R, 'bb', _e, 1) for (v3_y, v3_z) in S}, [], {'_deltaelem': '_e', '_deltalhs': '(v3_x, v3_y)', '_deltaop': 'add', '_deltarel': 'R', 'impl': 'auxonly'}): if ((v3_x, v3_z) not in Q): Q.add((v3_x, v3_z)) else: Q.incref((v3_x, v3_z)) def _maint_Q_R_remove(_e): for (v4_x, v4_y, v4_z) in COMP({(v4_x, v4_y, v4_z) for v4_x in _U_Q for (v4_x, v4_y) in deltamatch(R, 'bb', _e, 1) for (v4_y, v4_z) in S}, [], {'_deltaelem': '_e', '_deltalhs': '(v4_x, v4_y)', '_deltaop': 'remove', '_deltarel': 'R', 'impl': 'auxonly'}): if (Q.getref((v4_x, v4_z)) == 1): Q.remove((v4_x, v4_z)) else: Q.decref((v4_x, v4_z)) def _maint_Q_S_add(_e): for (v5_x, v5_y, v5_z) in COMP({(v5_x, v5_y, v5_z) for v5_x in _U_Q for (v5_x, v5_y) in R for (v5_y, v5_z) in deltamatch(S, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v5_y, v5_z)', '_deltaop': 'add', '_deltarel': 'S', 'impl': 'auxonly'}): if ((v5_x, v5_z) not in Q): Q.add((v5_x, v5_z)) else: Q.incref((v5_x, v5_z)) def _maint_Q_S_remove(_e): for (v6_x, v6_y, v6_z) in COMP({(v6_x, v6_y, v6_z) for v6_x in _U_Q for (v6_x, v6_y) in R for (v6_y, v6_z) in deltamatch(S, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v6_y, v6_z)', '_deltaop': 'remove', '_deltarel': 'S', 'impl': 'auxonly'}): if (Q.getref((v6_x, v6_z)) == 1): Q.remove((v6_x, v6_z)) else: Q.decref((v6_x, v6_z)) _U_Q = RCSet() _UEXT_Q = Set() def demand_Q(x): '{(x, z) : x in _U_Q, (x, y) in R, (y, z) in S}' if (x not in _U_Q): with MAINT(Q, 'after', '_U_Q.add(x)'): _U_Q.add(x) _maint_Q__U_Q_add(x) else: _U_Q.incref(x) def undemand_Q(x): '{(x, z) : x in _U_Q, (x, y) in R, (y, z) in S}' if (_U_Q.getref(x) == 1): with MAINT(Q, 'before', '_U_Q.remove(x)'): _maint_Q__U_Q_remove(x) _U_Q.remove(x) else: _U_Q.decref(x) def query_Q(x): '{(x, z) : x in _U_Q, (x, y) in R, (y, z) in S}' if (x not in _UEXT_Q): _UEXT_Q.add(x) demand_Q(x) return True T.add(e) print(DEMQUERY(Q, [x], setmatch(Q, 'bu', x))) ''') self.assertEqual(tree, exp_tree)
def test_inc_relcomp_maintcomps(self): comp = L.pe('COMP({z for (x, y) in R for (y, z) in S}, [x], {})') tree = L.p(''' R.add((1, 2)) print(COMP) ''', subst={'COMP': comp}) inccomp = make_inccomp(tree, self.manager, comp, 'Q') tree, maintcomps = inc_relcomp_helper(tree, self.manager, inccomp) exp_tree = L.p(''' Q = RCSet() def _maint_Q_R_add(_e): for (v1_x, v1_y, v1_z) in COMP({(v1_x, v1_y, v1_z) for (v1_x, v1_y) in deltamatch(R, 'bb', _e, 1) for (v1_y, v1_z) in S}, [], {'_deltaelem': '_e', '_deltalhs': '(v1_x, v1_y)', '_deltaop': 'add', '_deltarel': 'R', 'impl': 'auxonly'}): if ((v1_x, v1_z) not in Q): Q.add((v1_x, v1_z)) else: Q.incref((v1_x, v1_z)) def _maint_Q_R_remove(_e): for (v2_x, v2_y, v2_z) in COMP({(v2_x, v2_y, v2_z) for (v2_x, v2_y) in deltamatch(R, 'bb', _e, 1) for (v2_y, v2_z) in S}, [], {'_deltaelem': '_e', '_deltalhs': '(v2_x, v2_y)', '_deltaop': 'remove', '_deltarel': 'R', 'impl': 'auxonly'}): if (Q.getref((v2_x, v2_z)) == 1): Q.remove((v2_x, v2_z)) else: Q.decref((v2_x, v2_z)) def _maint_Q_S_add(_e): for (v3_x, v3_y, v3_z) in COMP({(v3_x, v3_y, v3_z) for (v3_x, v3_y) in R for (v3_y, v3_z) in deltamatch(S, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v3_y, v3_z)', '_deltaop': 'add', '_deltarel': 'S', 'impl': 'auxonly'}): if ((v3_x, v3_z) not in Q): Q.add((v3_x, v3_z)) else: Q.incref((v3_x, v3_z)) def _maint_Q_S_remove(_e): for (v4_x, v4_y, v4_z) in COMP({(v4_x, v4_y, v4_z) for (v4_x, v4_y) in R for (v4_y, v4_z) in deltamatch(S, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v4_y, v4_z)', '_deltaop': 'remove', '_deltarel': 'S', 'impl': 'auxonly'}): if (Q.getref((v4_x, v4_z)) == 1): Q.remove((v4_x, v4_z)) else: Q.decref((v4_x, v4_z)) with MAINT(Q, 'after', 'R.add((1, 2))'): R.add((1, 2)) _maint_Q_R_add((1, 2)) print(setmatch(Q, 'bu', x)) ''') exp_maintcomps = [ L.pe('''COMP({(v1_x, v1_y, v1_z) for (v1_x, v1_y) in deltamatch(R, 'bb', _e, 1) for (v1_y, v1_z) in S}, [], {'_deltaelem': '_e', '_deltalhs': '(v1_x, v1_y)', '_deltaop': 'add', '_deltarel': 'R', 'impl': 'auxonly'})'''), L.pe('''COMP({(v2_x, v2_y, v2_z) for (v2_x, v2_y) in deltamatch(R, 'bb', _e, 1) for (v2_y, v2_z) in S}, [], {'_deltaelem': '_e', '_deltalhs': '(v2_x, v2_y)', '_deltaop': 'remove', '_deltarel': 'R', 'impl': 'auxonly'})'''), L.pe('''COMP({(v3_x, v3_y, v3_z) for (v3_x, v3_y) in R for (v3_y, v3_z) in deltamatch(S, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v3_y, v3_z)', '_deltaop': 'add', '_deltarel': 'S', 'impl': 'auxonly'})'''), L.pe('''COMP({(v4_x, v4_y, v4_z) for (v4_x, v4_y) in R for (v4_y, v4_z) in deltamatch(S, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v4_y, v4_z)', '_deltaop': 'remove', '_deltarel': 'S', 'impl': 'auxonly'})'''), ] self.assertEqual(tree, exp_tree) self.assertEqual(maintcomps, exp_maintcomps) self.assertEqual(exp_maintcomps[0].options['impl'], 'auxonly')
def test_change_tracker(self): comp = L.pe('COMP({(x, y, z) for (x, y) in S ' 'for (y, z) in T}, [], {})') spec = CompSpec.from_comp(comp, self.manager.factory) inccomp = IncComp(comp, spec, 'Q', False, None, None, 'no', 'das', 'auxonly', [], None) inccomp.change_tracker = True tree = L.p(''' S.add(e) ''') tree, comps = RelcompMaintainer.run(tree, self.manager, inccomp) exp_tree = L.p(''' Q = RCSet() def _maint_Q_S_add(_e): for (v1_x, v1_y, v1_z) in COMP({(v1_x, v1_y, v1_z) for (v1_x, v1_y) in deltamatch(S, 'bb', _e, 1) for (v1_y, v1_z) in T}, [], {'_deltaelem': '_e', '_deltalhs': '(v1_x, v1_y)', '_deltaop': 'add', '_deltarel': 'S', 'impl': 'auxonly'}): Q.add((v1_x, v1_y, v1_z)) def _maint_Q_S_remove(_e): for (v2_x, v2_y, v2_z) in COMP({(v2_x, v2_y, v2_z) for (v2_x, v2_y) in deltamatch(S, 'bb', _e, 1) for (v2_y, v2_z) in T}, [], {'_deltaelem': '_e', '_deltalhs': '(v2_x, v2_y)', '_deltaop': 'remove', '_deltarel': 'S', 'impl': 'auxonly'}): Q.remove((v2_x, v2_y, v2_z)) def _maint_Q_T_add(_e): for (v3_x, v3_y, v3_z) in COMP({(v3_x, v3_y, v3_z) for (v3_x, v3_y) in S for (v3_y, v3_z) in deltamatch(T, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v3_y, v3_z)', '_deltaop': 'add', '_deltarel': 'T', 'impl': 'auxonly'}): Q.add((v3_x, v3_y, v3_z)) def _maint_Q_T_remove(_e): for (v4_x, v4_y, v4_z) in COMP({(v4_x, v4_y, v4_z) for (v4_x, v4_y) in S for (v4_y, v4_z) in deltamatch(T, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v4_y, v4_z)', '_deltaop': 'remove', '_deltarel': 'T', 'impl': 'auxonly'}): Q.remove((v4_x, v4_y, v4_z)) with MAINT(Q, 'after', 'S.add(e)'): S.add(e) _maint_Q_S_add(e) ''') self.assertEqual(tree, exp_tree)
def test_deminc_nested(self): comp = L.pe( 'COMP({(x, y, z) for (x, y) in R ' 'for (y, z) in DEMQUERY(foo, [y], A)}, ' '[], ' '{"uset_force": False})') tree = L.p(''' R.add(e) print(COMP) ''', subst={'COMP': comp}) tree = deminc_relcomp(tree, self.manager, comp, 'Q') tree = L.elim_deadfuncs(tree, lambda n: n.startswith('_maint_')) exp_tree = L.p(''' foo_delta = RCSet() def _maint_foo_delta_Q_Ty_add(_e): for v7_y in COMP({v7_y for v7_y in deltamatch(Q_Ty, 'b', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': 'v7_y', '_deltaop': 'add', '_deltarel': 'Q_Ty', 'impl': 'auxonly'}): foo_delta.add(v7_y) Q_Ty = RCSet() def _maint_Q_Ty_R_add(_e): for (v5_x, v5_y) in COMP({(v5_x, v5_y) for (v5_x, v5_y) in deltamatch(R, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v5_x, v5_y)', '_deltaop': 'add', '_deltarel': 'R', 'impl': 'auxonly'}): if (v5_y not in Q_Ty): with MAINT(foo_delta, 'after', 'Q_Ty.add(v5_y)'): Q_Ty.add(v5_y) _maint_foo_delta_Q_Ty_add(v5_y) else: Q_Ty.incref(v5_y) Q = RCSet() def _maint_Q_R_add(_e): for (v1_x, v1_y, v1_z) in COMP({(v1_x, v1_y, v1_z) for (v1_x, v1_y) in deltamatch(R, 'bb', _e, 1) for (v1_y, v1_z) in A}, [], {'_deltaelem': '_e', '_deltalhs': '(v1_x, v1_y)', '_deltaop': 'add', '_deltarel': 'R', 'impl': 'auxonly'}): Q.add((v1_x, v1_y, v1_z)) with MAINT(demand_foo, 'after', 'R.add(e)'): with MAINT(Q, 'after', 'R.add(e)'): with MAINT(Q_Ty, 'after', 'R.add(e)'): R.add(e) _maint_Q_Ty_R_add(e) _maint_Q_R_add(e) for v9_y in foo_delta.elements(): demand_foo(v9_y) foo_delta.clear() print(Q) ''') self.assertEqual(tree, exp_tree)
def test_deminc_nested(self): comp = L.pe('COMP({(x, y, z) for (x, y) in R ' 'for (y, z) in DEMQUERY(foo, [y], A)}, ' '[], ' '{"uset_force": False})') tree = L.p(''' R.add(e) print(COMP) ''', subst={'COMP': comp}) tree = deminc_relcomp(tree, self.manager, comp, 'Q') tree = L.elim_deadfuncs(tree, lambda n: n.startswith('_maint_')) exp_tree = L.p(''' foo_delta = RCSet() def _maint_foo_delta_Q_Ty_add(_e): for v7_y in COMP({v7_y for v7_y in deltamatch(Q_Ty, 'b', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': 'v7_y', '_deltaop': 'add', '_deltarel': 'Q_Ty', 'impl': 'auxonly'}): foo_delta.add(v7_y) Q_Ty = RCSet() def _maint_Q_Ty_R_add(_e): for (v5_x, v5_y) in COMP({(v5_x, v5_y) for (v5_x, v5_y) in deltamatch(R, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v5_x, v5_y)', '_deltaop': 'add', '_deltarel': 'R', 'impl': 'auxonly'}): if (v5_y not in Q_Ty): with MAINT(foo_delta, 'after', 'Q_Ty.add(v5_y)'): Q_Ty.add(v5_y) _maint_foo_delta_Q_Ty_add(v5_y) else: Q_Ty.incref(v5_y) Q = RCSet() def _maint_Q_R_add(_e): for (v1_x, v1_y, v1_z) in COMP({(v1_x, v1_y, v1_z) for (v1_x, v1_y) in deltamatch(R, 'bb', _e, 1) for (v1_y, v1_z) in A}, [], {'_deltaelem': '_e', '_deltalhs': '(v1_x, v1_y)', '_deltaop': 'add', '_deltarel': 'R', 'impl': 'auxonly'}): Q.add((v1_x, v1_y, v1_z)) with MAINT(demand_foo, 'after', 'R.add(e)'): with MAINT(Q, 'after', 'R.add(e)'): with MAINT(Q_Ty, 'after', 'R.add(e)'): R.add(e) _maint_Q_Ty_R_add(e) _maint_Q_R_add(e) for v9_y in foo_delta.elements(): demand_foo(v9_y) foo_delta.clear() print(Q) ''') self.assertEqual(tree, exp_tree)
def test_transform_noparams_nodem(self): aggr_node = L.pe('sum(R, {})') tree = L.p(''' R.add(5) print(AGGR) ''', subst={'AGGR': aggr_node}) tree = inc_aggr(tree, self.manager, aggr_node, 'A', demand=True, half_demand=False) exp_tree = L.p(''' A = Set() def _maint_A_add(_e): v1_v1 = _e if (() in _U_A): v1_val = A.smlookup('u', ()) v1_val = (v1_val + v1_v1) _ = () v1_elem = A.smlookup('u', ()) A.remove(v1_elem) A.add(v1_val) def _maint_A_remove(_e): v2_v1 = _e if (() in _U_A): v2_val = A.smlookup('u', ()) v2_val = (v2_val - v2_v1) _ = () v2_elem = A.smlookup('u', ()) A.remove(v2_elem) A.add(v2_val) _U_A = RCSet() _UEXT_A = Set() def demand_A(): 'sum(R, None)' if (() not in _U_A): with MAINT(A, 'after', '_U_A.add(())'): _U_A.add(()) v3_val = 0 for v3_elem in setmatch(R, 'u', ()): v3_val = (v3_val + v3_elem) _ = () A.add(v3_val) else: _U_A.incref(()) def undemand_A(): 'sum(R, None)' if (_U_A.getref(()) == 1): with MAINT(A, 'before', '_U_A.remove(())'): _ = () v4_elem = A.smlookup('u', ()) A.remove(v4_elem) _U_A.remove(()) else: _U_A.decref(()) def query_A(): 'sum(R, None)' if (() not in _UEXT_A): _UEXT_A.add(()) demand_A() return True with MAINT(A, 'after', 'R.add(5)'): R.add(5) _maint_A_add(5) print(DEMQUERY(A, [], A.smlookup('u', (),))) ''') self.assertEqual(tree, exp_tree)
def test_transform(self): tree = L.p(''' R.add((1, 2)) R.remove((1, 2)) print(setmatch(R, 'bu', a)) print(setmatch(R, 'ub', a)) print(setmatch(R, 'bu', b)) print(setmatch({(1, 2)}, 'bu', 1)) S.add((3, 4, 5)) print(S.smlookup('bbu', (3, 4))) ''') tree = inc_all_relmatch(tree, self.manager) exp_tree = L.p(''' _m_S_bbu = Map() def _maint__m_S_bbu_add(_e): (v5_1, v5_2, v5_3) = _e if ((v5_1, v5_2) not in _m_S_bbu): _m_S_bbu.assignkey((v5_1, v5_2), set()) _m_S_bbu[(v5_1, v5_2)].add(v5_3) def _maint__m_S_bbu_remove(_e): (v6_1, v6_2, v6_3) = _e _m_S_bbu[(v6_1, v6_2)].remove(v6_3) if _m_S_bbu[(v6_1, v6_2)].isempty(): _m_S_bbu.delkey((v6_1, v6_2)) _m_R_in = Map() def _maint__m_R_in_add(_e): (v3_1, v3_2) = _e if (v3_2 not in _m_R_in): _m_R_in.assignkey(v3_2, set()) _m_R_in[v3_2].add(v3_1) def _maint__m_R_in_remove(_e): (v4_1, v4_2) = _e _m_R_in[v4_2].remove(v4_1) if _m_R_in[v4_2].isempty(): _m_R_in.delkey(v4_2) _m_R_out = Map() def _maint__m_R_out_add(_e): (v1_1, v1_2) = _e if (v1_1 not in _m_R_out): _m_R_out.assignkey(v1_1, set()) _m_R_out[v1_1].add(v1_2) def _maint__m_R_out_remove(_e): (v2_1, v2_2) = _e _m_R_out[v2_1].remove(v2_2) if _m_R_out[v2_1].isempty(): _m_R_out.delkey(v2_1) with MAINT(_m_R_out, 'after', 'R.add((1, 2))'): with MAINT(_m_R_in, 'after', 'R.add((1, 2))'): R.add((1, 2)) _maint__m_R_in_add((1, 2)) _maint__m_R_out_add((1, 2)) with MAINT(_m_R_out, 'before', 'R.remove((1, 2))'): _maint__m_R_out_remove((1, 2)) with MAINT(_m_R_in, 'before', 'R.remove((1, 2))'): _maint__m_R_in_remove((1, 2)) R.remove((1, 2)) print(_m_R_out.imglookup(a)) print(_m_R_in.imglookup(a)) print(_m_R_out.imglookup(b)) print(setmatch({(1, 2)}, 'bu', 1)) with MAINT(_m_S_bbu, 'after', 'S.add((3, 4, 5))'): S.add((3, 4, 5)) _maint__m_S_bbu_add((3, 4, 5)) print(_m_S_bbu.singlelookup((3, 4))) ''') self.assertEqual(tree, exp_tree)
def test_deminc(self): comp = L.pe('COMP({x for (x, y) in S for (y, z) in T}, [z], ' '{"uset_force": False})') tree = L.p(''' S.add(e) print(COMP) ''', subst={'COMP': comp}) tree = deminc_relcomp(tree, self.manager, comp, 'Q') tree = L.elim_deadfuncs(tree, lambda n: n.startswith('_maint_')) exp_tree = L.p(''' Q_dT = RCSet() def _maint_Q_dT_Q_Ty1_add(_e): for (v7_y, v7_z) in COMP({(v7_y, v7_z) for v7_y in deltamatch(Q_Ty1, 'b', _e, 1) for (v7_y, v7_z) in T}, [], {'_deltaelem': '_e', '_deltalhs': 'v7_y', '_deltaop': 'add', '_deltarel': 'Q_Ty1', 'impl': 'auxonly'}): Q_dT.add((v7_y, v7_z)) def _maint_Q_dT_Q_Ty1_remove(_e): for (v8_y, v8_z) in COMP({(v8_y, v8_z) for v8_y in deltamatch(Q_Ty1, 'b', _e, 1) for (v8_y, v8_z) in T}, [], {'_deltaelem': '_e', '_deltalhs': 'v8_y', '_deltaop': 'remove', '_deltarel': 'Q_Ty1', 'impl': 'auxonly'}): Q_dT.remove((v8_y, v8_z)) Q_Ty1 = RCSet() def _maint_Q_Ty1_S_add(_e): for (v5_x, v5_y) in COMP({(v5_x, v5_y) for (v5_x, v5_y) in deltamatch(S, 'bb', _e, 1)}, [], {'_deltaelem': '_e', '_deltalhs': '(v5_x, v5_y)', '_deltaop': 'add', '_deltarel': 'S', 'impl': 'auxonly'}): if (v5_y not in Q_Ty1): with MAINT(Q_dT, 'after', 'Q_Ty1.add(v5_y)'): Q_Ty1.add(v5_y) _maint_Q_dT_Q_Ty1_add(v5_y) else: Q_Ty1.incref(v5_y) Q = RCSet() def _maint_Q_S_add(_e): for (v1_x, v1_y, v1_z) in COMP({(v1_x, v1_y, v1_z) for (v1_x, v1_y) in deltamatch(S, 'bb', _e, 1) for (v1_y, v1_z) in Q_dT}, [], {'_deltaelem': '_e', '_deltalhs': '(v1_x, v1_y)', '_deltaop': 'add', '_deltarel': 'S', 'impl': 'auxonly'}): if ((v1_z, v1_x) not in Q): Q.add((v1_z, v1_x)) else: Q.incref((v1_z, v1_x)) with MAINT(Q, 'after', 'S.add(e)'): with MAINT(Q_Ty1, 'after', 'S.add(e)'): S.add(e) _maint_Q_Ty1_S_add(e) _maint_Q_S_add(e) print(setmatch(Q, 'bu', z)) ''') self.assertEqual(tree, exp_tree)