Exemplo n.º 1
0
Arquivo: cxx.py Projeto: sanidhya/cozy
 def visit_EMapGet(self, e, indent=""):
     if isinstance(e.map, EStateVar):
         return self.visit(EMapGet(e.map.e, e.key).with_type(e.type),
                           indent=indent)
     elif isinstance(e.map, EMakeMap2):
         return self.visit(ELet(
             e.key,
             mk_lambda(
                 e.key.type, lambda k: ECond(
                     EBinOp(k, BOp.In, e.map.e).with_type(BOOL),
                     e.map.value.apply_to(k),
                     evaluation.construct_value(e.map.type.v)).with_type(
                         e.type))).with_type(e.type),
                           indent=indent)
     elif isinstance(e.map, ECond):
         return self.visit(ELet(
             e.key,
             mk_lambda(
                 e.key.type, lambda k: ECond(
                     e.map.cond,
                     EMapGet(e.map.then_branch, k).with_type(e.type),
                     EMapGet(e.map.else_branch, k).with_type(e.type)).
                 with_type(e.type))).with_type(e.type),
                           indent=indent)
     elif isinstance(e.map, EVar):
         if isinstance(e.map.type,
                       library.TNativeMap) or type(e.map.type) is TMap:
             return self.native_map_get(
                 e, lambda out: self.construct_concrete(
                     e.map.type.v, evaluation.construct_value(e.map.type.v),
                     out), indent)
         else:
             return self.visit(e.map.type.get_key(e.map, e.key), indent)
     else:
         raise NotImplementedError(type(e.map))
Exemplo n.º 2
0
def histogram(xs: Exp) -> Exp:
    elem_type = xs.type.t
    return EMakeMap2(
        xs,
        mk_lambda(
            elem_type, lambda x: ELen(
                EFilter(xs, mk_lambda(elem_type, lambda y: EEq(x, y))).
                with_type(xs.type)))).with_type(TMap(elem_type, INT))
Exemplo n.º 3
0
    def test_construct_concrete_map(self):
        with io.StringIO() as f:
            codgen = CxxPrinter(out=f)

            bag = EFilter(EVar("v").with_type(TBag(INT)), mk_lambda(INT, lambda x: EBinOp(x, ">", ZERO))).with_type(TBag(INT))
            map = EMakeMap2(bag, mk_lambda(INT, lambda k: k)).with_type(TMap(INT, INT))
            stm = codgen.construct_concrete(TMap(INT, INT), map, EVar("out").with_type(TMap(INT, INT)))
            codgen.visit(stm)
Exemplo n.º 4
0
def EArgDistinct(bag, key):
    from cozy.syntax_tools import mk_lambda
    b = EVar(fresh_name())
    distinct_keys = EUnaryOp(UOp.Distinct, EMap(b, key))
    res = EMap(distinct_keys,
        mk_lambda(None, lambda x:
            EUnaryOp(UOp.The, EFilter(b, mk_lambda(None, lambda y:
                EEq(x, key.apply_to(y)))))))
    return ELet(bag, ELambda(b, res))
Exemplo n.º 5
0
 def test_lambdas(self):
     employers = EVar("employers").with_type(TBag(TInt()))
     e1 = mk_lambda(
         employers.type.t, lambda employer: EGetField(
             EGetField(employer, "val"), "employer_name"))
     e2 = mk_lambda(
         employers.type.t, lambda employer: EGetField(
             EGetField(employer, "val"), "employer_name"))
     assert alpha_equivalent(e1, e2)
Exemplo n.º 6
0
def EArgDistinct(bag, key):
    from cozy.syntax_tools import mk_lambda
    b = EVar(fresh_name())
    distinct_keys = EUnaryOp(UOp.Distinct, EMap(b, key))
    res = EMap(
        distinct_keys,
        mk_lambda(
            None, lambda x: EUnaryOp(
                UOp.The,
                EFilter(b, mk_lambda(None, lambda y: EEq(x, key.apply_to(y)))))
        ))
    return ELet(bag, ELambda(b, res))
Exemplo n.º 7
0
def histogram(xs : Exp) -> Exp:
    """Compute a histogram of the given collection.

    This function takes a collection-type expression `xs` and returns a
    map-type expression.  The new expression constructs a map from elements of
    `xs` to the number of times they occur in `xs` (i.e. a histogram of the
    elements).
    """
    elem_type = xs.type.elem_type
    return EMakeMap2(xs,
        mk_lambda(elem_type, lambda x:
            ELen(EFilter(xs,
                mk_lambda(elem_type, lambda y:
                    EEq(x, y))).with_type(xs.type)))).with_type(TMap(elem_type, INT))
Exemplo n.º 8
0
def histogram(xs : Exp) -> Exp:
    """Compute a histogram of the given collection.

    This function takes a collection-type expression `xs` and returns a
    map-type expression.  The new expression constructs a map from elements of
    `xs` to the number of times they occur in `xs` (i.e. a histogram of the
    elements).
    """
    elem_type = xs.type.elem_type
    return EMakeMap2(xs,
        mk_lambda(elem_type, lambda x:
            ELen(EFilter(xs,
                mk_lambda(elem_type, lambda y:
                    EEq(x, y))).with_type(xs.type)))).with_type(TMap(elem_type, INT))
Exemplo n.º 9
0
 def test_make_map(self):
     employers = EVar("employers").with_type(TBag(TInt()))
     e1 = EMakeMap(
         employers,
         mk_lambda(
             employers.type.t, lambda employer: EGetField(
                 EGetField(employer, "val"), "employer_name")),
         mk_lambda(employers.type, lambda es: es))
     e2 = EMakeMap(
         employers,
         mk_lambda(
             employers.type.t, lambda employer: EGetField(
                 EGetField(employer, "val"), "employer_name")),
         mk_lambda(employers.type, lambda es: es))
     assert alpha_equivalent(e1, e2)
