~/bend-docscommunity

resources/resources.bend source

resources/resources.bend on the hub · documented module

# Bounded capacity pools with affine reservations: reserve, release, split, and combine.import Base# A pool of `capacity` units, `held` of them reserved. `owner` names the pool,# so a reservation cannot return to a different pool.type Pool is Data:  Pool{owner: Nat, capacity: Nat, held: Nat}# A reservation of `amount` units from the pool named `owner`. It is affine:# it cannot be copied, so it is released at most once.type Grant is Type:  Grant{owner: Nat, amount: Nat}type Reserve is Type:  Took{pool: Pool, grant: Grant}  Refused{pool: Pool}type Release is Type:  Released{pool: Pool}  Kept{pool: Pool, grant: Grant}type Split is Type:  Parts{taken: Grant, rest: Grant}  Whole{grant: Grant}type Combine is Type:  Joined{grant: Grant}  Apart{first: Grant, second: Grant}# An empty pool of `capacity` units.def new(owner: Nat, capacity: Nat) -> Pool:  Pool{owner, capacity, 0n}def capacity(p: Pool) -> Nat:  Pool{o, c, h} = p  cdef reserved(p: Pool) -> Nat:  Pool{o, c, h} = p  h# The units that a reserve can still take.def available(p: Pool) -> Nat:  Pool{o, c, h} = p  Nat.sub(c, h)def reserve.go(fits: Bool, +o: Nat, c: Nat, h: Nat, +n: Nat) -> Reserve:  match fits:    case True{}:      Took{Pool{o, c, Nat.add(h, n)}, Grant{o, n}}    case False{}:      Refused{Pool{o, c, h}}# Takes n units when they fit. Refused hands back the pool unchanged.def reserve(p: Pool, +n: Nat) -> Reserve:  Pool{o, +c, +h} = p  reserve.go(Nat.is_le(Nat.add(h, n), c), o, c, h, n)def release.go(ok: Bool, o: Nat, c: Nat, h: Nat, q: Nat, +n: Nat) -> Release:  match ok:    case True{}:      Released{Pool{o, c, Nat.sub(h, n)}}    case False{}:      Kept{Pool{o, c, h}, Grant{q, n}}# Returns g's units to p. Kept hands back both unchanged when g names another# pool or holds more than p has reserved.def release(p: Pool, g: Grant) -> Release:  Pool{+o, c, +h} = p  Grant{+q, +n} = g  release.go(Nat.is_eq(o, q) && Nat.is_le(n, h), o, c, h, q, n)def split.go(fits: Bool, +o: Nat, +a: Nat, +n: Nat) -> Split:  match fits:    case True{}:      Parts{Grant{o, n}, Grant{o, Nat.sub(a, n)}}    case False{}:      Whole{Grant{o, a}}# Splits n units off g. Whole hands back g when it holds fewer than n.def split(g: Grant, +n: Nat) -> Split:  Grant{+o, +a} = g  split.go(Nat.is_le(n, a), o, a, n)def combine.go(same: Bool, o: Nat, a: Nat, q: Nat, b: Nat) -> Combine:  match same:    case True{}:      Joined{Grant{o, Nat.add(a, b)}}    case False{}:      Apart{Grant{o, a}, Grant{q, b}}# Joins two grants of one pool. Apart hands back both when their pools differ.def combine(x: Grant, y: Grant) -> Combine:  Grant{+o, a} = x  Grant{+q, b} = y  combine.go(Nat.is_eq(o, q), o, a, q, b)