示例#1
0
def debug_comparison(e1, c1, e2, c2, assumptions : Exp = T):
    print("-" * 20)
    print("comparing costs...")
    print("  e1 = {}".format(pprint(e1)))
    print("  c1 = {}".format(c1))
    print("  e2 = {}".format(pprint(e2)))
    print("  c2 = {}".format(c2))
    print("  c1 compare_to c2 = {}".format(c1.compare_to(c2, assumptions=assumptions)))
    print("  c2 compare_to c1 = {}".format(c2.compare_to(c1, assumptions=assumptions)))
    for c1, c2 in zip(c1.costs, c2.costs):
        if not isinstance(c1, SymbolicCost):
            continue
        print("-" * 10)
        print("comparing {} and {}".format(c1, c2))
        print("  c1 compare_to c2 = {}".format(c1.compare_to(c2, assumptions=assumptions)))
        print("  c2 compare_to c1 = {}".format(c2.compare_to(c1, assumptions=assumptions)))
        print("variable meanings...")
        for e, v in itertools.chain(c1.cardinalities.items(), c2.cardinalities.items()):
            print("  {v} = len {e}".format(v=pprint(v), e=pprint(e)))
        print("joint orderings...")
        cards = c1.order_cardinalities(c2, assumptions=assumptions)
        print("  {}".format(pprint(cards)))
        for op in ("<=", "<", ">", ">="):
            print("c1 always {} c2?".format(op))
            x = []
            res = c1.always(op, c2, cards=cards, model_callback=lambda m: x.append(m))
            if res:
                print("  YES")
            elif not x:
                print("  NO (no model!?)")
            else:
                print("  NO: {}".format(x[0]))
                print("  c1 = {}".format(eval(c1.formula, env=x[0])))
                print("  c2 = {}".format(eval(c2.formula, env=x[0])))
示例#2
0
文件: semantics.py 项目: uwplse/cozy
 def dbg(model):
     print("model: {!r}".format(model))
     r1 = eval(e1, model)
     r2 = eval(e2, model)
     print("e1: {}".format(pprint(e1)))
     print(" ---> {!r}".format(r1))
     print("e2: {}".format(pprint(e2)))
     print(" ---> {!r}".format(r2))
示例#3
0
文件: semantics.py 项目: timwee/cozy
 def dbg(model):
     print("model: {!r}".format(model))
     r1 = eval(e1, model)
     r2 = eval(e2, model)
     print("e1: {}".format(pprint(e1)))
     print(" ---> {!r}".format(r1))
     print("e2: {}".format(pprint(e2)))
     print(" ---> {!r}".format(r2))
示例#4
0
 def visit(self, e):
     if hasattr(e, "_nosimpl"): return e
     if isinstance(e, Exp) and not isinstance(e, ELambda): t = e.type
     new = super().visit(e)
     if isinstance(e, Exp) and not isinstance(e, ELambda):
         assert new.type == e.type, repr(e)
     if self.debug and isinstance(e, Exp) and not isinstance(e, ELambda):
         model = satisfy(ENot(EBinOp(e, "===", new).with_type(BOOL)))
         if model is not None:
             raise Exception(
                 "bad simplification: {} ---> {} (under model {!r}, got {!r} and {!r})"
                 .format(pprint(e), pprint(new), model, eval(e, model),
                         eval(new, model)))
     return new
示例#5
0
文件: evaluation.py 项目: uwplse/cozy
 def test_set_sub(self):
     t = TSet(INT)
     s1 = Bag((0, 1))
     s2 = Bag((1, 0))
     e = EEq(EBinOp(EVar("s1").with_type(t), "-", EVar("s2").with_type(t)), EEmptyList().with_type(t))
     assert retypecheck(e)
     assert eval(e, {"s1": s1, "s2": s2}) is True