Exemplo n.º 10
0
 def test_mapget_of_makemap(self):
     t = THandle("T", INT)
     xs = EVar("xs").with_type(TBag(t))
     x = EVar("x").with_type(t)
     y = EVar("y").with_type(t)
     mt = TTuple((INT, INT))
     e1 = EMapGet(
         EMakeMap2(
             xs,
             ELambda(
                 x,
                 ETuple(
                     (EGetField(x, "val").with_type(INT), EGetField(
                         y,
                         "val").with_type(INT))).with_type(mt))).with_type(
                             TMap(t, mt)), y).with_type(mt)
     e2 = ECond(
         EIn(e1.key, e1.map.e),
         e1.map.value.apply_to(
             EUnaryOp(
                 UOp.The,
                 EFilter(
                     e1.map.e,
                     mk_lambda(e1.map.value.arg.type,
                               lambda foo: EEq(foo, e1.key))).with_type(
                                   e1.map.e.type)).with_type(
                                       e1.map.e.type.t)),
         construct_value(e1.type)).with_type(e1.type)
     self.assert_same(e1, e2)
Exemplo n.º 11
0
def optimized_bag_difference(xs, ys):
    # EStateVar(distinct xs) - (EStateVar(xs) - [i])
    # ===> is-last(i, xs) ? [] : [i]
    if (isinstance(ys, EBinOp) and ys.op == "-"
            and isinstance(ys.e1, EStateVar) and isinstance(ys.e2, ESingleton)
            and isinstance(xs, EStateVar) and isinstance(xs.e, EUnaryOp)
            and xs.e.op == UOp.Distinct and alpha_equivalent(xs.e.e, ys.e1.e)):
        distinct_elems = xs.e
        elems = distinct_elems.e
        elem_type = elems.type.t
        m = histogram(elems)
        m_rt = EStateVar(m).with_type(m.type)
        count = EMapGet(m_rt, ys.e2.e).with_type(INT)
        return optimized_cond(optimized_eq(count, ONE), ys.e2,
                              EEmptyList().with_type(xs.type))

    # xs - (xs - [i])
    # ===> (i in xs) ? [i] : []
    if isinstance(ys, EBinOp) and ys.op == "-" and isinstance(
            ys.e2, ESingleton) and alpha_equivalent(xs, ys.e1):
        return optimized_cond(optimized_in(ys.e2.e, xs), ys.e2,
                              EEmptyList().with_type(xs.type))

    # [x] - xs
    if isinstance(xs, ESingleton):
        return optimized_cond(optimized_in(xs.e, ys),
                              EEmptyList().with_type(xs.type), xs)

    # only legal if xs are distinct, but we'll give it a go...
    return EFilter(xs, mk_lambda(
        xs.type.t, lambda x: ENot(optimized_in(x, ys)))).with_type(xs.type)
Exemplo n.º 12
0
 def test_mapget_of_makemap1(self):
     t = THandle("elem_type", INT)
     xs = EVar("xs").with_type(TBag(t))
     x = EVar("x").with_type(t)
     y = EVar("y").with_type(t)
     mt = TTuple((INT, INT))
     e1 = EMapGet(
         EMakeMap2(
             xs,
             ELambda(
                 x,
                 ETuple(
                     (EGetField(x, "val").with_type(INT), EGetField(
                         y,
                         "val").with_type(INT))).with_type(mt))).with_type(
                             TMap(t, mt)), y).with_type(mt)
     e2 = EUnaryOp(
         UOp.The,
         EMap(
             EFilter(
                 e1.map.e,
                 mk_lambda(e1.map.value_function.arg.type,
                           lambda foo: EEq(foo, e1.key))).with_type(
                               e1.map.e.type),
             e1.map.value_function).with_type(e1.map.e.type)).with_type(
                 e1.map.e.type.elem_type)
     assert retypecheck(e1)
     assert retypecheck(e2)
     self.assert_same(e1, e2)
Exemplo n.º 13
0
def optimized_in(x, xs):
    if isinstance(xs, EStateVar):
        m = EMakeMap2(xs.e, mk_lambda(x.type, lambda x: ETRUE)).with_type(TMap(x.type, BOOL))
        m = EStateVar(m).with_type(m.type)
        return EHasKey(m, x).with_type(BOOL)
    elif isinstance(xs, EBinOp) and xs.op == "-" and isinstance(xs.e1, EStateVar) and isinstance(xs.e2, ESingleton):
        return optimized_cond(optimized_eq(x, xs.e2.e),
            EGt(optimized_count(x, xs.e1), ONE),
            optimized_in(x, xs.e1)).with_type(BOOL)
    elif isinstance(xs, EBinOp) and xs.op == "-":
        return EGt(optimized_count(x, xs.e1), optimized_count(x, xs.e2))
    elif isinstance(xs, EBinOp) and xs.op == "+":
        return EAny([
            optimized_in(x, xs.e1),
            optimized_in(x, xs.e2)])
    elif isinstance(xs, ECond):
        return optimized_cond(xs.cond,
            optimized_in(x, xs.then_branch),
            optimized_in(x, xs.else_branch)).with_type(BOOL)
    elif isinstance(xs, EFilter):
        return EAll([xs.predicate.apply_to(x), optimized_in(x, xs.e)])
    elif isinstance(xs, EMap) and xs.transform_function.arg not in free_vars(x):
        return optimized_any_matches(xs.e, ELambda(xs.transform_function.arg, optimized_eq(xs.transform_function.body, x)))
    elif isinstance(xs, ESingleton):
        return optimized_eq(x, xs.e)
    elif isinstance(xs, EEmptyList):
        return EFALSE
    else:
        return EBinOp(x, BOp.In, xs).with_type(BOOL)
