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])))
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))
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))
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
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
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
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
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)
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]))
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)
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
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
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
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:]))
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)
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
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, {}))
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
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
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)
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]))
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
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)])))
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
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)
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)
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)
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)
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, {}))