def merge_volumes(self, gen, n1, n2, into): changed = fresh_name("changed") new_value = fresh_name("new_value") t = self.the_type # TODO proc = gen.decl(changed, BoolTy(), gen.false_value()) proc += gen.decl(new_value, t) for f, _ in self.spec.lts: f = self.remap[f] proc += gen.set( new_value, gen.min(t, gen.get_field(n1, f), gen.get_field(n2, f))) proc += gen.set( changed, gen.either( changed, gen.not_true(gen.same(gen.get_field(into, f), new_value)))) proc += gen.set(gen.get_field(into, f), new_value) for f, _ in self.spec.gts: f = self.remap[f] proc += gen.set( new_value, gen.max(t, gen.get_field(n1, f), gen.get_field(n2, f))) proc += gen.set( changed, gen.either( changed, gen.not_true(gen.same(gen.get_field(into, f), new_value)))) proc += gen.set(gen.get_field(into, f), new_value) return proc, changed
def __init__(self): # Data structure self.length = fresh_name("length") self.array = fresh_name("array") # Iterator self.idx = fresh_name("index")
def gen_query(self, gen, qvars, parent_structure): field = parent_structure.field if self.stack_iteration: stk = fresh_name("stack") proc = gen.decl(stk, StackTy(self.node_type), gen.new_stack(self.node_type)) proc += gen.stack_size_hint(stk, "100") proc += gen.if_true( gen.not_true(gen.is_null(field(gen, self.root)))) proc += gen.stack_push(stk, field(gen, self.root)) proc += gen.endif() cursor = fresh_name("cursor") prev = fresh_name("prev") proc += gen.decl(cursor, RecordType(), gen.null_value()) proc += gen.decl(prev, RecordType(), gen.null_value()) proc += self._gen_advance(gen, stk, cursor, prev) return proc, [stk, gen.null_value(), cursor] cursor = fresh_name("cursor") proc = gen.decl(cursor, RecordType(), gen.null_value()) proc += gen.if_true(gen.not_true(gen.is_null(field(gen, self.root)))) p, m = self.find_first(gen, field(gen, self.root)) proc += p proc += gen.set(cursor, m) proc += gen.endif() return proc, [gen.null_value(), cursor]
def gen_query(self, gen, qvars, parent_structure): name = parent_structure.field(gen, self.name) vs = collections.OrderedDict() proc = "" for f, t in self.valueImpl.state(): n = fresh_name(f) vs[f] = n proc += gen.decl(n, t) k = fresh_name() proc += gen.decl(k, self.keyTy) proc += self.make_key(gen, k) p, handle = self.lookup(gen, name, k) proc += p proc += gen.if_true(self.handle_exists(gen, name, handle)) sub = fresh_name("substructure") proc += gen.decl(sub, RefTy(self.valueTy), self.read_handle(gen, name, handle)) p, r = self.valueImpl.gen_query(gen, qvars, self.valueTy.instance(sub)) proc += p for lhs, rhs in zip(vs.values(), r): proc += gen.set(lhs, rhs) proc += gen.else_true() r = self.valueImpl.gen_empty(gen, self.valueTy.instance(sub)) for lhs, rhs in zip(vs.values(), r): proc += gen.set(lhs, rhs) proc += gen.endif() return (proc, list(vs.values()) + [k, handle])
def recompute_all_augdata_recursively(self, gen, node, stop, augData=None): """recomputes augdata for [node, node.parent, node.parent.parent, ... stop)""" if augData is None: augData = self.augData proc = "" cursor = fresh_name("cursor") changed = fresh_name("changed") proc += gen.decl(cursor, self.ty, node) proc += gen.decl(changed, BoolTy(), gen.true_value()) proc += gen.while_true( gen.both(changed, gen.not_true(gen.same(cursor, stop)))) oldies = [(fresh_name("old_{}".format(a.real_field)), a.type, a.real_field) for a in augData] if self.balance == BALANCE_AVL: oldies.append( (fresh_name("old_height"), IntTy(), self.height_name)) for (o, t, f) in oldies: proc += gen.decl(o, t, gen.get_field(cursor, f)) for a in augData: proc += self.recompute_augdata(gen, cursor, a) proc += self._recompute_height(gen, cursor) proc += gen.set(changed, gen.false_value()) for (o, t, f) in oldies: proc += gen.set( changed, gen.either(changed, gen.not_true(gen.same(o, gen.get_field(cursor, f))))) proc += gen.set(cursor, gen.get_field(cursor, self.parent_ptr)) proc += gen.endwhile() return proc
def __init__(self): self.name = self.head_ptr = fresh_name("head") self.next_ptr = fresh_name("next") self.prev_ptr = fresh_name("prev") self.prev_cursor_name = fresh_name("prev_cursor") self.cursor_name = fresh_name("cursor") self.ty = RecordType()
def _rotate(self, gen, x, child, parent_structure): otherchild = self.left_ptr if child == self.right_ptr else self.right_ptr proc = gen.comment("rotate {}".format(gen.get_field(x, child))) a = fresh_name("a") b = fresh_name("b") c = fresh_name("c") proc += gen.decl(a, RecordType(), x) # non-null # proc += "assert({}); //1\n".format(gen.not_true(gen.is_null(a))) proc += gen.decl(b, RecordType(), gen.get_field(a, child)) # non-null # proc += "assert({}); //2\n".format(gen.not_true(gen.is_null(b))) proc += gen.decl(c, RecordType(), gen.get_field(b, otherchild)) # maybe null proc += self.replace_node_in_parent(gen, gen.get_field(a, self.parent_ptr), a, b) proc += self.replace_node_in_parent(gen, b, c, a, otherchild) # proc += "assert({}); //3\n".format(gen.same(a, gen.get_field(b, otherchild))) proc += self.replace_node_in_parent(gen, a, b, c, child) # proc += "assert({}); //4\n".format(gen.same(gen.get_field(a, child), c)) proc += self.recompute_all_augdata(gen, a) proc += self.recompute_all_augdata(gen, b) proc += gen.if_true( gen.not_true(gen.is_null(gen.get_field(b, self.parent_ptr)))) proc += self.recompute_all_augdata(gen, gen.get_field(b, self.parent_ptr)) proc += gen.else_true() proc += gen.set(parent_structure.field(gen, self.name), b) proc += gen.endif() # proc += "assert({}); //5\n".format(gen.same(a, gen.get_field(b, otherchild))) # proc += "assert({}); //6\n".format(gen.same(gen.get_field(a, child), c)) return proc
def __init__(self, spec, fields, predicate, stack_iteration=False): self.stack_iteration = stack_iteration self.spec = spec self.field_types = fields self.the_type = NativeTy(fields[spec.lts[0][0]]) self.predicate = predicate self.root = fresh_name("root") self.left_ptr = fresh_name("left") self.right_ptr = fresh_name("right") self.leaf_ptr = fresh_name("leaf") self.stack_name = fresh_name("stack") self.prev_name = fresh_name("prev") self.cursor_name = fresh_name("cursor") self.parent_ptr = fresh_name("parent") self.record_parent_ptr = fresh_name("parent") self.remap = { f: fresh_name(f) for f, _ in (self.spec.lts + self.spec.gts) } myfields = [f for f, _ in spec.lts] + [f for f, _ in spec.gts] self.node_type = TupleTy( collections.OrderedDict([(self.remap[f], NativeTy(fields[f])) for f in myfields])) self.node_type.fields[self.left_ptr] = PointerTy(self.node_type) self.node_type.fields[self.right_ptr] = PointerTy(self.node_type) self.node_type.fields[self.parent_ptr] = PointerTy(self.node_type) self.node_type.fields[self.leaf_ptr] = RecordType() self.node_type = PointerTy(self.node_type)
def __init__(self, fields, predicate, valueImpl): self.name = fresh_name("map") self.valueTy = self._make_value_type(valueImpl) self.keyArgs = make_key_args(fields, predicate) self.keyTy = make_key_type(fields, self.keyArgs) # value in the Tuple self.iterator_key_name = fresh_name("key") self.iterator_handle_name = fresh_name("handle") self.valueImpl = valueImpl # LinkedList, usually
def __init__(self, fields, predicate, valueImpl): super(Hamt, self).__init__(fields, predicate, valueImpl) self.node_ty = TupleTy(dict()) self.node_ty.fields = {'signature': IntTy()} self.node_ty.fields['isLeaf'] = BoolTy() self.node_ty.fields['next'] = ListTy(self.node_ty.name) self.node_ty.fields['values'] = ListTy("Record") # need to be fixed self.node_name = fresh_name("node") self.length_name = fresh_name("length")
def rm(self, gen, idx, parent_structure): rmidx = fresh_name("removal_idx") removed = fresh_name("removed") array = parent_structure.field(gen, self.array) length = parent_structure.field(gen, self.length) proc = gen.decl(rmidx, IntTy(), idx) proc += gen.decl(removed, RecordType(), gen.array_get(array, rmidx)) proc += gen.set(length, gen.sub(length, 1)) proc += gen.array_copy(RecordType(), array, array, src_start=gen.add(rmidx, 1), dst_start=rmidx, amt=gen.sub(length, rmidx)) return (proc, removed)
def find_first(self, gen, tree_root): cursor = fresh_name("cursor") out = fresh_name("first") proc = gen.decl(cursor, self.node_type, tree_root) proc += gen.decl(out, RecordType(), gen.null_value()) proc += gen.while_true(gen.true_value()) # greedy descent until you find a leaf proc += gen.while_true(gen.not_true(self.is_leaf(gen, cursor))) proc += gen.if_true( self.intersects_query(gen, gen.get_field(cursor, self.left_ptr))) proc += gen.set(cursor, gen.get_field(cursor, self.left_ptr)) proc += gen.else_if( self.intersects_query(gen, gen.get_field(cursor, self.right_ptr))) proc += gen.set(cursor, gen.get_field(cursor, self.right_ptr)) proc += gen.else_true() proc += gen.break_loop() proc += gen.endif() proc += gen.endwhile() # if we are at a leaf AND the leaf matches, we're done! proc += gen.if_true( gen.both( self.is_leaf(gen, cursor), self.query_holds(gen, gen.get_field(cursor, self.leaf_ptr)))) proc += gen.set(out, gen.get_field(cursor, self.leaf_ptr)) proc += gen.break_loop() proc += gen.endif() # otherwise, ascend until we can descend to the right and then do so proc += gen.while_true(gen.not_true(gen.same(cursor, tree_root))) parent = fresh_name("parent") proc += gen.decl(parent, self.node_type, gen.get_field(cursor, self.parent_ptr)) proc += gen.if_true( gen.both( gen.same(cursor, gen.get_field(parent, self.left_ptr)), self.intersects_query(gen, gen.get_field(parent, self.right_ptr)))) proc += gen.set(cursor, gen.get_field(parent, self.right_ptr)) proc += gen.break_loop() proc += gen.endif() proc += gen.set(cursor, parent) proc += gen.endwhile() # if we are stuck at the root, then we're done! proc += gen.if_true(gen.same(cursor, tree_root)) proc += gen.break_loop() proc += gen.endif() proc += gen.endwhile() return proc, out
def gen_update(self, gen, fields, x, remap, parent_structure): currently_in = fresh_name("currently_in") belongs_in = fresh_name("belongs_in") proc = gen.decl(currently_in, BoolTy(), self.belongs(gen, x)) proc += gen.decl(belongs_in, BoolTy(), self.belongs(gen, x, remap)) proc += gen.if_true(gen.both(currently_in, belongs_in)) proc += self.ty.gen_update(gen, fields, x, remap, parent_structure) proc += gen.else_if(gen.both(currently_in, gen.not_true(belongs_in))) proc += self.ty.gen_remove(gen, x, parent_structure) proc += gen.else_if(gen.both(gen.not_true(currently_in), belongs_in)) proc += self.ty.gen_insert(gen, x, parent_structure) proc += gen.endif() return proc
def for_each_map_entry(self, m, keyType, valType, body): entryname = fresh_name("entry") kname = fresh_name("key") vname = fresh_name("val") return """for (auto {e} : {m}) {{ {kt} {k} = {e}.first; {vt} {v} = {e}.second; {body} }}\n""".format( kt=keyType.gen_type(self), vt=valType.gen_type(self), k=kname, v=vname, m=m, e=entryname, body=body(kname, vname, self.break_loop))
def gen_advance(self, gen, parent_structure, iterator): prev = iterator.field(gen, self.prev_name) cursor = iterator.field(gen, self.cursor_name) if self.stack_iteration: return self._gen_advance(gen, iterator.field(gen, self.stack_name), cursor, prev) proc = gen.comment("advance") proc += gen.set(prev, cursor) cursor = fresh_name("cursor") proc += gen.decl(cursor, self.node_type, gen.get_field(cursor, self.record_parent_ptr)) proc += gen.while_true(gen.true_value()) # ascend until we can descend to the right and then do so proc += gen.while_true( gen.not_true(gen.is_null(gen.get_field(cursor, self.parent_ptr)))) parent = fresh_name("parent") proc += gen.decl(parent, self.node_type, gen.get_field(cursor, self.parent_ptr)) proc += gen.if_true( gen.both( gen.same(cursor, gen.get_field(parent, self.left_ptr)), self.intersects_query(gen, gen.get_field(parent, self.right_ptr)))) proc += gen.set(cursor, gen.get_field(parent, self.right_ptr)) proc += gen.break_loop() proc += gen.endif() proc += gen.set(cursor, parent) proc += gen.endwhile() # if we are stuck at the root, then we're done! proc += gen.if_true(gen.is_null(gen.get_field(cursor, self.parent_ptr))) proc += gen.set(cursor, gen.null_value()) proc += gen.break_loop() proc += gen.endif() # find the first matching node in this subtree, if it exists p, m = self.find_first(gen, cursor) proc += p # we found the min! proc += gen.if_true(gen.not_true(gen.is_null(m))) proc += gen.set(cursor, m) proc += gen.break_loop() proc += gen.endif() proc += gen.endwhile() return proc
def gen_find_any(self, gen, parent_structure): cursor = fresh_name("cursor") result = fresh_name("result") proc = gen.decl(cursor, self.node_type, parent_structure.field(gen, self.root)) proc += gen.while_true( gen.both(gen.not_true(gen.is_null(cursor)), self.is_leaf(gen, cursor))) proc += gen.set(cursor, gen.get_field(cursor, self.left_ptr)) proc += gen.endif() proc += gen.decl( result, RecordType(), gen.ternary(gen.is_null(cursor), gen.null_value(), gen.get_field(cursor, self.leaf_ptr))) return proc, result
def for_each_map_entry(self, m, keyType, valType, body): entryname = fresh_name("entry") kname = fresh_name("key") vname = fresh_name("val") return """for (Map.Entry<{kt}, {vt}> {e} : {m}) {{ {kt} {k} = e.getKey(); {vt} {v} = e.getValue(); {body} }}\n""".format(kt=keyType.gen_type(self), vt=valType.gen_type(self), k=kname, v=vname, m=m, e=entryname, body=body(kname, vname, self.break_loop))
def iterator_current_substructure(self, gen, parent_structure, iterator): m = parent_structure.field(gen, self.name) handle = iterator.field(gen, self.iterator_handle_name) sub = fresh_name("substructure") proc = gen.decl(sub, RefTy(self.valueTy), self.read_handle(gen, m, handle)) return proc, sub
def gen_remove_in_place(self, gen, parent_structure, iterator): old_prev = fresh_name("old_prev") prev = iterator.field(gen, self.prev_cursor_name) proc = gen.decl(old_prev, self.ty, prev) proc += self.gen_remove(gen, prev, parent_structure=parent_structure) proc += gen.set(prev, gen.null_value()) return proc, old_prev
def gen_next(self, gen, parent_structure, iterator): """returns (proc, result)""" proc, cur = self.gen_current(gen, parent_structure, iterator) oldcursor = fresh_name() proc += gen.decl(oldcursor, RecordType(), cur) proc += self.gen_advance(gen, parent_structure, iterator) return proc, oldcursor
def find_insertion_point(self, gen, x, root, remap={}): ip = fresh_name("insertion_point") proc = gen.decl(ip, self.node_type, root) proc += gen.while_true( gen.not_true(gen.either(gen.is_null(ip), self.is_leaf(gen, ip)))) proc += gen.set(ip, self.select_child(gen, ip, x, remap=remap)) proc += gen.endwhile() return proc, ip
def get_match_node(self, gen, match, node, bits, hashcode, startIndex, length): is_match = fresh_name("isMatch") proc = gen.decl(is_match, BoolTy()) proc += self.match(gen, node, bits, is_match, hashcode, startIndex, length) proc += gen.if_true(gen.not_true(is_match)) proc += gen.set(match, gen.null_value()) proc += gen.else_true() index = fresh_name("index") arg = gen.left_shift( gen.left_shift(gen.get_node_signature(node), gen.sub(gen.sub(32, bits), 1)), 1) proc += gen.decl(index, IntTy(), gen.integer_bitcount(arg)) proc += gen.map_find_handle(gen.get_node_next(node), index, match) proc += gen.endif() return proc
def gen_remove(self, gen, x, parent_structure): name = parent_structure.field(gen, self.name) proc = "" k = fresh_name("key") proc += gen.decl(k, self.keyTy) proc += self.make_key_of_record(gen, x, k) proc += self.gen_remove_at_key(gen, x, parent_structure, k) return proc
def create_substructure_at_key(self, gen, m, k): name = fresh_name() proc = gen.decl(name, self.valueTy) proc += gen.initialize(self.valueTy, name) proc += self.valueImpl.construct( gen, parent_structure=self.valueTy.instance(name)) proc += gen.map_put(m, k, name) return proc
def gen_remove(self, gen, x, parent_structure): x_node = fresh_name("x_node") x_parent = fresh_name("x_parent") x_grandparent = fresh_name("x_grandparent") # x is the root! proc = gen.decl(x_node, self.node_type, gen.get_field(x, self.record_parent_ptr)) proc += gen.if_true( gen.same(x_node, parent_structure.field(gen, self.root))) proc += gen.free(self.node_type, x_node) proc += gen.set(parent_structure.field(gen, self.root), gen.null_value()) proc += gen.else_true() proc += gen.decl(x_parent, self.node_type, gen.get_field(x_node, self.parent_ptr)) sibling = fresh_name("sibling") proc += gen.decl( sibling, self.node_type, gen.ternary( gen.same(gen.get_field(x_parent, self.left_ptr), x_node), gen.get_field(x_parent, self.right_ptr), gen.get_field(x_parent, self.left_ptr))) # x's parent is the root! proc += gen.if_true( gen.same(x_parent, parent_structure.field(gen, self.root))) proc += gen.set(parent_structure.field(gen, self.root), sibling) proc += gen.set(gen.get_field(sibling, self.parent_ptr), gen.null_value()) # x's parent is not the root! proc += gen.else_true() proc += gen.decl(x_grandparent, self.node_type, gen.get_field(x_parent, self.parent_ptr)) proc += self.replace_child(gen, x_grandparent, x_parent, sibling) proc += gen.set(gen.get_field(sibling, self.parent_ptr), x_grandparent) proc += self.recompute_volumes_recursively(gen, x_grandparent) proc += gen.endif() proc += gen.free(self.node_type, x_node) proc += gen.free(self.node_type, x_parent) proc += gen.endif() return proc
def find_match(self, gen, hashcode, node, level): proc = gen.while_true(gen.le(IntTy(), level, 8)) # Bad style match = fresh_name("match") bits = fresh_name("bits") proc += gen.decl(match, NodeTy(self.node_ty.name)) proc += gen.decl(bits, IntTy(), 0) proc += self.get_match_node(gen, match, node, bits, hashcode, gen.mul(self.length_name, level), self.length_name) # if proc += gen.if_true(gen.is_null(match)) proc += gen.break_loop() proc += gen.endif() # end if proc += gen.set(node, match) proc += gen.plus_one(level) proc += gen.endwhile() return proc
def gen_query_one(self, gen, qvars, parent_structure): name = parent_structure.field(gen, self.name) p, h = self.hash(gen, [(NativeTy(self.field_types[k]), v) for (k,(v,)) in self.keyArgs.items()]) proc = p sub = fresh_name("substructure") proc += gen.decl(sub, self.valueTy, gen.array_get(name, self.handle_to_index(gen, name, h))) p, r = self.valueImpl.gen_query_one(gen, qvars, self.valueTy.instance(sub)) proc += p return (proc, r)
def _gen_advance(self, gen, stack, cursor, prev): node = fresh_name("node") proc = gen.set(prev, cursor) proc += gen.set(cursor, gen.null_value()) proc += gen.while_true(gen.not_true(gen.stack_is_empty(stack))) proc += gen.decl(node, self.node_type, gen.stack_peek(stack)) proc += gen.stack_pop(stack) proc += gen.if_true(self.is_leaf(gen, node)) # TODO: determine when this if-check is necessary! It isn't for # Bullet, but it _is_ in general. # proc += gen.if_true(self.query_holds(gen, gen.get_field(node, self.leaf_ptr))) proc += gen.set(cursor, gen.get_field(node, self.leaf_ptr)) proc += gen.break_loop() # proc += gen.endif() proc += gen.else_true() if True: l = fresh_name("left") r = fresh_name("right") proc += gen.decl(l, self.node_type, gen.get_field(node, self.left_ptr)) proc += gen.decl(r, self.node_type, gen.get_field(node, self.right_ptr)) for n in (l, r): proc += gen.if_true(self.intersects_query(gen, n)) proc += gen.stack_push(stack, n) proc += gen.endif() else: proc += gen.if_true(self.intersects_query(gen, node)) proc += gen.stack_push(stack, gen.get_field(node, self.left_ptr)) proc += gen.stack_push(stack, gen.get_field(node, self.right_ptr)) proc += gen.endif() proc += gen.endif() proc += gen.endwhile() return proc
def gen_remove_in_place(self, gen, parent_structure, iterator): to_remove = fresh_name("to_remove") proc = gen.decl(to_remove, self.ty, iterator.field(gen, self.prev_cursor_name)) proc += self.gen_remove(gen, to_remove, parent_structure=parent_structure) proc += gen.set(iterator.field(gen, self.prev_cursor_name), gen.null_value()) return proc, to_remove
def gen_insert(self, gen, x, parent_structure): name = parent_structure.field(gen, self.name) newa = fresh_name("newarray") proc = gen.if_true(gen.gt(FloatTy(), self.current_load(gen, parent_structure), self.load_factor)) proc += gen.decl(newa, ArrayTy(self.valueTy), gen.new_array(self.valueTy, gen.mul(gen.array_size(name), "2"))) class FakeParent(object): def field(self, gen, f): return newa i = fresh_name("i") proc += gen.decl(i, IntTy(), "0") proc += gen.while_true(gen.lt(IntTy(), i, gen.array_size(newa))) proc += gen.initialize(self.valueTy, gen.array_get(newa, i)) proc += self.valueImpl.construct(gen, self.valueTy.instance(gen.array_get(newa, i))) proc += gen.set(i, gen.add(i, 1)) proc += gen.endwhile() proc += gen.set(i, "0") proc += gen.while_true(gen.lt(IntTy(), i, gen.array_size(name))) sub = fresh_name("substructure") proc += gen.decl(sub, self.valueTy, gen.array_get(name, i)) proc += gen.while_true(gen.true_value()) p, y = self.valueImpl.gen_find_any(gen, self.valueTy.instance(sub)) proc += p saved = fresh_name("record") proc += gen.decl(saved, RecordType(), y) proc += gen.if_true(gen.is_null(saved)) proc += gen.break_loop() proc += gen.endif() proc += self.valueImpl.gen_remove(gen, saved, self.valueTy.instance(sub)) proc += self.gen_insert_no_autobalance(gen, saved, FakeParent()) proc += gen.endwhile() proc += gen.set(i, gen.add(i, 1)) proc += gen.endwhile() proc += gen.free(ArrayTy(self.valueTy), name) proc += gen.set(name, newa) proc += gen.endif() proc += self.gen_insert_no_autobalance(gen, x, parent_structure) return proc