Exemplo n.º 14
0
def optimized_bag_difference(xs, ys):
    # EStateVar(distinct xs) - (EStateVar(xs) - [i])
    # ===> is-last(i, xs) ? [] : [i]
    if (isinstance(ys, EBinOp) and ys.op == "-" and
            isinstance(ys.e1, EStateVar) and
            isinstance(ys.e2, ESingleton) and
            isinstance(xs, EStateVar) and isinstance(xs.e, EUnaryOp) and xs.e.op == UOp.Distinct and
            alpha_equivalent(xs.e.e, ys.e1.e)):
        distinct_elems = xs.e
        elems = distinct_elems.e
        elem_type = elems.type.elem_type
        m = histogram(elems)
        m_rt = EStateVar(m).with_type(m.type)
        count = EMapGet(m_rt, ys.e2.e).with_type(INT)
        return optimized_cond(
            optimized_eq(count, ONE),
            ys.e2,
            EEmptyList().with_type(xs.type))

    # xs - (xs - [i])
    # ===> (i in xs) ? [i] : []
    if isinstance(ys, EBinOp) and ys.op == "-" and isinstance(ys.e2, ESingleton) and alpha_equivalent(xs, ys.e1):
        return optimized_cond(optimized_in(ys.e2.e, xs),
            ys.e2,
            EEmptyList().with_type(xs.type))

    # [x] - xs
    if isinstance(xs, ESingleton):
        return optimized_cond(
            optimized_in(xs.e, ys),
            EEmptyList().with_type(xs.type),
            xs)

    # only legal if xs are distinct, but we'll give it a go...
    return EFilter(xs, mk_lambda(xs.type.elem_type, lambda x: ENot(optimized_in(x, ys)))).with_type(xs.type)
Exemplo n.º 15
0
 def test_construct_concrete_list(self):
     with io.StringIO() as f:
         codgen = CxxPrinter(out=f)
         
         bag = EFilter(EVar("v").with_type(TBag(INT)), mk_lambda(INT, lambda x: EBinOp(x, ">", ZERO))).with_type(TBag(INT))
         stm = codgen.construct_concrete(TList(INT), bag, EVar("out").with_type(TList(INT)))
         codgen.visit(stm)
Exemplo n.º 16
0
def optimized_in(x, xs):
    if isinstance(xs, EStateVar):
        m = EMakeMap2(xs.e,
                      mk_lambda(x.type,
                                lambda x: T)).with_type(TMap(x.type, BOOL))
        m = EStateVar(m).with_type(m.type)
        return EHasKey(m, x).with_type(BOOL)
    elif isinstance(xs, EBinOp) and xs.op == "-" and isinstance(
            xs.e1, EStateVar) and isinstance(xs.e2, ESingleton):
        return optimized_cond(optimized_eq(x, xs.e2.e),
                              EGt(optimized_count(x, xs.e1), ONE),
                              optimized_in(x, xs.e1)).with_type(BOOL)
    elif isinstance(xs, EBinOp) and xs.op == "-":
        return EGt(optimized_count(x, xs.e1), optimized_count(x, xs.e2))
    elif isinstance(xs, EBinOp) and xs.op == "+":
        return EAny([optimized_in(x, xs.e1), optimized_in(x, xs.e2)])
    elif isinstance(xs, ECond):
        return optimized_cond(xs.cond, optimized_in(x, xs.then_branch),
                              optimized_in(x, xs.else_branch)).with_type(BOOL)
    elif isinstance(xs, EFilter):
        return EAll([xs.p.apply_to(x), optimized_in(x, xs.e)])
    elif isinstance(xs, EMap) and xs.f.arg not in free_vars(x):
        return optimized_any_matches(
            xs.e, ELambda(xs.f.arg, optimized_eq(xs.f.body, x)))
    elif isinstance(xs, ESingleton):
        return optimized_eq(x, xs.e)
    elif isinstance(xs, EEmptyList):
        return F
    else:
        return EBinOp(x, BOp.In, xs).with_type(BOOL)
Exemplo n.º 17
0
 def test_subsub(self):
     xs = EVar("xs").with_type(INT_BAG)
     i = EVar("i").with_type(INT)
     e1 = EBinOp(EUnaryOp(UOp.Distinct, xs), "-",
                 EBinOp(xs, "-", ESingleton(i)))
     assert retypecheck(e1)
     m = EMakeMap2(
         e1.e1,
         mk_lambda(
             INT, lambda x: EUnaryOp(
                 UOp.Length, EFilter(xs, mk_lambda(INT, lambda y: EEq(
                     x, y)))).with_type(INT))).with_type(TMap(INT, INT))
     count = EMapGet(m, i).with_type(INT)
     e2 = ECond(EEq(count, ONE),
                ESingleton(i).with_type(INT_BAG),
                EEmptyList().with_type(INT_BAG)).with_type(INT_BAG)
     assert retypecheck(e2)
     self.assert_same(e1, e2)
Exemplo n.º 18
0
    def test_distinct_foreach(self):
        with io.StringIO() as f:
            codgen = CxxPrinter(out=f)

            bag = EFilter(EVar("v").with_type(TBag(INT)), mk_lambda(INT, lambda x: EBinOp(x, ">", ZERO))).with_type(TBag(INT))
            x = fresh_var(INT)
            v = fresh_var(INT)
            stm = SForEach(x, EUnaryOp(UOp.Distinct, bag).with_type(TSet(INT)), SAssign(v, x))
            codgen.visit(stm)
Exemplo n.º 19
0
def sizeof(e, cardinalities):
    terms = [ONE]
    if is_collection(e.type):
        terms.append(cardinality(e, cardinalities))
    elif isinstance(e.type, TMap):
        ks = EMapKeys(e).with_type(TBag(e.type.k))
        terms.append(cardinality(ks, cardinalities))
        if is_collection(e.type.v):
            vals = EFlatMap(ks, mk_lambda(e.type.k, lambda k: EMapGet(e, k).with_type(e.type.v))).with_type(e.type.v)
            terms.append(cardinality(vals, cardinalities))
    return SymbolicCost(ESum(terms), cardinalities)
Exemplo n.º 20
0
def optimized_count(x, xs):
    if isinstance(xs, EStateVar):
        m = histogram(xs.e)
        m = EStateVar(m).with_type(m.type)
        return EMapGet(m, x).with_type(INT)
    elif isinstance(xs, EBinOp) and xs.op == "-" and isinstance(xs.e2, ESingleton):
        return EBinOp(
            optimized_count(x, xs.e1), "-",
            optimized_cond(optimized_in(xs.e2.e, xs.e1), ONE, ZERO).with_type(INT)).with_type(INT)
    else:
        return ELen(EFilter(xs, mk_lambda(x.type, lambda y: EEq(x, y))).with_type(xs.type)).with_type(INT)