示例#6
0
 def always(self, op, other, cards : Exp, **kwargs) -> bool:
     """
     Partial order on costs.
     """
     if isinstance(self.formula, ENum) and isinstance(other.formula, ENum):
         return eval(EBinOp(self.formula, op, other.formula).with_type(BOOL), env={})
     f = EImplies(cards, EBinOp(self.formula, op, other.formula).with_type(BOOL))
     if integer_cardinalities.value:
         try:
             return valid(f, logic="QF_LIA", timeout=1, **kwargs)
         except SolverReportedUnknown:
             # If we accidentally made an unsolveable integer arithmetic formula,
             # then try again with real numbers. This will admit some models that
             # are not possible (since bags must have integer cardinalities), but
             # returning false is always a safe move here, so it's fine.
             print("Warning: not able to solve {}".format(pprint(f)))
     f = subst(f, { v.id : EVar(v.id).with_type(REAL) for v in free_vars(cards) })
     # This timeout is dangerous! Sufficiently complex specifications
     # will cause this to timeout _every_time_, meaning we never make
     # progress.
     #   However, this timeout helps ensure liveness: the Python process
     # never gets deadlocked waiting for Z3. In the Distant Future it
     # would be nice to move away from Z3Py and invoke Z3 as a subprocess
     # instead. That would allow the Python process to break out if it is
     # asked to stop while Z3 is running. It would also give us added
     # protection against Z3 segfaults, which have been observed in the
     # wild from time to time.
     timeout = 60
     try:
         return valid(f, logic="QF_NRA", timeout=timeout, **kwargs)
     except SolverReportedUnknown:
         print("Giving up!")
         return False
示例#7
0
 def test_set_sub(self):
     t = TSet(INT)
     s1 = Bag((0, 1))
     s2 = Bag((1, 0))
     e = EEq(EBinOp(EVar("s1").with_type(t), "-", EVar("s2").with_type(t)), EEmptyList().with_type(t))
     assert retypecheck(e)
     assert eval(e, {"s1": s1, "s2": s2}) is True
示例#8
0
 def test_heap_equality(self):
     t = TMinHeap(BOOL, INT)
     env = {
         "h1": Bag(((False, 7), (False, 13), (False, 13))),
         "h2": Bag(((False, 13), (False, 13), (False, 7))),
     }
     assert eval(EEq(EVar("h1").with_type(t), EVar("h2").with_type(t)), env)
示例#9
0
 def test_distinct_order(self):
     env = {
         "xs": Bag([0, 1, 0]),
     }
     e = EUnaryOp(UOp.Distinct,
                  EVar("xs").with_type(INT_BAG)).with_type(INT_BAG)
     self.assertEqual(eval(e, env), Bag([0, 1]))
示例#10
0
文件: evaluation.py 项目: uwplse/cozy
 def test_heap_equality(self):
     t = TMinHeap(BOOL, INT)
     env = {
         "h1": Bag(((False, 7), (False, 13), (False, 13))),
         "h2": Bag(((False, 13), (False, 13), (False, 7))),
     }
     assert eval(EEq(EVar("h1").with_type(t), EVar("h2").with_type(t)), env)
示例#11
0
 def EBinOp(self, e1, op, e2):
     if isinstance(e1, list): e1 = EMax([ONE] + e1)
     if isinstance(e2, list): e2 = EMax([ONE] + e2)
     if op == "*":
         if e1 == ENum(1): return e2
         if e2 == ENum(1): return e1
     e = EBinOp(e1, op, e2).with_type(e1.type)
     if isinstance(e1, ENum) and isinstance(e2, ENum):
         return ENum(eval(e, {})).with_type(e1.type)
     return e
示例#12
0
文件: contexts.py 项目: uwplse/cozy
 def instantiate_examples(self, examples : [dict]) -> [dict]:
     inst = self._parent.instantiate_examples(examples)
     res = []
     for ex in inst:
         vals = eval(self.bag, ex)
         for v in unique(vals):
             ex = dict(ex)
             ex[self.var.id] = v
             res.append(ex)
     return res
示例#13
0
 def instantiate_examples(self, examples : [dict]) -> [dict]:
     inst = self._parent.instantiate_examples(examples)
     res = []
     for ex in inst:
         vals = eval(self.bag, ex)
         for v in unique(vals):
             ex = dict(ex)
             ex[self.var.id] = v
             res.append(ex)
     return res
示例#14
0
def fingerprint_is_subset(fp1, fp2):
    """Are all cases of fp1 a subset of fp2?"""
    assert is_collection(fp1[0])
    assert is_collection(fp2[0])
    x = EVar("x").with_type(fp1[0])
    y = EVar("y").with_type(fp2[0])
    is_subset = EIsSubset(x, y)
    return all(
        eval(is_subset, {
            "x": a,
            "y": b
        }) for (a, b) in zip(fp1[1:], fp2[1:]))
