def uses_intrusive_data(e: target_syntax.Exp, handle: target_syntax.Exp) -> target_syntax.Exp: if isinstance(e, target_syntax.EMakeMap): if isinstance(e.e.type, target_syntax.TBag) and e.e.type.t == handle.type: k = e.key.apply_to(handle) kk = syntax_tools.fresh_var(k.type, "k") return uses_intrusive_data( e.value.apply_to( target_syntax.EFilter( e.e, target_syntax.ELambda(handle, syntax_tools.equal(k, kk)))), handle) return target_syntax.F elif isinstance(e, target_syntax.EMakeMap2): if e.e.type.t == handle.type: k = syntax_tools.fresh_var(e.type.k) return target_syntax.EImplies( target_syntax.EBinOp(k, target_syntax.BOp.In, e.e), uses_intrusive_data(e.value.apply_to(k), handle)) return target_syntax.F elif isinstance(e, target_syntax.EFilter): return target_syntax.EAll( [uses_intrusive_data(e.e, handle), e.p.apply_to(handle)]) elif isinstance(e, target_syntax.EEmptyList): return target_syntax.F elif isinstance(e, target_syntax.EMap): return uses_intrusive_data(e.e, handle) elif isinstance(e, target_syntax.EUnaryOp): return uses_intrusive_data(e.e, handle) elif isinstance(e, target_syntax.EBinOp): return uses_intrusive_data(e.e1, handle) or uses_intrusive_data( e.e2, handle) elif isinstance(e, target_syntax.ECond): return target_syntax.ECond(e.cond, uses_intrusive_data(e.then_branch, handle), uses_intrusive_data(e.else_branch, handle)).with_type( target_syntax.BOOL) elif isinstance(e, target_syntax.ESingleton): if e.type.t == handle.type: return target_syntax.EEq(e.e, handle) return target_syntax.F elif isinstance(e, target_syntax.ETuple): return target_syntax.EAny( uses_intrusive_data(ee, handle) for ee in e.es) elif isinstance(e, target_syntax.EVar): if isinstance(e.type, target_syntax.TBag) and e.type.t == handle.type: return target_syntax.EBinOp(handle, target_syntax.BOp.In, e).with_type(target_syntax.BOOL) return target_syntax.F elif type(e) in [ target_syntax.ENum, target_syntax.EBool, target_syntax.EEnumEntry ]: return target_syntax.F else: raise NotImplementedError(e)
def test_no_argument_conflict_lambda(self): x = EVar("x").with_type(TInt()) y = EVar("y").with_type(TInt()) f = ELambda(x, EBinOp(y, "+", ENum(1).with_type(INT))) assert retypecheck(f) g = subst(f, {y.id: x}) a = EVar("a").with_type(TInt()) b = EVar("b").with_type(TInt()) assert valid(equal(g.apply_to(a), g.apply_to(b)))
def implement_remove(self, target, args): assert target.type == self target = shallow_copy(target).with_type(self.rep_type()) elem, = args prev = EGetField(elem, self.prev_ptr).with_type(self.t) next = EGetField(elem, self.next_ptr).with_type(self.t) return seq([ SIf(equal(elem, target), SAssign(target, next), SNoOp()), SIf( ENot(equal(prev, self.null)), SAssign( EGetField(prev, self.next_ptr).with_type(self.t), next), SNoOp()), SIf( ENot(equal(next, self.null)), SAssign( EGetField(next, self.prev_ptr).with_type(self.t), prev), SNoOp()), SAssign(next, self.null), SAssign(prev, self.null) ])
def implement_add(self, target, args): assert target.type == self target = shallow_copy(target).with_type(self.rep_type()) new_elem, = args return seq([ SAssign( EGetField(new_elem, self.next_ptr).with_type(self.t), target), SAssign( EGetField(new_elem, self.prev_ptr).with_type(self.t), self.null), SIf( ENot(equal(target, self.null)), SAssign( EGetField(target, self.prev_ptr).with_type(self.t), new_elem), SNoOp()), SAssign(target, new_elem) ])
def for_each(self, id, iter, body): assert iter.type == self # assert isinstance(iter, EVar), pprint(iter) iter = shallow_copy(iter).with_type(self.rep_type()) assert id.type == self.t next = fresh_name("next") return seq([ SDecl(id.id, iter), SWhile( ENot(equal(id, self.null)), seq([ SDecl(next, EGetField(id, self.next_ptr).with_type(id.type)), body, SAssign(id, EVar(next).with_type(id.type)) ])) ])
def construct_concrete(self, e: Exp, out: Exp): print(pprint(e)) if self == out.type: out = shallow_copy(out).with_type(self.rep_type()) x = fresh_var(self.t, "x") return seq([ SAssign(out, self.null), SForEach( x, e, seq([ SAssign( EGetField(x, self.next_ptr).with_type(self.t), out), SAssign( EGetField(x, self.prev_ptr).with_type(self.t), self.null), SIf( ENot(equal(out, self.null)), SAssign( EGetField(out, self.prev_ptr).with_type(self.t), x), SNoOp()), SAssign(out, x) ])) ])