Exemplo n.º 21
0
 def test_map_discovery(self):
     xs = EVar("xs").with_type(INT_BAG)
     y = EVar("y").with_type(INT)
     spec = EFilter(EStateVar(xs), mk_lambda(INT, lambda x: EEq(x, y)))
     assert retypecheck(spec)
     assert check_discovery(
         spec=spec,
         expected=lambda e: isinstance(e, EMapGet) and isinstance(
             e.map, EStateVar) and valid(EEq(e, spec)),
         args=[y],
         state_vars=[xs])
Exemplo n.º 22
0
def optimized_count(x, xs):
    if isinstance(xs, EStateVar):
        m = histogram(xs.e)
        m = EStateVar(m).with_type(m.type)
        return EMapGet(m, x).with_type(INT)
    elif isinstance(xs, EBinOp) and xs.op == "-" and isinstance(xs.e2, ESingleton):
        return EBinOp(
            optimized_count(x, xs.e1), "-",
            optimized_cond(optimized_in(xs.e2.e, xs.e1), ONE, ZERO).with_type(INT)).with_type(INT)
    else:
        return ELen(EFilter(xs, mk_lambda(x.type, lambda y: EEq(x, y))).with_type(xs.type)).with_type(INT)
Exemplo n.º 23
0
 def test_subsub(self):
     xs = EVar("xs").with_type(INT_BAG)
     i = EVar("i").with_type(INT)
     e1 = EBinOp(
         EUnaryOp(UOp.Distinct, xs), "-",
         EBinOp(
             xs, "-",
             ESingleton(i)))
     assert retypecheck(e1)
     m = EMakeMap2(e1.e1,
         mk_lambda(INT, lambda x:
             EUnaryOp(UOp.Length, EFilter(xs,
                 mk_lambda(INT, lambda y:
                     EEq(x, y)))).with_type(INT))).with_type(TMap(INT, INT))
     count = EMapGet(m, i).with_type(INT)
     e2 = ECond(
         EEq(count, ONE),
         ESingleton(i).with_type(INT_BAG),
         EEmptyList().with_type(INT_BAG)).with_type(INT_BAG)
     assert retypecheck(e2)
     self.assert_same(e1, e2)
Exemplo n.º 24
0
 def test_argmin(self):
     xs = EVar("xs").with_type(INT_BAG)
     ys = EVar("ys").with_type(INT_BAG)
     id = mk_lambda(INT, lambda x: x)
     e1 = EArgMin(EBinOp(xs, "+", ys), id)
     e2 = ECond(EUnaryOp(UOp.Empty, xs), EArgMin(ys, id),
          ECond(EUnaryOp(UOp.Empty, ys), EArgMin(xs, id),
             EArgMin(EBinOp(
                 ESingleton(EArgMin(xs, id)),
                 "+",
                 ESingleton(EArgMin(ys, id))), id)))
     assert retypecheck(e1)
     assert retypecheck(e2)
     self.assert_same(e1, e2)
Exemplo n.º 25
0
 def test_argmin(self):
     xs = EVar("xs").with_type(INT_BAG)
     ys = EVar("ys").with_type(INT_BAG)
     id = mk_lambda(INT, lambda x: x)
     e1 = EArgMin(EBinOp(xs, "+", ys), id)
     e2 = ECond(EUnaryOp(UOp.Empty, xs), EArgMin(ys, id),
          ECond(EUnaryOp(UOp.Empty, ys), EArgMin(xs, id),
             EArgMin(EBinOp(
                 ESingleton(EArgMin(xs, id)),
                 "+",
                 ESingleton(EArgMin(ys, id))), id)))
     assert retypecheck(e1)
     assert retypecheck(e2)
     self.assert_same(e1, e2)
Exemplo n.º 26
0
 def test_mapget_of_makemap2(self):
     t = THandle("elem_type", INT)
     xs = EVar("xs").with_type(TBag(t))
     x = EVar("x").with_type(t)
     y = EVar("y").with_type(t)
     mt = TTuple((INT, INT))
     e1 = EMapGet(
         EMakeMap2(xs, ELambda(x,
             ETuple((EGetField(x, "val").with_type(INT), EGetField(y, "val").with_type(INT))).with_type(mt)
             )).with_type(TMap(t, mt)),
         y).with_type(mt)
     e2 = ECond(
         EIn(e1.key, e1.map.e),
         e1.map.value_function.apply_to(EUnaryOp(UOp.The, EFilter(e1.map.e, mk_lambda(e1.map.value_function.arg.type, lambda foo: EEq(foo, e1.key))).with_type(e1.map.e.type)).with_type(e1.map.e.type.elem_type)),
         construct_value(e1.type)).with_type(e1.type)
     self.assert_same(e1, e2)
Exemplo n.º 27
0
 def visit_EMapGet(self, e):
     m = self.visit(e.map)
     k = self.visit(e.key)
     if isinstance(m, EMakeMap2):
         if equality_implies_deep_equality(k.type):
             return self.visit(ECond(
                 EIn(k, m.e),
                 m.value_function.apply_to(k),
                 construct_value(m.type.v)).with_type(m.type.v))
         else:
             return self.visit(EUnaryOp(UOp.The,
                     EMap(
                         EFilter(m.e,
                             mk_lambda(m.type.k, lambda kk: EEq(kk, k))).with_type(TBag(m.type.k)),
                         m.value_function).with_type(TBag(m.type.v))).with_type(m.type.v))
     return EMapGet(m, k).with_type(e.type)