示例#15
0
 def test_bind_callback(self):
     xs = EVar("xs").with_type(TBag(INT))
     x = EVar("x").with_type(INT)
     e = EFilter(xs, ELambda(x, equal(x, ENum(1).with_type(INT))))
     assert retypecheck(e)
     numbers = [0, 1, 1, 2, 3, 4]
     binds = []
     m = eval(e,
              env={xs.id: Bag(numbers)},
              bind_callback=lambda arg, val: binds.append((arg, val)))
     assert m == Bag([1, 1]), "m={}".format(m)
     assert binds == [(x, i) for i in numbers], "binds={}".format(binds)
示例#16
0
    def _compare(self, e1: Exp, e2: Exp, context: Context):
        e1_constant = not free_vars(e1) and not free_funcs(e1)
        e2_constant = not free_vars(e2) and not free_funcs(e2)
        if e1_constant and e2_constant:
            e1v = eval(e1, {})
            e2v = eval(e2, {})
            event("comparison obvious on constants: {} vs {}".format(e1v, e2v))
            return order_objects(e1v, e2v)
        if alpha_equivalent(e1, e2):
            event("shortcutting comparison of identical terms")
            return Order.EQUAL

        path_condition = EAll(context.path_conditions())
        always_le = self.solver.valid(EImplies(path_condition, ELe(e1, e2)))
        always_ge = self.solver.valid(EImplies(path_condition, EGe(e1, e2)))

        if always_le and always_ge:
            return Order.EQUAL
        if always_le:
            return Order.LT
        if always_ge:
            return Order.GT
        return Order.AMBIGUOUS
示例#17
0
 def test_makerecord(self):
     e = EMakeRecord(
         (('orderkey', ENum(0).with_type(TInt())),
          ('custkey', ENum(0).with_type(TInt())),
          ('orderstatus',
           ENative(ENum(0).with_type(TInt())).with_type(TNative('char'))),
          ('totalprice', ENum(0).with_type(TFloat())),
          ('orderdate', ENative(ENum(0).with_type(TInt())).with_type(
              TNative('uint64_t'))), ('orderpriority', EStr('').with_type(
                  TString())), ('clerk', EStr('').with_type(TString())),
          ('shippriority', ENum(0).with_type(TInt())),
          ('comment', EStr('').with_type(TString())))).with_type(
              TRecord((('orderkey', TInt()), ('custkey', TInt()),
                       ('orderstatus', TNative('char')),
                       ('totalprice', TFloat()), ('orderdate',
                                                  TNative('uint64_t')),
                       ('orderpriority', TString()), ('clerk', TString()),
                       ('shippriority', TInt()), ('comment', TString()))))
     uneval(e.type, eval(e, {}))
示例#18
0
def _satisfy(e, solver, assumptions):
    """
    :param e: expression to test sat
    :param solver: the default solver
    :param assumptions: a list of expressions that are assumed true
    Heuristic to decide whether e is satisfiable quickly.
    it is a partial procedure: the possible outputs are a satisfying assignment or None (indicating unknown)
    it is allowed to indicate unknown with an arbitrary exception
    (in which case falling back to the symbolic solver is a reasonable choice)
    """

    if isinstance(e, EUnaryOp) and e.op == "not" and isinstance(
            e.e, EBinOp) and e.e.op == "==":
        e1 = e.e.e1
        e2 = e.e.e2
        if isinstance(e1, EFlatMap) and isinstance(e2, EFlatMap):
            lc1 = extract_listcomp(e1)
            lc2 = extract_listcomp(e2)
            if lc1 is not None and lc2 is not None:
                cond1 = get_cond(lc1)
                cond2 = get_cond(lc2)
                sat1 = solver.satisfy(cond1)
                sat2 = solver.satisfy(cond2)
                if sat1 is None and sat2 is not None:
                    return {k: v for k, v in sat2.items() if k not in lc2["P"]}
                if sat1 is not None and sat2 is None:
                    return {k: v for k, v in sat1.items() if k not in lc1["P"]}

    iterables = [random_value(v.type) for v in free_vars(e)]
    ids = [v.id for v in free_vars(e)]
    for vs in product(*iterables):
        assignments = {}
        for id_, val in zip(ids, vs):
            assignments[id_] = val
        sat = eval(EAll([e] + assumptions), assignments)
        if sat:
            return assignments
    return None