Exemplo n.º 28
0
 def visit_EMapGet(self, e):
     m = self.visit(e.map)
     k = self.visit(e.key)
     if isinstance(m, EMakeMap2):
         if is_simple(k.type):
             return self.visit(ECond(
                 EIn(k, m.e),
                 m.value.apply_to(k),
                 construct_value(m.type.v)).with_type(m.type.v))
         else:
             return self.visit(EUnaryOp(UOp.The,
                     EMap(
                         EFilter(m.e,
                             mk_lambda(m.type.k, lambda kk: EEq(kk, k))).with_type(TBag(m.type.k)),
                         m.value).with_type(TBag(m.type.v))).with_type(m.type.v))
     return EMapGet(m, k).with_type(e.type)
Exemplo n.º 29
0
 def encode(self, e : Exp) -> Exp:
     if isinstance(e, EMakeMinHeap):
         tt = TTuple((e.type.elem_type, e.type.key_type))
         return EMap(e.e, ELambda(e.f.arg, ETuple((e.f.arg, e.f.body)).with_type(tt))).with_type(TBag(tt))
     elif isinstance(e, EMakeMaxHeap):
         tt = TTuple((e.type.elem_type, e.type.key_type))
         return EMap(e.e, ELambda(e.f.arg, ETuple((e.f.arg, e.f.body)).with_type(tt))).with_type(TBag(tt))
     elif isinstance(e, EHeapElems):
         tt = TTuple((e.e.type.elem_type, e.e.type.key_type))
         return EMap(e.e, mk_lambda(tt, lambda arg: ETupleGet(arg, 0).with_type(e.type.t))).with_type(e.type)
     elif isinstance(e, EHeapPeek):
         tt = TTuple((e.e.type.elem_type, e.e.type.key_type))
         f = EArgMin if isinstance(e.e.type, TMinHeap) else EArgMax
         return nth(tt, 0).apply_to(f(e.e, nth(tt, 1)).with_type(tt))
     elif isinstance(e, EHeapPeek2):
         tt = TTuple((e.e.type.elem_type, e.e.type.key_type))
         f = EArgMin if isinstance(e.e.type, TMinHeap) else EArgMax
         best = f(e.e, nth(tt, 1)).with_type(tt)
         return nth(tt, 0).apply_to(f(EBinOp(e.e, "-", ESingleton(best).with_type(TBag(tt))).with_type(TBag(tt)), nth(tt, 1)).with_type(tt))
     else:
         raise NotImplementedError(e)
Exemplo n.º 30
0
Arquivo: heaps.py Projeto: uwplse/cozy
 def encode(self, e : Exp) -> Exp:
     """Convert an expression about heaps to one about bags."""
     if isinstance(e, EMakeMinHeap):
         tt = TTuple((e.type.elem_type, e.type.key_type))
         return EMap(e.e, ELambda(e.key_function.arg, ETuple((e.key_function.arg, e.key_function.body)).with_type(tt))).with_type(TBag(tt))
     elif isinstance(e, EMakeMaxHeap):
         tt = TTuple((e.type.elem_type, e.type.key_type))
         return EMap(e.e, ELambda(e.key_function.arg, ETuple((e.key_function.arg, e.key_function.body)).with_type(tt))).with_type(TBag(tt))
     elif isinstance(e, EHeapElems):
         tt = TTuple((e.e.type.elem_type, e.e.type.key_type))
         return EMap(e.e, mk_lambda(tt, lambda arg: ETupleGet(arg, 0).with_type(e.type.elem_type))).with_type(e.type)
     elif isinstance(e, EHeapPeek):
         tt = TTuple((e.e.type.elem_type, e.e.type.key_type))
         f = EArgMin if isinstance(e.e.type, TMinHeap) else EArgMax
         return nth_func(tt, 0).apply_to(f(e.e, nth_func(tt, 1)).with_type(tt))
     elif isinstance(e, EHeapPeek2):
         tt = TTuple((e.e.type.elem_type, e.e.type.key_type))
         f = EArgMin if isinstance(e.e.type, TMinHeap) else EArgMax
         best = f(e.e, nth_func(tt, 1)).with_type(tt)
         return nth_func(tt, 0).apply_to(f(EBinOp(e.e, "-", ESingleton(best).with_type(TBag(tt))).with_type(TBag(tt)), nth_func(tt, 1)).with_type(tt))
     else:
         raise NotImplementedError(e)
Exemplo n.º 31
0
def _fix_map(m: target_syntax.EMap) -> syntax.Exp:
    return m
    from cozy.simplification import simplify
    m = simplify(m)
    if not isinstance(m, target_syntax.EMap):
        return m
    elem_type = m.e.type.t
    assert m.f.body.type == elem_type
    changed = target_syntax.EFilter(
        m.e,
        mk_lambda(
            elem_type, lambda x: syntax.ENot(
                syntax.EBinOp(x, "===", m.f.apply_to(x)).with_type(syntax.BOOL)
            ))).with_type(m.e.type)
    e = syntax.EBinOp(
        syntax.EBinOp(m.e, "-", changed).with_type(m.e.type), "+",
        target_syntax.EMap(changed,
                           m.f).with_type(m.e.type)).with_type(m.e.type)
    if not valid(syntax.EEq(m, e)):
        print("WARNING: rewrite failed")
        print("_fix_map({!r})".format(m))
        return m
    return e
Exemplo n.º 32
0
def _update_handle(e: syntax.Exp, handle: syntax.EVar, change):
    if isinstance(e.type, syntax.TBag) or isinstance(e.type, syntax.TList):
        return target_syntax.EMap(
            e, mk_lambda(
                e.type.t,
                lambda x: _update_handle(x, handle, change))).with_type(e.type)
    elif isinstance(e.type, syntax.THandle):
        if e.type == handle.type:
            return syntax.ECond(syntax.EEq(e, handle), change(e),
                                e).with_type(e.type)
        else:
            return e
    elif isinstance(e.type, syntax.TTuple):
        return syntax.ETuple(
            tuple(
                _update_handle(
                    syntax.ETupleGet(e, i).with_type(e.type.ts[i]), handle,
                    change) for i in range(len(e.type.ts)))).with_type(e.type)
    elif e.type == syntax.INT or e.type == syntax.LONG or e.type == syntax.BOOL or e.type == syntax.STRING or isinstance(
            e.type, syntax.TNative) or isinstance(e.type, syntax.TEnum):
        return e
    else:
        raise NotImplementedError(repr(e.type))