示例#19
0
 def visit(self, e):
     if hasattr(e, "_nosimpl"): return e
     if isinstance(e, Exp) and not isinstance(e, ELambda): t = e.type
     new = super().visit(e)
     if isinstance(e, Exp) and not isinstance(e, ELambda): assert new.type == e.type or (is_collection(new.type) and is_collection(e.type)), repr(e)
     if self.debug and isinstance(e, Exp) and not isinstance(e, ELambda):
         model = satisfy(ENot(EBinOp(e, "===", new).with_type(BOOL)))
         if model is not None:
             raise Exception("bad simplification: {} ---> {} (under model {!r}, got {!r} and {!r})".format(pprint(e), pprint(new), model, eval(e, model), eval(new, model)))
     return new
示例#20
0
def _try_optimize(e: Exp, context: Context, pool: Pool):
    if not accelerate.value:
        return

    if pool != RUNTIME_POOL:
        return

    state_vars = [v for v, p in context.vars() if p == STATE_POOL]
    args = [v for v, p in context.vars() if p == RUNTIME_POOL]

    # ---------------------------------------------------------------------
    # "Rewrite schemes": these trigger on many different AST shapes
    # They are listed first because they are more powerful than the
    # specific rewrite rules below.

    if not free_vars(e) and not free_funcs(e):
        try:
            yield _check(uneval(e.type, eval(e, {})), context, RUNTIME_POOL)
        except NotImplementedError:
            print("Unable to evaluate {!r}".format(e))

    if all(v in state_vars for v in free_vars(e)):
        nsv = strip_EStateVar(e)
        sv = EStateVar(nsv).with_type(e.type)
        yield _check(sv, context, RUNTIME_POOL)

    for ee in fold_into_map(e, context):
        yield _check(ee, context, pool)

    # ---------------------------------------------------------------------
    # "Rewrites": these trigger on specific AST nodes

    if isinstance(e, EBinOp):

        if e.op == "-" and is_collection(e.type):
            ee = optimized_bag_difference(e.e1, e.e2)
            yield _check(ee, context, RUNTIME_POOL)

        if e.op == "===" and isinstance(e.e1.type, THandle):
            yield _check(
                EAll([
                    optimized_eq(optimized_addr(e.e1), optimized_addr(e.e2)),
                    optimized_eq(optimized_val(e.e1),
                                 optimized_val(e.e2)).with_type(BOOL)
                ]), context, RUNTIME_POOL)

        if e.op == BOp.In:
            ee = optimized_in(e.e1, e.e2)
            yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, ECond):
        yield _check(optimized_cond(e.cond, e.then_branch, e.else_branch),
                     context, RUNTIME_POOL)

    if isinstance(e, EGetField):
        for ee in optimized_get_field(e.e, e.field_name, args):
            yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EListGet) and e.index == ZERO:
        for res in optimized_the(e.e, args):
            yield _check(res, context, RUNTIME_POOL)

    if isinstance(e, EListGet) and isinstance(e.e, ECond):
        yield optimized_cond(
            e.e.cond,
            EListGet(e.e.then_branch, e.index).with_type(e.type),
            EListGet(e.e.else_branch, e.index).with_type(e.type))

    from cozy.structures.treemultiset import ETreeMultisetElems, ETreeMultisetPeek
    if isinstance(e, EListGet) and isinstance(e.e, ETreeMultisetElems):
        yield ETreeMultisetPeek(e.e.e, e.index).with_type(e.type)

    if isinstance(e, EMapGet):
        ee = inline_mapget(e, context)
        yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EUnaryOp):

        if e.op == UOp.Sum:
            for ee in optimized_sum(e.e, args):
                yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.Length:
            ee = optimized_len(e.e)
            yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.Empty:
            ee = optimized_empty(e.e)
            yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.Exists:
            ee = optimized_exists(e.e)
            yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.Distinct:
            for ee in optimized_distinct(e.e, args):
                yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.The:
            for ee in optimized_the(e.e, args):
                yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EArgMin) or isinstance(e, EArgMax):
        for ee in optimized_best(e.e,
                                 e.key_function,
                                 "<" if isinstance(e, EArgMin) else ">",
                                 args=args):
            yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EFilter):
        for ee in optimized_filter(e.e, e.predicate, args=args):
            yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EMap):
        for ee in optimized_map(e.e, e.transform_function, args=args):
            yield _check(ee, context, RUNTIME_POOL)
    from cozy.syntax import ESorted
    from cozy.structures.treemultiset import EMakeMaxTreeMultiset, TMaxTreeMultiset, EMakeMinTreeMultiset, TMinTreeMultiset, ETreeMultisetElems
    target = e
    if isinstance(target, ESorted) and isinstance(target.e, EStateVar):
        e_max = EMakeMaxTreeMultiset(target.e.e).with_type(
            TMaxTreeMultiset(target.e.e.type.elem_type))
        e_min = EMakeMinTreeMultiset(target.e.e).with_type(
            TMinTreeMultiset(target.e.e.type.elem_type))
        ee = optimized_cond(
            target.asc,
            ETreeMultisetElems(EStateVar(e_min).with_type(
                e_min.type)).with_type(target.type),
            ETreeMultisetElems(EStateVar(e_max).with_type(
                e_max.type)).with_type(target.type))
        yield _check(ee, context, RUNTIME_POOL)