Exemplo n.º 33
0
 def test_binders(self):
     v1 = EVar("foo")
     e1 = EMap(v1, mk_lambda(TInt(), lambda arg: v1))
     e2 = EMap(v1, mk_lambda(TInt(), lambda arg: v1))
     assert e1.transform_function.arg.id != e2.transform_function.arg.id
     assert alpha_equivalent(e1, e2)
Exemplo n.º 34
0
    def test_argmin(self):
        with io.StringIO() as f:
            codgen = CxxPrinter(out=f)

            bag = EMap(EVar("v").with_type(TBag(INT)), mk_lambda(INT, lambda x: EBinOp(x, ">", ZERO).with_type(BOOL))).with_type(TBag(BOOL))
            print(codgen.visit(EArgMin(bag, mk_lambda(INT, lambda x: EUnaryOp("-", x).with_type(x.type))).with_type(INT)))
Exemplo n.º 35
0
def EForall(e, p):
    from cozy.syntax_tools import mk_lambda
    return EUnaryOp(UOp.All, EMap(e, mk_lambda(e.type.elem_type, p)).with_type(type(e.type)(BOOL))).with_type(BOOL)
Exemplo n.º 36
0
 def test_map_over_noncollection(self):
     x = EVar("x").with_type(TInt())
     e = EMap(x, mk_lambda(TInt(), lambda elem: EBool(True)))
     errs = typecheck(e, { x.id : x.type })
     assert errs
Exemplo n.º 37
0
 def test_map_discovery(self):
     xs = EVar("xs").with_type(INT_BAG)
     y = EVar("y").with_type(INT)
     spec = EFilter(EStateVar(xs), mk_lambda(INT, lambda x: EEq(x, y)))
     assert retypecheck(spec)
     assert check_discovery(spec=spec, expected=lambda e: isinstance(e, EMapGet) and isinstance(e.map, EStateVar) and valid(EEq(e, spec)), args=[y], state_vars=[xs])