示例#21
0
文件: evaluation.py 项目: uwplse/cozy
 def test_distinct_order(self):
     env = {
         "xs": Bag([0, 1, 0]),
     }
     e = EUnaryOp(UOp.Distinct, EVar("xs").with_type(INT_BAG)).with_type(INT_BAG)
     self.assertEqual(eval(e, env), Bag([0, 1]))
示例#22
0
 def test_let(self):
     x = EVar("x").with_type(INT)
     e = ELet(ZERO, ELambda(x, ELet(ONE, ELambda(x, EBinOp(x, "+", x)))))
     assert retypecheck(e)
     assert eval(e, env={}) == 2
示例#23
0
 def test_eall(self):
     assert eval(EAll(()), {})
     for l in range(5):
         print(pprint(EAll([EVar("v{}".format(i)).with_type(BOOL) for i in range(l)])))
示例#24
0
文件: evaluation.py 项目: uwplse/cozy
 def test_let(self):
     x = EVar("x").with_type(INT)
     e = ELet(ZERO, ELambda(x, ELet(ONE, ELambda(x, EBinOp(x, "+", x)))))
     assert retypecheck(e)
     assert eval(e, env={}) == 2
示例#25
0
def _try_optimize(e, context, pool):
    if not accelerate.value:
        return

    state_vars = [v for v, p in context.vars() if p == STATE_POOL]
    args = [v for v, p in context.vars() if p == RUNTIME_POOL]

    if pool == RUNTIME_POOL:

        if not free_vars(e) and not free_funcs(e):
            try:
                yield _check(uneval(e.type, eval(e, {})), context,
                             RUNTIME_POOL)
            except NotImplementedError:
                print("Unable to evaluate {!r}".format(e))

        if all(v in state_vars for v in free_vars(e)):
            nsv = strip_EStateVar(e)
            sv = EStateVar(nsv).with_type(e.type)
            yield _check(sv, context, RUNTIME_POOL)

        for ee in fold_into_map(e, context):
            yield _check(ee, context, pool)

        if isinstance(e, EListGet) and e.index == ZERO:
            for res in optimize_the(e.e, args):
                yield _check(res, context, RUNTIME_POOL)

        if isinstance(e, EArgMin) or isinstance(e, EArgMax):
            for ee in optimized_best(e.e,
                                     e.f,
                                     "<" if isinstance(e, EArgMin) else ">",
                                     args=args):
                yield _check(ee, context, RUNTIME_POOL)

        if is_collection(e.type) and isinstance(e, EBinOp) and e.op == "-":
            ee = optimized_bag_difference(e.e1, e.e2)
            yield _check(ee, context, RUNTIME_POOL)

        if isinstance(e, EBinOp) and e.op == "===" and isinstance(
                e.e1.type, THandle):
            yield _check(
                EAll([
                    optimized_eq(optimized_addr(e.e1), optimized_addr(e.e2)),
                    optimized_eq(optimized_val(e.e1),
                                 optimized_val(e.e2)).with_type(BOOL)
                ]), context, RUNTIME_POOL)

        if isinstance(e, ECond):
            yield _check(optimized_cond(e.cond, e.then_branch, e.else_branch),
                         context, RUNTIME_POOL)

        if isinstance(e, EGetField):
            for ee in optimized_get_field(e.e, e.f, args):
                yield _check(ee, context, RUNTIME_POOL)

        if isinstance(e, EBinOp) and e.op == BOp.In:
            ee = optimized_in(e.e1, e.e2)
            yield _check(ee, context, RUNTIME_POOL)

        if isinstance(e, EUnaryOp) and e.op == UOp.Sum:
            for ee in optimized_sum(e.e, args):
                yield _check(ee, context, RUNTIME_POOL)

        if isinstance(e, EUnaryOp) and e.op == UOp.Empty:
            ee = optimized_empty(e.e)
            yield _check(ee, context, RUNTIME_POOL)

        if isinstance(e, EUnaryOp) and e.op == UOp.Exists:
            ee = optimized_exists(e.e)
            yield _check(ee, context, RUNTIME_POOL)

        if isinstance(e, EUnaryOp) and e.op == UOp.Length:
            ee = optimized_len(e.e)
            yield _check(ee, context, RUNTIME_POOL)

        if isinstance(e, EUnaryOp) and e.op == UOp.The:
            for ee in optimize_the(e.e, args):
                yield _check(ee, context, RUNTIME_POOL)

        if isinstance(e, EFilter):
            ee = optimize_filter_as_if_distinct(e.e, e.p, args=args)
            yield _check(ee, context, RUNTIME_POOL)
            if isinstance(e.e, EFilter):
                # try swizzle
                ee = EFilter(_simple_filter(e.e.e, e.p, args=args),
                             e.e.p).with_type(e.type)
                yield _check(ee, context, RUNTIME_POOL)

        if isinstance(e, EMap):
            for ee in optimize_map(e.e, e.f, args=args):
                yield _check(ee, context, RUNTIME_POOL)