Exemplo n.º 38
0
    def build(self, cache, size):

        for e in cache.find(pool=RUNTIME_POOL, size=size - 1, type=INT):
            if not is_root(e):
                continue
            e2 = simplify_sum(e)
            if e != e2:
                yield self.check(e2, RUNTIME_POOL)

        # for e in cache.find(pool=RUNTIME_POOL, size=size-1):
        #     if isinstance(e, EMapGet) and isinstance(e.map, EMakeMap2):
        #         x = e.map.value.apply_to(e.key)
        #         x._tag = True
        #         yield self.check(x, RUNTIME_POOL)

        # [x] - ys
        for e in cache.find_collections(pool=RUNTIME_POOL, size=size - 1):
            if not is_root(e):
                continue
            if isinstance(e, EBinOp) and e.op == "-" and isinstance(
                    e.e1, ESingleton):
                x = e.e1.e
                y = e.e2
                x = ECond(
                    EBinOp(x, BOp.In, y).with_type(BOOL),
                    EEmptyList().with_type(e.type), e.e1).with_type(e.type)
                yield self.check(x, RUNTIME_POOL)
            elif isinstance(e, EUnaryOp) and e.op == UOp.Distinct:
                e = strip_EStateVar(e)
                m = EMakeMap2(e.e, mk_lambda(e.type.t, lambda x: T)).with_type(
                    TMap(e.type.t, BOOL))
                yield self.check(m, STATE_POOL)
                m = EStateVar(m).with_type(m.type)
                yield self.check(m, RUNTIME_POOL)
                x = EMapKeys(m).with_type(e.type)
                # x._tag = True
                yield self.check(x, RUNTIME_POOL)

        # # x in ys ----> (count x in ys) > 0
        # for e in cache.find(pool=RUNTIME_POOL, type=BOOL, size=size-1):
        #     if isinstance(e, EBinOp) and e.op == BOp.In:
        #         for b in self.binders:
        #             if b.type != e.e1.type:
        #                 continue
        #             x = EGt(
        #                 EUnaryOp(UOp.Length, EFilter(e.e2, ELambda(b, EEq(e.e1, b))).with_type(e.e2.type)).with_type(INT),
        #                 ZERO)
        #             x._tag = True
        #             yield self.check(x, RUNTIME_POOL)

        for e in cache.find(pool=RUNTIME_POOL, size=size - 1):
            if not is_root(e):
                continue
            if (isinstance(e, EArgMin) or isinstance(
                    e, EArgMax)) and isinstance(e.e, EBinOp) and e.e.op == "+":
                l = e.e.e1
                r = e.e.e2
                op = e.e.op
                f = lambda x: type(e)(x, e.f).with_type(e.type)
                ll = EStateVar(f(l.e)).with_type(e.type) if isinstance(
                    l, EStateVar) else f(l)
                rr = EStateVar(f(r.e)).with_type(e.type) if isinstance(
                    r, EStateVar) else f(r)
                x = ECond(
                    EUnaryOp(UOp.Exists, l).with_type(BOOL),
                    ECond(
                        EUnaryOp(UOp.Exists, r).with_type(BOOL),
                        f(
                            EBinOp(
                                ESingleton(ll).with_type(e.e.type), op,
                                ESingleton(rr).with_type(e.e.type)).with_type(
                                    e.e.type)), ll).with_type(e.type),
                    rr).with_type(e.type)
                # from cozy.solver import valid
                # assert valid(EEq(e, x), model_callback=print)
                x._tag = True
                yield self.check(x, RUNTIME_POOL)

        # is-last(x, l)
        for (sz1, sz2) in pick_to_sum(2, size - 1):
            for e1 in cache.find(pool=RUNTIME_POOL, size=sz1):
                if not is_root(e1):
                    continue
                for e2 in cache.find_collections(pool=STATE_POOL,
                                                 size=sz2,
                                                 of=e1.type):
                    if not is_root(e2):
                        continue
                    for b in self.binders:
                        if b.type != e1.type:
                            continue
                        m = EMakeMap2(
                            e2,
                            mk_lambda(
                                e2.type.t, lambda x: EUnaryOp(
                                    UOp.Length,
                                    EFilter(
                                        e2,
                                        mk_lambda(e2.type.t, lambda y: EEq(
                                            x, y))).with_type(e2.type)).
                                with_type(INT))).with_type(TMap(
                                    e2.type.t, INT))
                        # filt = EFilter(e2, ELambda(b, EEq(e1, b))).with_type(e2.type)
                        # x = EEq(
                        #     EUnaryOp(UOp.Length, filt).with_type(INT),
                        #     ONE)
                        x = EGt(
                            EMapGet(EStateVar(m).with_type(m.type),
                                    e1).with_type(INT), ONE)
                        # x._tag = True
                        yield self.check(x, RUNTIME_POOL)

        # histogram
        # for e in cache.find_collections(pool=STATE_POOL, size=size-1):
        #     m = EMakeMap2(e,
        #         mk_lambda(e.type.t, lambda x:
        #             EUnaryOp(UOp.Length, EFilter(e,
        #                 mk_lambda(e.type.t, lambda y: EEq(x, y))).with_type(e.type)).with_type(INT))).with_type(TMap(e.type.t, INT))
        #     m._tag = True
        #     yield self.check(m, STATE_POOL)

        # Fixup EFilter(\x -> ECond...)
        for e in cache.find_collections(pool=RUNTIME_POOL, size=size - 1):
            if not is_root(e):
                continue
            if isinstance(e, EFilter):
                for (_, x, r, _) in enumerate_fragments(e.p.body):
                    if isinstance(x, ECond):
                        lhs = EFilter(
                            e.e,
                            ELambda(e.p.arg, EAll([x.cond,
                                                   r(x.then_branch)
                                                   ]))).with_type(e.type)
                        rhs = EFilter(
                            e.e,
                            ELambda(e.p.arg,
                                    EAll([ENot(x.cond),
                                          r(x.else_branch)
                                          ]))).with_type(e.type)
                        union = EBinOp(lhs, "+", rhs).with_type(e.type)
                        # yield self.check(lhs.p.body, RUNTIME_POOL)
                        # yield self.check(rhs.p.body, RUNTIME_POOL)
                        yield self.check(lhs, RUNTIME_POOL)
                        yield self.check(rhs, RUNTIME_POOL)
                        yield self.check(union, RUNTIME_POOL)

        # Try instantiating bound expressions
        for pool in (STATE_POOL, RUNTIME_POOL):
            for (sz1, sz2) in pick_to_sum(2, size - 1):
                for e1 in cache.find(pool=pool, size=sz1):
                    if not is_root(e1):
                        continue
                    for v in free_vars(e1):
                        if pool == RUNTIME_POOL:
                            e1 = subst(
                                strip_EStateVar(e1), {
                                    sv.id: EStateVar(sv).with_type(sv.type)
                                    for sv in self.state_vars if sv != v
                                })
                        for e2 in cache.find(pool=pool, type=v.type, size=sz2):
                            yield self.check(subst(e1, {v.id: e2}), pool)

        for (sz1, sz2) in pick_to_sum(2, size - 1):
            for e in cache.find(pool=RUNTIME_POOL, size=sz1):
                if not is_root(e):
                    continue
                for x, pool in map_accelerate(e, self.state_vars, self.binders,
                                              self.args, cache, sz2):
                    yield self.check(x, pool)
                if isinstance(e, EFilter) and not any(v in self.binders
                                                      for v in free_vars(e)):
                    for x, pool in accelerate_filter(e.e, e.p, self.state_vars,
                                                     self.binders, self.args,
                                                     cache, sz2):
                        yield self.check(x, pool)

        for bag in cache.find_collections(pool=RUNTIME_POOL, size=size - 1):
            if not is_root(bag):
                continue
            for a in self.args:
                for v in self.state_vars:
                    if is_collection(v.type) and v.type == a.type:
                        v = EStateVar(v).with_type(v.type)
                        cond = EBinOp(a, BOp.In, v).with_type(BOOL)
                        yield self.check(
                            EFilter(bag, mk_lambda(bag.type.t,
                                                   lambda _: cond)).with_type(
                                                       bag.type), RUNTIME_POOL)
                        yield self.check(
                            EFilter(
                                bag,
                                mk_lambda(bag.type.t,
                                          lambda _: ENot(cond))).with_type(
                                              bag.type), RUNTIME_POOL)

            if isinstance(bag, EFilter):
                if any(v not in self.state_vars for v in free_vars(bag.e)):
                    continue

                # separate filter conds
                if isinstance(bag.p.body, EBinOp) and bag.p.body.op == BOp.And:
                    p1 = ELambda(bag.p.arg, bag.p.body.e1)
                    p2 = ELambda(bag.p.arg, bag.p.body.e2)
                    f1 = EFilter(bag.e, p1).with_type(bag.type)
                    f2 = EFilter(bag.e, p2).with_type(bag.type)
                    f3 = EFilter(f1, p2).with_type(bag.type)
                    f4 = EFilter(f2, p1).with_type(bag.type)
                    yield self.check(f1, RUNTIME_POOL)
                    yield self.check(f2, RUNTIME_POOL)
                    yield self.check(f3, RUNTIME_POOL)
                    yield self.check(f4, RUNTIME_POOL)

                # construct map lookups
                binder = bag.p.arg
                inf = infer_map_lookup(bag.p.body, binder,
                                       set(self.state_vars))
                if inf:
                    key_proj, key_lookup, remaining_filter = inf
                    bag_binder = find_one(
                        self.binders,
                        lambda b: b.type == key_proj.type and b != binder)
                    if bag_binder:
                        m = strip_EStateVar(
                            EMakeMap2(
                                EMap(bag.e,
                                     ELambda(binder, key_proj)).with_type(
                                         type(bag.type)(key_proj.type)),
                                ELambda(
                                    bag_binder,
                                    EFilter(
                                        bag.e,
                                        ELambda(binder,
                                                EEq(key_proj,
                                                    bag_binder))).with_type(
                                                        bag.type))).with_type(
                                                            TMap(
                                                                key_proj.type,
                                                                bag.type)))
                        assert not any(v in self.args for v in free_vars(m))
                        yield self.check(m, STATE_POOL)
                        m = EStateVar(m).with_type(m.type)
                        mg = EMapGet(m, key_lookup).with_type(bag.type)
                        yield self.check(mg, RUNTIME_POOL)
                        yield self.check(
                            EFilter(mg, ELambda(
                                binder, remaining_filter)).with_type(mg.type),
                            RUNTIME_POOL)

        # for e in cache.find(size=size-1):
        #     # F(xs +/- ys) ---> F(xs), F(ys)
        #     for z in break_plus_minus(e):
        #         if z != e:
        #             # print("broke {} --> {}".format(pprint(e), pprint(z)))
        #             yield z

        #     # try reordering operations
        #     for (_, e1, f) in enumerate_fragments(e):
        #         if e1.type == e.type and e1 != e:
        #             for (_, e2, g) in enumerate_fragments(e1):
        #                 if e2.type == e.type and e2 != e1:
        #                     # e == f(g(e2))
        #                     yield g(f(e2))

        yield from self.wrapped.build(cache, size)
Exemplo n.º 39
0
    def test_len(self):
        with io.StringIO() as f:
            codgen = CxxPrinter(out=f)

            bag = EFilter(EVar("v").with_type(TBag(INT)), mk_lambda(INT, lambda x: EBinOp(x, ">", ZERO))).with_type(TBag(INT))
            print(codgen.visit(EUnaryOp(UOp.Length, bag).with_type(TSet(INT))))
Exemplo n.º 40
0
def EForall(e, p):
    from cozy.syntax_tools import mk_lambda
    return EUnaryOp(
        UOp.All,
        EMap(e, mk_lambda(e.type.t,
                          p)).with_type(type(e.type)(BOOL))).with_type(BOOL)
Exemplo n.º 41
0
def EForall(e, p):
    return EUnaryOp(
        UOp.All,
        EMap(e, mk_lambda(e.type.t,
                          p)).with_type(type(e.type)(BOOL))).with_type(BOOL)
Exemplo n.º 42
0
 def test_lambdas(self):
     employers = EVar("employers").with_type(TBag(TInt()))
     e1 = mk_lambda(employers.type.elem_type, lambda employer: EGetField(EGetField(employer, "val"), "employer_name"))
     e2 = mk_lambda(employers.type.elem_type, lambda employer: EGetField(EGetField(employer, "val"), "employer_name"))
     assert alpha_equivalent(e1, e2)
Exemplo n.º 43
0
def _maintenance_cost(e: Exp, op: Op, freebies: [Exp] = []):
    """Determines the cost of maintaining the expression when there are
    freebies and ops being considered.

    The cost is the result of mutating the expression and getting the storage
    size of the difference between the mutated expression and the original.
    """
    e_prime = mutate(e, op.body)
    if alpha_equivalent(e, e_prime):
        return ZERO

    h = extension_handler(type(e.type))
    if h is not None:
        return h.maintenance_cost(old_value=e,
                                  new_value=e_prime,
                                  op=op,
                                  freebies=freebies,
                                  storage_size=storage_size,
                                  maintenance_cost=_maintenance_cost)

    if is_scalar(e.type):
        return storage_size(e, freebies)
    elif isinstance(e.type, TBag) or isinstance(e.type, TSet):
        things_added = storage_size(
            EBinOp(e_prime, "-", e).with_type(e.type), freebies).with_type(INT)
        things_remov = storage_size(
            EBinOp(e, "-", e_prime).with_type(e.type), freebies).with_type(INT)

        return ESum([things_added, things_remov])
    elif isinstance(e.type, TList):
        return storage_size(e_prime, freebies)
    elif isinstance(e.type, TMap):
        keys = EMapKeys(e).with_type(TBag(e.type.k))
        vals = EMap(
            keys,
            mk_lambda(e.type.k,
                      lambda k: EMapGet(e, k).with_type(e.type.v))).with_type(
                          TBag(e.type.v))

        keys_prime = EMapKeys(e_prime).with_type(TBag(e_prime.type.k))
        vals_prime = EMap(
            keys_prime,
            mk_lambda(e_prime.type.k, lambda k: EMapGet(e_prime, k).with_type(
                e_prime.type.v))).with_type(TBag(e_prime.type.v))

        keys_added = storage_size(
            EBinOp(keys_prime, "-", keys).with_type(keys.type),
            freebies).with_type(INT)
        keys_rmved = storage_size(
            EBinOp(keys, "-", keys_prime).with_type(keys.type),
            freebies).with_type(INT)

        vals_added = storage_size(
            EBinOp(vals_prime, "-", vals).with_type(vals.type),
            freebies).with_type(INT)
        vals_rmved = storage_size(
            EBinOp(vals, "-", vals_prime).with_type(vals.type),
            freebies).with_type(INT)

        keys_difference = ESum([keys_added, keys_rmved])
        vals_difference = ESum([vals_added, vals_rmved])
        return EBinOp(keys_difference, "*", vals_difference).with_type(INT)

    else:
        raise NotImplementedError(repr(e.type))
Exemplo n.º 44
0
    def test_any(self):
        with io.StringIO() as f:
            codgen = CxxPrinter(out=f)

            bag = EMap(EVar("v").with_type(TBag(INT)), mk_lambda(INT, lambda x: EBinOp(x, ">", ZERO).with_type(BOOL))).with_type(TBag(BOOL))
            print(codgen.visit(EUnaryOp(UOp.Any, bag).with_type(TSet(INT))))
Exemplo n.º 45
0
 def test_map_over_noncollection(self):
     x = EVar("x").with_type(TInt())
     e = EMap(x, mk_lambda(TInt(), lambda elem: EBool(True)))
     errs = typecheck(e, {x.id: x.type})
     assert errs