示例#26
0
文件: evaluation.py 项目: uwplse/cozy
 def test_leq(self):
     e = ZERO
     for i in range(50):
         e = ECond(EBinOp(e, "<=", ONE), ONE, ZERO).with_type(INT)
     res = eval(e, env={})
     print(res)
示例#27
0
 def test_leq(self):
     e = ZERO
     for i in range(50):
         e = ECond(EBinOp(e, "<=", ONE), ONE, ZERO).with_type(INT)
     res = eval(e, env={})
     print(res)
示例#28
0
def _try_optimize(e : Exp, context : Context, pool : Pool):
    if not accelerate.value:
        return

    if pool != RUNTIME_POOL:
        return

    state_vars = [v for v, p in context.vars() if p == STATE_POOL]
    args = [v for v, p in context.vars() if p == RUNTIME_POOL]

    # ---------------------------------------------------------------------
    # "Rewrite schemes": these trigger on many different AST shapes
    # They are listed first because they are more powerful than the
    # specific rewrite rules below.

    if not free_vars(e) and not free_funcs(e):
        try:
            yield _check(uneval(e.type, eval(e, {})), context, RUNTIME_POOL)
        except NotImplementedError:
            print("Unable to evaluate {!r}".format(e))

    if all(v in state_vars for v in free_vars(e)):
        nsv = strip_EStateVar(e)
        sv = EStateVar(nsv).with_type(e.type)
        yield _check(sv, context, RUNTIME_POOL)

    for ee in fold_into_map(e, context):
        yield _check(ee, context, pool)

    # ---------------------------------------------------------------------
    # "Rewrites": these trigger on specific AST nodes

    if isinstance(e, EBinOp):

        if e.op == "-" and is_collection(e.type):
            ee = optimized_bag_difference(e.e1, e.e2)
            yield _check(ee, context, RUNTIME_POOL)

        if e.op == "===" and isinstance(e.e1.type, THandle):
            yield _check(EAll([
                optimized_eq(optimized_addr(e.e1), optimized_addr(e.e2)),
                optimized_eq(optimized_val(e.e1),  optimized_val(e.e2)).with_type(BOOL)]), context, RUNTIME_POOL)

        if e.op == BOp.In:
            ee = optimized_in(e.e1, e.e2)
            yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, ECond):
        yield _check(optimized_cond(e.cond, e.then_branch, e.else_branch), context, RUNTIME_POOL)

    if isinstance(e, EGetField):
        for ee in optimized_get_field(e.e, e.field_name, args):
            yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EListGet) and e.index == ZERO:
        for res in optimized_the(e.e, args):
            yield _check(res, context, RUNTIME_POOL)

    if isinstance(e, EListGet) and isinstance(e.e, ECond):
        yield optimized_cond(e.e.cond,
                             EListGet(e.e.then_branch, e.index).with_type(e.type),
                             EListGet(e.e.else_branch, e.index).with_type(e.type))

    from cozy.structures.treemultiset import ETreeMultisetElems, ETreeMultisetPeek
    if isinstance(e, EListGet) and isinstance(e.e, ETreeMultisetElems):
        yield ETreeMultisetPeek(e.e.e, e.index).with_type(e.type)

    if isinstance(e, EMapGet):
        ee = inline_mapget(e, context)
        yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EUnaryOp):

        if e.op == UOp.Sum:
            for ee in optimized_sum(e.e, args):
                yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.Length:
            ee = optimized_len(e.e)
            yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.Empty:
            ee = optimized_empty(e.e)
            yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.Exists:
            ee = optimized_exists(e.e)
            yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.Distinct:
            for ee in optimized_distinct(e.e, args):
                yield _check(ee, context, RUNTIME_POOL)

        if e.op == UOp.The:
            for ee in optimized_the(e.e, args):
                yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EArgMin) or isinstance(e, EArgMax):
        for ee in optimized_best(e.e, e.key_function, "<" if isinstance(e, EArgMin) else ">", args=args):
            yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EFilter):
        for ee in optimized_filter(e.e, e.predicate, args=args):
            yield _check(ee, context, RUNTIME_POOL)

    if isinstance(e, EMap):
        for ee in optimized_map(e.e, e.transform_function, args=args):
            yield _check(ee, context, RUNTIME_POOL)
    from cozy.syntax import ESorted
    from cozy.structures.treemultiset import EMakeMaxTreeMultiset, TMaxTreeMultiset, EMakeMinTreeMultiset, TMinTreeMultiset, ETreeMultisetElems
    target = e
    if isinstance(target, ESorted) and isinstance(target.e, EStateVar):
        e_max = EMakeMaxTreeMultiset(target.e.e).with_type(TMaxTreeMultiset(target.e.e.type.elem_type))
        e_min = EMakeMinTreeMultiset(target.e.e).with_type(TMinTreeMultiset(target.e.e.type.elem_type))
        ee = optimized_cond(target.asc,
                            ETreeMultisetElems(EStateVar(e_min).with_type(e_min.type)).with_type(target.type),
                            ETreeMultisetElems(EStateVar(e_max).with_type(e_max.type)).with_type(target.type))
        yield _check(ee, context, RUNTIME_POOL)
示例#29
0
文件: evaluation.py 项目: uwplse/cozy
 def test_makerecord(self):
     e = EMakeRecord((('orderkey', ENum(0).with_type(TInt())), ('custkey', ENum(0).with_type(TInt())), ('orderstatus', ENative(ENum(0).with_type(TInt())).with_type(TNative('char'))), ('totalprice', ENum(0).with_type(TFloat())), ('orderdate', ENative(ENum(0).with_type(TInt())).with_type(TNative('uint64_t'))), ('orderpriority', EStr('').with_type(TString())), ('clerk', EStr('').with_type(TString())), ('shippriority', ENum(0).with_type(TInt())), ('comment', EStr('').with_type(TString())))).with_type(TRecord((('orderkey', TInt()), ('custkey', TInt()), ('orderstatus', TNative('char')), ('totalprice', TFloat()), ('orderdate', TNative('uint64_t')), ('orderpriority', TString()), ('clerk', TString()), ('shippriority', TInt()), ('comment', TString()))))
     uneval(e.type, eval(e, {}))