motoko 3.1.0 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- {"name":"base","version":"master","files":{"Blob.mo":{"content":"/// Binary blobs\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// An immutable, possibly empty sequence of bytes.\n /// Given `b : Blob`:\n ///\n /// * `b.size() : Nat` returns the number of bytes in the blob;\n /// * `b.vals() : Iter.Iter<Nat8>` returns an iterator to enumerate the bytes of the blob.\n ///\n /// (Direct indexing of Blobs is not yet supported.)\n public type Blob = Prim.Types.Blob;\n\n /// Returns a (non-cryptographic) hash of 'b'\n public let hash : (b : Blob) -> Nat32 = Prim.hashBlob;\n\n /// Returns `x == y`.\n public func equal(x : Blob, y : Blob) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Blob, y : Blob) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Blob, y : Blob) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Blob, y : Blob) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Blob, y : Blob) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Blob, y : Blob) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Blob, y : Blob) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Creates a blob from an array of bytes, by copying each element.\n public let fromArray : [Nat8] -> Blob = Prim.arrayToBlob;\n\n /// Creates a blob from a mutable array of bytes, by copying each element.\n public let fromArrayMut : [var Nat8] -> Blob = Prim.arrayMutToBlob;\n\n /// Creates an array of bytes from a blob, by copying each element.\n public let toArray : Blob -> [Nat8] = Prim.blobToArray;\n\n /// Creates a mutable array of bytes from a blob, by copying each element.\n public let toArrayMut : Blob -> [var Nat8] = Prim.blobToArrayMut;\n\n}\n"},"Buffer.mo":{"content":"/// Class `Buffer<X>` provides a mutable list of elements of type `X`.\n/// The class wraps and resizes an underyling array that holds the elements,\n/// and thus is comparable to ArrayLists or Vectors in other languages.\n///\n/// When required, the current state of a buffer object can be converted to a fixed-size array of its elements.\n/// This is recommended for example when storing a buffer to a stable variable.\n///\n/// Throughout this documentation, two terms come up that can be confused: `size`\n/// and `capacity`. `size` is the length of the list that the buffer represents.\n/// `capacity` is the length of the underyling array that backs this list.\n/// `capacity` >= `size` is an invariant for this class.\n///\n/// Like arrays, elements in the buffer are ordered by indices from 0 to `size`-1.\n///\n/// WARNING: Certain operations are amortized O(1) time, such as `add`, but run\n/// in worst case O(n) time. These worst case runtimes may exceed the cycles limit\n/// per message if the size of the buffer is large enough. Grow these structures\n/// with discretion. All amortized operations below also list the worst case runtime.\n///\n/// Constructor:\n/// The argument `initCapacity` determines the initial capacity of the array.\n/// The underlying array grows by a factor of 1.5 when its current capacity is\n/// exceeded. Further, when the size of the buffer shrinks to be less than 1/4th\n/// of the capacity, the underyling array is shrunk by a factor of 2.\n///\n/// Example:\n/// ```motoko name=initialize\n/// import Buffer \"mo:base/Buffer\";\n///\n/// let buffer = Buffer.Buffer<Nat>(3); // Creates a new Buffer\n/// ```\n///\n/// Runtime: O(initCapacity)\n///\n/// Space: O(initCapacity)\n\nimport Prim \"mo:⛔\";\nimport Result \"Result\";\nimport Order \"Order\";\nimport Array \"Array\";\n\nmodule {\n type Order = Order.Order;\n\n // The following constants are used to manage the capacity.\n // The length of `elements` is increased by `INCREASE_FACTOR` when capacity is reached.\n // The length of `elements` is decreased by `DECREASE_FACTOR` when capacity is strictly less than\n // `DECREASE_THRESHOLD`.\n\n // INCREASE_FACTOR = INCREASE_FACTOR_NUME / INCREASE_FACTOR_DENOM (with floating point division)\n // Keep INCREASE_FACTOR low to minimize cycle limit problem\n private let INCREASE_FACTOR_NUME = 3;\n private let INCREASE_FACTOR_DENOM = 2;\n private let DECREASE_THRESHOLD = 4; // Don't decrease capacity too early to avoid thrashing\n private let DECREASE_FACTOR = 2;\n private let DEFAULT_CAPACITY = 8;\n\n private func newCapacity(oldCapacity : Nat) : Nat {\n if (oldCapacity == 0) {\n 1;\n } else {\n // calculates ceil(oldCapacity * INCREASE_FACTOR) without floats\n ((oldCapacity * INCREASE_FACTOR_NUME) + INCREASE_FACTOR_DENOM - 1) / INCREASE_FACTOR_DENOM;\n };\n };\n\n public class Buffer<X>(initCapacity : Nat) = this {\n var _size : Nat = 0; // avoid name clash with `size()` method\n var elements : [var ?X] = Prim.Array_init(initCapacity, null);\n\n /// Returns the current number of elements in the buffer.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// buffer.size()\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func size() : Nat = _size;\n\n /// Adds a single element to the end of the buffer, doubling\n /// the size of the array if capacity is exceeded.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(0); // add 0 to buffer\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3); // causes underlying array to increase in capacity\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Amortized Runtime: O(1), Worst Case Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func add(element : X) {\n if (_size == elements.size()) {\n reserve(newCapacity(elements.size()));\n };\n elements[_size] := ?element;\n _size += 1;\n };\n\n /// Returns the element at index `index`. Traps if `index >= size`. Indexing is zero-based.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// let x = buffer.get(0); // evaluates to 10\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func get(index : Nat) : X {\n switch (elements[index]) {\n case (?element) element;\n case null Prim.trap(\"Buffer index out of bounds in get\");\n };\n };\n\n /// Returns the element at index `index` as an option.\n /// Returns `null` when `index >= size`. Indexing is zero-based.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// let x = buffer.getOpt(0); // evaluates to ?10\n /// let y = buffer.getOpt(2); // evaluates to null\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func getOpt(index : Nat) : ?X {\n if (index < _size) {\n elements[index];\n } else {\n null;\n };\n };\n\n /// Overwrites the current element at `index` with `element`. Traps if\n /// `index` >= size. Indexing is zero-based.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.put(0, 20); // overwrites 10 at index 0 with 20\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func put(index : Nat, element : X) {\n if (index >= _size) {\n Prim.trap \"Buffer index out of bounds in put\";\n };\n elements[index] := ?element;\n };\n\n /// Removes and returns the last item in the buffer or `null` if\n /// the buffer is empty.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// let x = buffer.removeLast(); // evaluates to ?11\n /// ```\n ///\n /// Amortized Runtime: O(1), Worst Case Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func removeLast() : ?X {\n if (_size == 0) {\n return null;\n };\n\n _size -= 1;\n let lastElement = elements[_size];\n elements[_size] := null;\n\n if (_size < elements.size() / DECREASE_THRESHOLD) {\n // FIXME should this new capacity be a function of _size\n // instead of the current capacity? E.g. _size * INCREASE_FACTOR\n reserve(elements.size() / DECREASE_FACTOR);\n };\n\n lastElement;\n };\n\n /// Removes and returns the element at `index` from the buffer.\n /// All elements with index > `index` are shifted one position to the left.\n /// This may cause a downsizing of the array.\n ///\n /// Traps if index >= size.\n ///\n /// WARNING: Repeated removal of elements using this method is ineffecient\n /// and might be a sign that you should consider a different data-structure\n /// for your use case.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// let x = buffer.remove(1); // evaluates to 11. 11 no longer in list.\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func remove(index : Nat) : X {\n if (index >= _size) {\n Prim.trap \"Buffer index out of bounds in remove\";\n };\n\n let element = elements[index];\n\n // copy elements to new array and shift over in one pass\n if ((_size - 1) : Nat < elements.size() / DECREASE_THRESHOLD) {\n let elements2 = Prim.Array_init<?X>(elements.size() / DECREASE_FACTOR, null);\n\n var i = 0;\n var j = 0;\n label l while (i < _size) {\n if (i == index) {\n i += 1;\n continue l;\n };\n\n elements2[j] := elements[i];\n i += 1;\n j += 1;\n };\n elements := elements2;\n } else {\n // just shift over elements\n var i = index;\n while (i < (_size - 1 : Nat)) {\n elements[i] := elements[i + 1];\n i += 1;\n };\n elements[_size - 1] := null;\n };\n\n _size -= 1;\n\n switch (element) {\n case (?element) {\n element;\n };\n case null {\n Prim.trap \"Malformed buffer in remove\";\n };\n };\n };\n\n /// Resets the buffer. Capacity is set to 8.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// buffer.clear(); // buffer is now empty\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func clear() {\n _size := 0;\n reserve(DEFAULT_CAPACITY);\n };\n\n /// Removes all elements from the buffer for which the predicate returns false.\n /// The predicate is given both the index of the element and the element itself.\n /// This may cause a downsizing of the array.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// buffer.filterEntries(func(_, x) = x % 2 == 0); // only keep even elements\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func filterEntries(predicate : (Nat, X) -> Bool) {\n var numRemoved = 0;\n let keep = Prim.Array_tabulate<Bool>(\n _size,\n func i {\n switch (elements[i]) {\n case (?element) {\n if (predicate(i, element)) {\n true;\n } else {\n numRemoved += 1;\n false;\n };\n };\n case null {\n Prim.trap \"Malformed buffer in filter()\";\n };\n };\n },\n );\n\n let capacity = elements.size();\n\n if ((_size - numRemoved : Nat) < capacity / DECREASE_THRESHOLD) {\n let elements2 = Prim.Array_init<?X>(capacity / DECREASE_FACTOR, null);\n\n var i = 0;\n var j = 0;\n while (i < _size) {\n if (keep[i]) {\n elements2[j] := elements[i];\n i += 1;\n j += 1;\n } else {\n i += 1;\n };\n };\n\n elements := elements2;\n } else {\n var i = 0;\n var j = 0;\n while (i < _size) {\n if (keep[i]) {\n elements[j] := elements[i];\n i += 1;\n j += 1;\n } else {\n i += 1;\n };\n };\n\n while (j < _size) {\n elements[j] := null;\n j += 1;\n };\n };\n\n _size -= numRemoved;\n };\n\n /// Returns the capacity of the buffer (the length of the underlying array).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// let buffer = Buffer.Buffer<Nat>(2); // underlying array has capacity 2\n /// buffer.add(10);\n /// let c1 = buffer.capacity(); // evaluates to 2\n /// buffer.add(11);\n /// buffer.add(12); // causes capacity to increase by factor of 1.5\n /// let c2 = buffer.capacity(); // evaluates to 3\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func capacity() : Nat = elements.size();\n\n /// Changes the capacity to `capacity`. Traps if `capacity` < `size`.\n ///\n /// ```motoko include=initialize\n /// \n /// buffer.reserve(4);\n /// buffer.add(10);\n /// buffer.add(11);\n /// let c = buffer.capacity(); // evaluates to 4\n /// ```\n ///\n /// Runtime: O(capacity)\n ///\n /// Space: O(capacity)\n public func reserve(capacity : Nat) {\n if (capacity < _size) {\n Prim.trap \"capacity must be >= size in reserve\";\n };\n\n let elements2 = Prim.Array_init<?X>(capacity, null);\n\n var i = 0;\n while (i < _size) {\n elements2[i] := elements[i];\n i += 1;\n };\n elements := elements2;\n };\n\n /// Adds all elements in buffer `b` to this buffer.\n ///\n /// ```motoko include=initialize\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(10);\n /// buffer1.add(11);\n /// buffer2.add(12);\n /// buffer2.add(13);\n /// buffer1.append(buffer2); // adds elements from buffer2 to buffer1\n /// Buffer.toArray(buffer1)\n /// ```\n ///\n /// Amortized Runtime: O(size2), Worst Case Runtime: O(size1 + size2)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size1 + size2)\n public func append(buffer2 : Buffer<X>) {\n let size2 = buffer2.size();\n // Make sure you only allocate a new array at most once\n if (_size + size2 > elements.size()) {\n // FIXME would be nice to have a tabulate for var arrays here\n reserve(newCapacity(_size + size2));\n };\n var i = 0;\n while (i < size2) {\n elements[_size + i] := buffer2.getOpt i;\n i += 1;\n };\n\n _size += size2;\n };\n\n /// Inserts `element` at `index`, shifts all elements to the right of\n /// `index` over by one index. Traps if `index` is greater than size.\n ///\n /// ```motoko include=initialize\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.insert(1, 9);\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func insert(index : Nat, element : X) {\n if (index > _size) {\n Prim.trap \"Buffer index out of bounds in insert\";\n };\n let capacity = elements.size();\n\n if (_size + 1 > capacity) {\n let capacity = elements.size();\n let elements2 = Prim.Array_init<?X>(newCapacity capacity, null);\n var i = 0;\n while (i < _size + 1) {\n if (i < index) {\n elements2[i] := elements[i];\n } else if (i == index) {\n elements2[i] := ?element;\n } else {\n elements2[i] := elements[i - 1];\n };\n\n i += 1;\n };\n elements := elements2;\n } else {\n var i : Nat = _size;\n while (i > index) {\n elements[i] := elements[i - 1];\n i -= 1;\n };\n elements[index] := ?element;\n };\n\n _size += 1;\n };\n\n /// Inserts `buffer2` at `index`, and shifts all elements to the right of\n /// `index` over by size2. Traps if `index` is greater than size.\n ///\n /// ```motoko include=initialize\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(10);\n /// buffer1.add(11);\n /// buffer2.add(12);\n /// buffer2.add(13);\n /// buffer1.insertBuffer(1, buffer2);\n /// Buffer.toArray(buffer1)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size1 + size2)\n public func insertBuffer(index : Nat, buffer2 : Buffer<X>) {\n if (index > _size) {\n Prim.trap \"Buffer index out of bounds in insertBuffer\";\n };\n\n let size2 = buffer2.size();\n let capacity = elements.size();\n\n // copy elements to new array and shift over in one pass\n if (_size + size2 > capacity) {\n let elements2 = Prim.Array_init<?X>(newCapacity(_size + size2), null);\n var i = 0;\n for (element in elements.vals()) {\n if (i == index) {\n i += size2;\n };\n elements2[i] := element;\n i += 1;\n };\n\n i := 0;\n while (i < size2) {\n elements2[i + index] := buffer2.getOpt(i);\n i += 1;\n };\n elements := elements2;\n } // just insert\n else {\n var i = index;\n while (i < index + size2) {\n if (i < _size) {\n elements[i + size2] := elements[i];\n };\n elements[i] := buffer2.getOpt(i - index);\n\n i += 1;\n };\n };\n\n _size += size2;\n };\n\n /// Sorts the elements in the buffer according to `compare`.\n /// Sort is deterministic, stable, and in-place.\n ///\n /// ```motoko include=initialize\n /// \n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(11);\n /// buffer.add(12);\n /// buffer.add(10);\n /// buffer.sort(Nat.compare);\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n public func sort(compare : (X, X) -> Order.Order) {\n // Stable merge sort in a bottom-up iterative style\n if (_size == 0) {\n return;\n };\n let scratchSpace = Prim.Array_init<?X>(_size, null);\n\n let sizeDec = _size - 1 : Nat;\n var currSize = 1; // current size of the subarrays being merged\n // when the current size == size, the array has been merged into a single sorted array\n while (currSize < _size) {\n var leftStart = 0; // selects the current left subarray being merged\n while (leftStart < sizeDec) {\n let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {\n leftStart + currSize - 1;\n } else { sizeDec };\n let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {\n leftStart + (2 * currSize) - 1;\n } else { sizeDec };\n\n // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]\n var left = leftStart;\n var right = mid + 1;\n var nextSorted = leftStart;\n while (left < mid + 1 and right < rightEnd + 1) {\n let leftOpt = elements[left];\n let rightOpt = elements[right];\n switch (leftOpt, rightOpt) {\n case (?leftElement, ?rightElement) {\n switch (compare(leftElement, rightElement)) {\n case (#less or #equal) {\n scratchSpace[nextSorted] := leftOpt;\n left += 1;\n };\n case (#greater) {\n scratchSpace[nextSorted] := rightOpt;\n right += 1;\n };\n };\n };\n case (_, _) {\n // only sorting non-null items\n Prim.trap \"Malformed buffer in sort\";\n };\n };\n nextSorted += 1;\n };\n while (left < mid + 1) {\n scratchSpace[nextSorted] := elements[left];\n nextSorted += 1;\n left += 1;\n };\n while (right < rightEnd + 1) {\n scratchSpace[nextSorted] := elements[right];\n nextSorted += 1;\n right += 1;\n };\n\n // Copy over merged elements\n var i = leftStart;\n while (i < rightEnd + 1) {\n elements[i] := scratchSpace[i];\n i += 1;\n };\n\n leftStart += 2 * currSize;\n };\n currSize *= 2;\n };\n };\n\n /// Returns an Iterator (`Iter`) over the elements of this buffer.\n /// Iterator provides a single method `next()`, which returns\n /// elements in order, or `null` when out of elements to iterate over.\n ///\n /// ```motoko include=initialize\n ///\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n ///\n /// var sum = 0;\n /// for (element in buffer.vals()) {\n /// sum += element;\n /// };\n /// sum\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func vals() : { next : () -> ?X } = object {\n // FIXME either handle modification to underlying list\n // or explicitly warn users in documentation\n var nextIndex = 0;\n public func next() : ?X {\n if (nextIndex >= _size) {\n return null;\n };\n let nextElement = elements[nextIndex];\n nextIndex += 1;\n nextElement;\n };\n };\n\n // FOLLOWING METHODS ARE DEPRECATED\n\n /// @deprecated Use static library function instead.\n public func clone() : Buffer<X> {\n let newBuffer = Buffer<X>(elements.size());\n for (element in vals()) {\n newBuffer.add(element);\n };\n newBuffer;\n };\n\n /// @deprecated Use static library function instead.\n public func toArray() : [X] =\n // immutable clone of array\n Prim.Array_tabulate<X>(\n _size,\n func(i : Nat) : X { get i },\n );\n\n /// @deprecated Use static library function instead.\n public func toVarArray() : [var X] {\n if (_size == 0) { [var] } else {\n let newArray = Prim.Array_init<X>(_size, get 0);\n var i = 0;\n for (element in vals()) {\n newArray[i] := element;\n i += 1;\n };\n newArray;\n };\n };\n };\n\n /// Returns true iff the buffer is empty.\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func isEmpty<X>(buffer : Buffer<X>) : Bool = buffer.size() == 0;\n\n /// Returns true iff `buffer` contains `element` with respect to equality\n /// defined by `equal`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func contains<X>(buffer : Buffer<X>, element : X, equal : (X, X) -> Bool) : Bool {\n for (current in buffer.vals()) {\n if (equal(current, element)) {\n return true;\n };\n };\n\n false;\n };\n\n /// Returns a copy of `buffer`, with the same capacity.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func clone<X>(buffer : Buffer<X>) : Buffer<X> {\n let newBuffer = Buffer<X>(buffer.capacity());\n for (element in buffer.vals()) {\n newBuffer.add(element);\n };\n newBuffer;\n };\n\n /// Finds the greatest element in `buffer` defined by `compare`.\n /// Returns `null` if `buffer` is empty.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func max<X>(buffer : Buffer<X>, compare : (X, X) -> Order) : ?X {\n if (buffer.size() == 0) {\n return null;\n };\n\n var maxSoFar = buffer.get(0);\n for (current in buffer.vals()) {\n switch (compare(current, maxSoFar)) {\n case (#greater) {\n maxSoFar := current;\n };\n case _ {};\n };\n };\n\n ?maxSoFar;\n };\n\n /// Finds the least element in `buffer` defined by `compare`.\n /// Returns `null` if `buffer` is empty.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func min<X>(buffer : Buffer<X>, compare : (X, X) -> Order) : ?X {\n if (buffer.size() == 0) {\n return null;\n };\n\n var minSoFar = buffer.get(0);\n for (current in buffer.vals()) {\n switch (compare(current, minSoFar)) {\n case (#less) {\n minSoFar := current;\n };\n case _ {};\n };\n };\n\n ?minSoFar;\n };\n\n /// Defines equality for two buffers, using `equal` to recursively compare elements in the\n /// buffers. Returns true iff the two buffers are of the same size, and `equal`\n /// evaluates to true for every pair of elements in the two buffers of the same\n /// index.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func equal<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let size1 = buffer1.size();\n\n if (size1 != buffer2.size()) {\n return false;\n };\n\n var i = 0;\n while (i < size1) {\n if (not equal(buffer1.get(i), buffer2.get(i))) {\n return false;\n };\n i += 1;\n };\n\n true;\n };\n\n /// Defines comparison for two buffers, using `compare` to recursively compare elements in the\n /// buffers. Comparison is defined lexicographically.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func compare<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, compare : (X, X) -> Order.Order) : Order.Order {\n let size1 = buffer1.size();\n let size2 = buffer2.size();\n let minSize = if (size1 < size2) { size1 } else { size2 };\n\n var i = 0;\n while (i < minSize) {\n switch (compare(buffer1.get(i), buffer2.get(i))) {\n case (#less) {\n return #less;\n };\n case (#greater) {\n return #greater;\n };\n case _ {};\n };\n i += 1;\n };\n\n if (size1 < size2) {\n #less;\n } else if (size1 == size2) {\n #equal;\n } else {\n #greater;\n };\n };\n\n /// Creates a textual representation of `buffer`, using `toText` to recursively\n /// convert the elements into Text.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `toText` runs in O(1) time and space.\n public func toText<X>(buffer : Buffer<X>, toText : X -> Text) : Text {\n let size : Int = buffer.size();\n var i = 0;\n var text = \"\";\n while (i < size - 1) {\n text := text # toText(buffer.get(i)) # \", \"; // Text implemented as rope\n i += 1;\n };\n if (size > 0) {\n // avoid the trailing comma\n text := text # toText(buffer.get(i));\n };\n\n \"[\" # text # \"]\";\n };\n\n /// Hashes `buffer` using `hash` to hash the underlying elements.\n /// The deterministic hash function is a function of the elements in the Buffer, as well\n /// as their ordering.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `hash` runs in O(1) time and space.\n public func hash<X>(buffer : Buffer<X>, hash : X -> Nat32) : Nat32 {\n let size = buffer.size();\n var i = 0;\n var accHash : Nat32 = 0;\n\n while (i < size) {\n accHash := Prim.intToNat32Wrap(i) ^ accHash ^ hash(buffer.get(i));\n i += 1;\n };\n\n accHash;\n };\n\n /// Finds the first index of `element` in `buffer` using equality of elements defined\n /// by `equal`. Returns `null` if `element` is not found.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func indexOf<X>(element : X, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n let size = buffer.size();\n var i = 0;\n while (i < size) {\n if (equal(buffer.get(i), element)) {\n return ?i;\n };\n i += 1;\n };\n\n null;\n };\n\n /// Finds the last index of `element` in `buffer` using equality of elements defined\n /// by `equal`. Returns `null` if `element` is not found.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func lastIndexOf<X>(element : X, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n let size = buffer.size();\n if (size == 0) {\n return null;\n };\n var i = size;\n while (i >= 1) {\n i -= 1;\n if (equal(buffer.get(i), element)) {\n return ?i;\n };\n };\n\n null;\n };\n\n /// Searches for `subBuffer` in `buffer`, and returns the starting index if it is found.\n ///\n /// Runtime: O(size of buffer + size of subBuffer)\n ///\n /// Space: O(size of subBuffer)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func indexOfBuffer<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n // Uses the KMP substring search algorithm\n // Implementation from: https://www.educative.io/answers/what-is-the-knuth-morris-pratt-algorithm\n let size = buffer.size();\n let subSize = subBuffer.size();\n if (subSize > size or subSize == 0) {\n return null;\n };\n\n // precompute lps\n let lps = Prim.Array_init<Nat>(subSize, 0);\n var i = 0;\n var j = 1;\n\n while (j < subSize) {\n if (equal(subBuffer.get(i), subBuffer.get(j))) {\n i += 1;\n lps[j] := i;\n j += 1;\n } else if (i == 0) {\n lps[j] := 0;\n j += 1;\n } else {\n i := lps[i - 1];\n };\n };\n\n // start search\n i := 0;\n j := 0;\n let subSizeDec = subSize - 1 : Nat; // hoisting loop invariant\n while (i < subSize and j < size) {\n if (equal(subBuffer.get(i), buffer.get(j)) and i == subSizeDec) {\n return ?(j - i);\n } else if (equal(subBuffer.get(i), buffer.get(j))) {\n i += 1;\n j += 1;\n } else {\n if (i != 0) {\n i := lps[i - 1];\n } else {\n j += 1;\n };\n };\n };\n\n null;\n };\n\n /// Similar to indexOf, but runs in logarithmic time. Assumes that `buffer` is sorted.\n /// Behavior is undefined if `buffer` is not sorted. Uses `compare` to\n /// perform the search. Returns an index of `element` if it is found.\n ///\n /// Runtime: O(log(size))\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func binarySearch<X>(element : X, buffer : Buffer<X>, compare : (X, X) -> Order.Order) : ?Nat {\n var low = 0;\n var high = buffer.size();\n\n while (low < high) {\n let mid = (low + high) / 2;\n let current = buffer.get(mid);\n switch (compare(element, current)) {\n case (#equal) {\n return ?mid;\n };\n case (#less) {\n high := mid;\n };\n case (#greater) {\n low := mid + 1;\n };\n };\n };\n\n null;\n };\n\n /// Returns the sub-buffer of `buffer` starting at index `start`\n /// of length `length`. Traps if `start` is out of bounds, or `start + length`\n /// is greater than the size of `buffer`.\n ///\n /// Runtime: O(length)\n ///\n /// Space: O(length)\n public func subBuffer<X>(buffer : Buffer<X>, start : Nat, length : Nat) : Buffer<X> {\n let size = buffer.size();\n let end = start + length; // exclusive\n if (start >= size or end > size) {\n Prim.trap \"Buffer index out of bounds in subBuffer\";\n };\n\n let newBuffer = Buffer<X>(newCapacity length);\n\n var i = start;\n while (i < end) {\n newBuffer.add(buffer.get(i));\n\n i += 1;\n };\n\n newBuffer;\n };\n\n /// Checks if `subBuffer` is a sub-Buffer of `buffer`. Uses `equal` to\n /// compare elements.\n ///\n /// Runtime: O(size of subBuffer + size of buffer)\n ///\n /// Space: O(size of subBuffer)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isSubBufferOf<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n switch (indexOfBuffer(subBuffer, buffer, equal)) {\n case null subBuffer.size() == 0;\n case _ true;\n };\n };\n\n /// Checks if `subBuffer` is a strict subBuffer of `buffer`, i.e. `subBuffer` must be\n /// strictly contained inside both the first and last indices of `buffer`.\n /// Uses `equal` to compare elements.\n ///\n /// Runtime: O(size of subBuffer + size of buffer)\n ///\n /// Space: O(size of subBuffer)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isStrictSubBufferOf<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let subBufferSize = subBuffer.size();\n\n switch (indexOfBuffer(subBuffer, buffer, equal)) {\n case (?index) {\n index != 0 and index != (buffer.size() - subBufferSize : Nat) // enforce strictness\n };\n case null {\n subBufferSize == 0 and subBufferSize != buffer.size();\n };\n };\n };\n\n /// Returns the prefix of `buffer` of length `length`. Traps if `length`\n /// is greater than the size of `buffer`.\n ///\n /// Runtime: O(length)\n ///\n /// Space: O(length)\n public func prefix<X>(buffer : Buffer<X>, length : Nat) : Buffer<X> {\n let size = buffer.size();\n if (length > size) {\n Prim.trap \"Buffer index out of bounds in prefix\";\n };\n\n let newBuffer = Buffer<X>(newCapacity length);\n\n var i = 0;\n while (i < length) {\n newBuffer.add(buffer.get(i));\n i += 1;\n };\n\n newBuffer;\n };\n\n /// Checks if `prefix` is a prefix of `buffer`. Uses `equal` to\n /// compare elements.\n ///\n /// Runtime: O(size of prefix)\n ///\n /// Space: O(size of prefix)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isPrefixOf<X>(prefix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let sizePrefix = prefix.size();\n if (buffer.size() < sizePrefix) {\n return false;\n };\n\n var i = 0;\n while (i < sizePrefix) {\n if (not equal(buffer.get(i), prefix.get(i))) {\n return false;\n };\n\n i += 1;\n };\n\n return true;\n };\n\n /// Checks if `prefix` is a strict prefix of `buffer`. Uses `equal` to\n /// compare elements.\n ///\n /// Runtime: O(size of prefix)\n ///\n /// Space: O(size of prefix)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isStrictPrefixOf<X>(prefix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n if (buffer.size() <= prefix.size()) {\n return false;\n };\n isPrefixOf(prefix, buffer, equal);\n };\n\n /// Returns the suffix of `buffer` of length `length`.\n /// Traps if `length`is greater than the size of `buffer`.\n ///\n /// Runtime: O(length)\n ///\n /// Space: O(length)\n public func suffix<X>(buffer : Buffer<X>, length : Nat) : Buffer<X> {\n let size = buffer.size();\n\n if (length > size) {\n Prim.trap \"Buffer index out of bounds in suffix\";\n };\n\n let newBuffer = Buffer<X>(newCapacity length);\n\n var i = size - length : Nat;\n while (i < size) {\n newBuffer.add(buffer.get(i));\n\n i += 1;\n };\n\n newBuffer;\n };\n\n /// Checks if `suffix` is a suffix of `buffer`. Uses `equal` to compare\n /// elements.\n ///\n /// Runtime: O(length of suffix)\n ///\n /// Space: O(length of suffix)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isSuffixOf<X>(suffix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let suffixSize = suffix.size();\n let bufferSize = buffer.size();\n if (bufferSize < suffixSize) {\n return false;\n };\n\n var i = bufferSize;\n var j = suffixSize;\n while (i >= 1 and j >= 1) {\n i -= 1;\n j -= 1;\n if (not equal(buffer.get(i), suffix.get(j))) {\n return false;\n };\n };\n\n return true;\n };\n\n /// Checks if `suffix` is a strict suffix of `buffer`. Uses `equal` to compare\n /// elements.\n ///\n /// Runtime: O(length of suffix)\n ///\n /// Space: O(length of suffix)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isStrictSuffixOf<X>(suffix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n if (buffer.size() <= suffix.size()) {\n return false;\n };\n isSuffixOf(suffix, buffer, equal);\n };\n\n /// Returns true iff every element in `buffer` satisfies `predicate`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func forAll<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n for (element in buffer.vals()) {\n if (not predicate element) {\n return false;\n };\n };\n\n true;\n };\n\n /// Returns true iff some element in `buffer` satisfies `predicate`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func forSome<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n for (element in buffer.vals()) {\n if (predicate element) {\n return true;\n };\n };\n\n false;\n };\n\n /// Returns true iff no element in `buffer` satisfies `predicate`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func forNone<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n for (element in buffer.vals()) {\n if (predicate element) {\n return false;\n };\n };\n\n true;\n };\n\n /// Creates an array containing elements from `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toArray<X>(buffer : Buffer<X>) : [X] =\n // immutable clone of array\n Prim.Array_tabulate<X>(\n buffer.size(),\n func(i : Nat) : X { buffer.get(i) },\n );\n\n /// Creates a mutable array containing elements from `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toVarArray<X>(buffer : Buffer<X>) : [var X] {\n let size = buffer.size();\n if (size == 0) { [var] } else {\n let newArray = Prim.Array_init<X>(size, buffer.get(0));\n var i = 1;\n while (i < size) {\n newArray[i] := buffer.get(i);\n i += 1;\n };\n newArray;\n };\n };\n\n /// Creates a buffer containing elements from `array`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromArray<X>(array : [X]) : Buffer<X> {\n // When returning new buffer, if possible, set the capacity\n // to the capacity of the old buffer. Otherwise, return them\n // at 2/3 capacity (like in this case). Alternative is to\n // calculate what the size would be if the elements were\n // sequentially added using `add`. This current strategy (2/3)\n // is the upper bound of that calculation (if the last element\n // added caused a capacity increase).\n let newBuffer = Buffer<X>(newCapacity(array.size()));\n\n for (element in array.vals()) {\n newBuffer.add(element);\n };\n\n newBuffer;\n };\n\n /// Creates a buffer containing elements from `array`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromVarArray<X>(array : [var X]) : Buffer<X> {\n let newBuffer = Buffer<X>(newCapacity(array.size()));\n\n for (element in array.vals()) {\n newBuffer.add(element);\n };\n\n newBuffer;\n };\n\n /// Creates a buffer containing elements from `iter`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromIter<X>(iter : { next : () -> ?X }) : Buffer<X> {\n let newBuffer = Buffer<X>(DEFAULT_CAPACITY); // can't get size from `iter`\n\n for (element in iter) {\n newBuffer.add(element);\n };\n\n newBuffer;\n };\n\n /// Reallocates the array underlying `buffer` such that capacity == size.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func trimToSize<X>(buffer : Buffer<X>) {\n let size = buffer.size();\n if (size < buffer.capacity()) {\n buffer.reserve(size);\n };\n };\n\n /// Creates a new buffer by applying `f` to each element in `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func map<X, Y>(buffer : Buffer<X>, f : X -> Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n newBuffer.add(f element);\n };\n\n newBuffer;\n };\n\n /// Applies `f` to each element in `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func iterate<X>(buffer : Buffer<X>, f : X -> ()) {\n for (element in buffer.vals()) {\n f element;\n };\n };\n\n /// Applies `f` to each element in `buffer` and its index.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapEntries<X, Y>(buffer : Buffer<X>, f : (Nat, X) -> Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n var i = 0;\n let size = buffer.size();\n while (i < size) {\n newBuffer.add(f(i, buffer.get(i)));\n i += 1;\n };\n\n newBuffer;\n };\n\n /// Creates a new buffer by applying `f` to each element in `buffer`,\n /// and keeping all non-null elements.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapFilter<X, Y>(buffer : Buffer<X>, f : X -> ?Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n switch (f element) {\n case (?element) {\n newBuffer.add(element);\n };\n case _ {};\n };\n };\n\n newBuffer;\n };\n\n /// Creates a new buffer by applying `f` to each element in `buffer`.\n /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n /// Returns an `#ok` containing the new buffer.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapResult<X, Y, E>(buffer : Buffer<X>, f : X -> Result.Result<Y, E>) : Result.Result<Buffer<Y>, E> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n switch (f element) {\n case (#ok result) {\n newBuffer.add(result);\n };\n case (#err e) {\n return #err e;\n };\n };\n };\n\n #ok newBuffer;\n };\n\n /// Creates a new buffer by applying `k` to each element in `buffer`,\n /// and concatenating the resulting buffers in order. This operation\n /// is similar to what in other functional languages is known as monadic bind.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `k` runs in O(1) time and space.\n public func chain<X, Y>(buffer : Buffer<X>, k : X -> Buffer<Y>) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.size() * 4);\n\n for (element in buffer.vals()) {\n newBuffer.append(k element);\n };\n\n newBuffer;\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldLeft<A, X>(buffer : Buffer<X>, base : A, combine : (A, X) -> A) : A {\n var accumulation = base;\n\n for (element in buffer.vals()) {\n accumulation := combine(accumulation, element);\n };\n\n accumulation;\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldRight<X, A>(buffer : Buffer<X>, base : A, combine : (X, A) -> A) : A {\n let size = buffer.size();\n if (size == 0) {\n return base;\n };\n var accumulation = base;\n\n var i = size;\n while (i >= 1) {\n i -= 1; // to avoid Nat underflow, subtract first and stop iteration at 1\n accumulation := combine(buffer.get(i), accumulation);\n };\n\n accumulation;\n };\n\n /// Returns the first element of `buffer`. Traps if `buffer` is empty.\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func first<X>(buffer : Buffer<X>) : X = buffer.get(0);\n\n /// Returns the last element of `buffer`. Traps if `buffer` is empty.\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func last<X>(buffer : Buffer<X>) : X = buffer.get(buffer.size() - 1);\n\n /// Returns a new buffer with capacity and size 1, containing `element`.\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func make<X>(element : X) : Buffer<X> {\n let newBuffer = Buffer<X>(1);\n newBuffer.add(element);\n newBuffer;\n };\n\n /// Reverses the order of elements in `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func reverse<X>(buffer : Buffer<X>) {\n let size = buffer.size();\n if (size == 0) {\n return;\n };\n\n var i = 0;\n var j = size - 1 : Nat;\n var temp = buffer.get(0);\n while (i < size / 2) {\n temp := buffer.get(j);\n buffer.put(j, buffer.get(i));\n buffer.put(i, temp);\n i += 1;\n j -= 1;\n };\n };\n\n /// Merges two sorted buffers into a single sorted buffer, using `compare` to define\n /// the ordering. The final ordering is stable. Behavior is undefined if either\n /// `buffer1` or `buffer2` is not sorted.\n ///\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(size1 + size2)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func merge<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, compare : (X, X) -> Order) : Buffer<X> {\n let size1 = buffer1.size();\n let size2 = buffer2.size();\n\n let newBuffer = Buffer<X>(newCapacity(size1 + size2));\n\n var pointer1 = 0;\n var pointer2 = 0;\n\n while (pointer1 < size1 and pointer2 < size2) {\n let current1 = buffer1.get(pointer1);\n let current2 = buffer2.get(pointer2);\n\n switch (compare(current1, current2)) {\n case (#less) {\n newBuffer.add(current1);\n pointer1 += 1;\n };\n case _ {\n newBuffer.add(current2);\n pointer2 += 1;\n };\n };\n };\n\n while (pointer1 < size1) {\n newBuffer.add(buffer1.get(pointer1));\n pointer1 += 1;\n };\n\n while (pointer2 < size2) {\n newBuffer.add(buffer2.get(pointer2));\n pointer2 += 1;\n };\n\n newBuffer;\n };\n\n /// Eliminates all duplicate elements in `buffer` as defined by `compare`.\n /// Elimination is stable with respect to the original ordering of the elements.\n ///\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n public func removeDuplicates<X>(buffer : Buffer<X>, compare : (X, X) -> Order) {\n let size = buffer.size();\n let indices = Prim.Array_tabulate<(Nat, X)>(size, func i = (i, buffer.get(i)));\n // Sort based on element, while carrying original index information\n // This groups together the duplicate elements\n let sorted = Array.sort<(Nat, X)>(indices, func(pair1, pair2) = compare(pair1.1, pair2.1));\n let uniques = Buffer<(Nat, X)>(size);\n\n // Iterate over elements\n var i = 0;\n while (i < size) {\n var j = i;\n // Iterate over duplicate elements, and find the smallest index among them (for stability)\n var minIndex = sorted[j];\n label duplicates while (j < (size - 1 : Nat)) {\n let pair1 = sorted[j];\n let pair2 = sorted[j + 1];\n switch (compare(pair1.1, pair2.1)) {\n case (#equal) {\n if (pair2.0 < pair1.0) {\n minIndex := pair2;\n };\n j += 1;\n };\n case _ {\n break duplicates;\n };\n };\n };\n\n uniques.add(minIndex);\n i := j + 1;\n };\n\n // resort based on original ordering and place back in buffer\n uniques.sort(\n func(pair1, pair2) {\n if (pair1.0 < pair2.0) {\n #less;\n } else if (pair1.0 == pair2.0) {\n #equal;\n } else {\n #greater;\n };\n },\n );\n\n buffer.clear();\n buffer.reserve(uniques.size());\n for (element in uniques.vals()) {\n buffer.add(element.1);\n };\n };\n\n /// Splits `buffer` into a pair of buffers where all elements in the left\n /// buffer satisfy `predicate` and all elements in the right buffer do not.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func partition<X>(buffer : Buffer<X>, predicate : X -> Bool) : (Buffer<X>, Buffer<X>) {\n let size = buffer.size();\n let trueBuffer = Buffer<X>(size);\n let falseBuffer = Buffer<X>(size);\n\n for (element in buffer.vals()) {\n if (predicate element) {\n trueBuffer.add(element);\n } else {\n falseBuffer.add(element);\n };\n };\n\n (trueBuffer, falseBuffer);\n };\n\n /// Splits the buffer into two buffers at `index`, where the left buffer contains\n /// all elements with indices less than `index`, and the right buffer contains all\n /// elements with indices greater than or equal to `index`. Traps if `index` is out\n /// of bounds.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func split<X>(buffer : Buffer<X>, index : Nat) : (Buffer<X>, Buffer<X>) {\n let size = buffer.size();\n\n if (index < 0 or index > size) {\n Prim.trap \"Index out of bounds in split\";\n };\n\n let buffer1 = Buffer<X>(newCapacity index);\n let buffer2 = Buffer<X>(newCapacity(size - index));\n\n var i = 0;\n while (i < index) {\n buffer1.add(buffer.get(i));\n i += 1;\n };\n while (i < size) {\n buffer2.add(buffer.get(i));\n i += 1;\n };\n\n (buffer1, buffer2);\n };\n\n /// Breaks up `buffer` into buffers of size `size`. The last chunk may\n /// have less than `size` elements if the number of elements is not divisible\n /// by the chunk size.\n ///\n /// Runtime: O(number of elements in buffer)\n ///\n /// Space: O(number of elements in buffer)\n public func chunk<X>(buffer : Buffer<X>, size : Nat) : Buffer<Buffer<X>> {\n if (size == 0) {\n Prim.trap \"Chunk size must be non-zero in chunk\";\n };\n\n // ceil(buffer.size() / size)\n let newBuffer = Buffer<Buffer<X>>((buffer.size() + size - 1) / size);\n\n var newInnerBuffer = Buffer<X>(newCapacity size);\n var innerSize = 0;\n for (element in buffer.vals()) {\n if (innerSize == size) {\n newBuffer.add(newInnerBuffer);\n newInnerBuffer := Buffer<X>(newCapacity size);\n innerSize := 0;\n };\n newInnerBuffer.add(element);\n innerSize += 1;\n };\n if (innerSize > 0) {\n newBuffer.add(newInnerBuffer);\n };\n\n newBuffer;\n };\n\n /// Groups equal and adjacent elements in the list into sub lists.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func groupBy<X>(buffer : Buffer<X>, equal : (X, X) -> Bool) : Buffer<Buffer<X>> {\n let size = buffer.size();\n let newBuffer = Buffer<Buffer<X>>(size);\n if (size == 0) {\n return newBuffer;\n };\n\n var i = 0;\n var baseElement = buffer.get(0);\n var newInnerBuffer = Buffer<X>(size);\n while (i < size) {\n let element = buffer.get(i);\n\n if (equal(baseElement, element)) {\n newInnerBuffer.add(element);\n } else {\n newBuffer.add(newInnerBuffer);\n baseElement := element;\n newInnerBuffer := Buffer<X>(size - i);\n newInnerBuffer.add(element);\n };\n i += 1;\n };\n if (newInnerBuffer.size() > 0) {\n newBuffer.add(newInnerBuffer);\n };\n\n newBuffer;\n };\n\n /// Flattens the buffer of buffers into a single buffer.\n ///\n /// Runtime: O(number of elements in buffer)\n ///\n /// Space: O(number of elements in buffer)\n public func flatten<X>(buffer : Buffer<Buffer<X>>) : Buffer<X> {\n let size = buffer.size();\n if (size == 0) {\n return Buffer<X>(0);\n };\n\n let newBuffer = Buffer<X>(\n if (buffer.get(0).size() != 0) {\n newCapacity(buffer.get(0).size() * size);\n } else {\n newCapacity(size);\n },\n );\n\n for (innerBuffer in buffer.vals()) {\n for (innerElement in innerBuffer.vals()) {\n newBuffer.add(innerElement);\n };\n };\n\n newBuffer;\n };\n\n /// Combines the two buffers into a single buffer of pairs, pairing together\n /// elements with the same index. If one buffer is longer than the other, the\n /// remaining elements from the longer buffer are not included.\n ///\n /// Runtime: O(min(size1, size2))\n ///\n /// Space: O(min(size1, size2))\n public func zip<X, Y>(buffer1 : Buffer<X>, buffer2 : Buffer<Y>) : Buffer<(X, Y)> {\n // compiler should pull lamda out as a static function since it is fully closed\n zipWith<X, Y, (X, Y)>(buffer1, buffer2, func(x, y) = (x, y));\n };\n\n /// Combines the two buffers into a single buffer, pairing together\n /// elements with the same index and combining them using `zip`. If\n /// one buffer is longer than the other, the remaining elements from\n /// the longer buffer are not included.\n ///\n /// Runtime: O(min(size1, size2))\n ///\n /// Space: O(min(size1, size2))\n ///\n /// *Runtime and space assumes that `zip` runs in O(1) time and space.\n public func zipWith<X, Y, Z>(buffer1 : Buffer<X>, buffer2 : Buffer<Y>, zip : (X, Y) -> Z) : Buffer<Z> {\n let size1 = buffer1.size();\n let size2 = buffer2.size();\n let minSize = if (size1 < size2) { size1 } else { size2 };\n\n var i = 0;\n let newBuffer = Buffer<Z>(newCapacity minSize);\n while (i < minSize) {\n newBuffer.add(zip(buffer1.get(i), buffer2.get(i)));\n i += 1;\n };\n newBuffer;\n };\n\n /// Creates a new buffer taking elements in order from `buffer` until predicate\n /// returns false.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func takeWhile<X>(buffer : Buffer<X>, predicate : X -> Bool) : Buffer<X> {\n let newBuffer = Buffer<X>(buffer.size());\n\n for (element in buffer.vals()) {\n if (not predicate element) {\n return newBuffer;\n };\n newBuffer.add(element);\n };\n\n newBuffer;\n };\n\n /// Creates a new buffer excluding elements in order from `buffer` until predicate\n /// returns false.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func dropWhile<X>(buffer : Buffer<X>, predicate : X -> Bool) : Buffer<X> {\n let size = buffer.size();\n let newBuffer = Buffer<X>(size);\n\n var i = 0;\n var take = false;\n label iter for (element in buffer.vals()) {\n if (not (take or predicate element)) {\n take := true;\n };\n if (take) {\n newBuffer.add(element);\n };\n };\n newBuffer;\n };\n};\n"},"AssocList.mo":{"content":"/// Lists of key-value entries (\"associations\").\n///\n/// Implements the same operations as library `Trie`, but uses a\n/// linked-list of entries and no hashing.\n\nimport List \"List\";\n\nmodule {\n\n /// polymorphic association linked lists between keys and values\n public type AssocList<K, V> = List.List<(K, V)>;\n\n /// Find the value associated with a given key, or null if absent.\n public func find<K, V>(\n al : AssocList<K, V>,\n k : K,\n k_eq : (K, K) -> Bool\n ) : ?V {\n func rec(al : AssocList<K, V>) : ?V {\n label profile_assocList_find_rec : (?V)\n switch (al) {\n case (null) { label profile_assocList_find_end_fail : (?V) { null } };\n case (?((hd_k, hd_v), tl)) {\n if (k_eq(k, hd_k)) {\n label profile_assocList_find_end_success : (?V) {\n ?hd_v\n }\n } else {\n rec(tl)\n }\n };\n }\n };\n label profile_assocList_find_begin : (?V) {\n rec(al)\n }\n };\n\n /// replace the value associated with a given key, or add it, if missing.\n /// returns old value, or null, if no prior value existed.\n public func replace<K, V>(\n al : AssocList<K, V>,\n k : K,\n k_eq : (K, K) -> Bool,\n ov : ?V\n )\n : (AssocList<K, V>, ?V) {\n func rec(al : AssocList<K, V>) : (AssocList<K, V>, ?V) {\n switch (al) {\n case (null) {\n switch ov {\n case (null) { (null, null) };\n case (?v) { (?((k, v), null), null) };\n }\n };\n case (?((hd_k, hd_v), tl)) {\n if (k_eq(k, hd_k)) {\n // if value is null, remove the key; otherwise, replace key's old value\n // return old value\n switch ov {\n case (null) { (tl, ?hd_v) };\n case (?v) { (?((hd_k, v), tl), ?hd_v) };\n }\n } else {\n let (tl2, old_v) = rec(tl);\n (?((hd_k, hd_v), tl2), old_v)\n }\n };\n }\n };\n rec(al)\n };\n\n /// The entries of the final list consist of those pairs of\n /// the left list whose keys are not present in the right list; the\n /// \"extra\" values of the right list are irrelevant.\n public func diff<K, V, W>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n keq : (K, K) -> Bool\n ) : AssocList<K, V> {\n func rec(al1 : AssocList<K, V>) : AssocList<K, V> {\n switch al1 {\n case (null) { null };\n case (?((k, v1), tl)) {\n switch (find<K, W>(al2, k, keq)) {\n case (null) { ?((k, v1), rec(tl)) };\n case (?v2) { rec(tl)};\n }\n };\n }\n };\n rec(al1)\n };\n\n /// Transform and combine the entries of two association lists.\n public func mapAppend<K, V, W, X>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n vbin : (?V, ?W) -> X\n ) : AssocList<K, X> =\n label profile_assocList_mapAppend : AssocList<K, X> {\n func rec(al1 : AssocList<K, V>, al2 : AssocList<K, W>) : AssocList<K, X> =\n label profile_assocList_mapAppend_rec : AssocList<K,X> {\n switch (al1, al2) {\n case (null, null) { null };\n case (?((k, v), al1_), _ ) { ?((k, vbin(?v, null)), rec(al1_, al2 )) };\n case (null, ?((k, v), al2_)) { ?((k, vbin(null, ?v)), rec(null, al2_)) };\n }\n };\n rec(al1, al2)\n };\n\n /// Specialized version of `disj`, optimized for disjoint sub-spaces of keyspace (no matching keys).\n public func disjDisjoint<K, V, W, X>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n vbin : (?V, ?W) -> X)\n : AssocList<K, X> = label profile_assocList_disjDisjoint : AssocList<K,X> {\n mapAppend<K, V, W, X>(al1, al2, vbin)\n };\n\n /// This operation generalizes the notion of \"set union\" to finite maps.\n /// Produces a \"disjunctive image\" of the two lists, where the values of\n /// matching keys are combined with the given binary operator.\n ///\n /// For unmatched entries, the operator is still applied to\n /// create the value in the image. To accomodate these various\n /// situations, the operator accepts optional values, but is never\n /// applied to (null, null).\n public func disj<K, V, W, X>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n keq : (K, K) -> Bool,\n vbin :(?V, ?W) -> X\n ) : AssocList<K, X> {\n func rec1(al1 : AssocList<K, V>) : AssocList<K, X> {\n switch al1 {\n case (null) {\n func rec2(al2 : AssocList<K, W>) : AssocList<K, X> {\n switch al2 {\n case (null) { null };\n case (?((k, v2), tl)) {\n switch (find<K, V>(al1, k, keq)) {\n case (null) { ?((k, vbin(null, ?v2)), rec2(tl)) };\n case (?v1) { ?((k, vbin(?v1, ?v2)), rec2(tl)) };\n }\n };\n }\n };\n rec2(al2)\n };\n case (?((k, v1), tl)) {\n switch (find<K, W>(al2, k, keq)) {\n case (null) { ?((k, vbin(?v1, null)), rec1(tl)) };\n case (?v2) { /* handled above */ rec1(tl) };\n }\n };\n }\n };\n rec1(al1)\n };\n\n /// This operation generalizes the notion of \"set intersection\" to\n /// finite maps. Produces a \"conjuctive image\" of the two lists, where\n /// the values of matching keys are combined with the given binary\n /// operator, and unmatched entries are not present in the output.\n public func join<K, V, W, X>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n keq : (K, K) -> Bool,\n vbin : (V, W) -> X\n ) : AssocList<K, X> {\n func rec(al1 : AssocList<K, V>) : AssocList<K, X> {\n switch al1 {\n case (null) { null };\n case (?((k, v1), tl)) {\n switch (find<K, W>(al2, k, keq)) {\n case (null) { rec(tl) };\n case (?v2) { ?((k, vbin(v1, v2)), rec(tl)) };\n }\n };\n }\n };\n rec(al1)\n };\n\n /// Fold the entries based on the recursive list structure.\n public func fold<K, V, X>(\n al : AssocList<K, V>,\n nil : X,\n cons : (K, V, X) -> X\n ) : X {\n func rec(al : AssocList<K, V>) : X {\n switch al {\n case null { nil };\n case (?((k, v), t)) { cons(k, v, rec(t)) };\n }\n };\n rec(al)\n };\n\n}\n"},"Bool.mo":{"content":"/// Boolean type and operations.\n///\n/// While boolean operators `_ and _` and `_ or _` are short-circuiting,\n/// avoiding computation of the right argument when possible, the functions\n/// `logand(_, _)` and `logor(_, _)` are *strict* and will always evaluate *both*\n/// of their arguments.\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// Booleans with constants `true` and `false`.\n public type Bool = Prim.Types.Bool;\n\n /// Conversion.\n public func toText(x : Bool) : Text {\n if x { \"true\" } else { \"false\" }\n };\n\n /// Returns `x and y`.\n public func logand(x : Bool, y : Bool) : Bool { x and y };\n\n /// Returns `x or y`.\n public func logor(x : Bool, y : Bool) : Bool { x or y };\n\n /// Returns exclusive or of `x` and `y`, `x != y`.\n public func logxor(x : Bool, y : Bool) : Bool {\n x != y\n };\n\n /// Returns `not x`.\n public func lognot(x : Bool) : Bool { not x };\n\n /// Returns `x == y`.\n public func equal(x : Bool, y : Bool) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Bool, y : Bool) : Bool { x != y };\n\n /// Returns the order of `x` and `y`, where `false < true`.\n public func compare(x : Bool, y : Bool) : {#less; #equal; #greater } {\n if (x == y) { #equal } else if (x) { #greater } else { #less }\n };\n\n}\n"},"CertifiedData.mo":{"content":"/// Certified data.\n///\n/// The Internet Computer allows canister smart contracts to store a small amount of data during\n/// update method processing so that during query call processing, the canister can obtain\n/// a certificate about that data.\n///\n/// This module provides a _low-level_ interface to this API, aimed at advanced\n/// users and library implementors. See the Internet Computer Functional\n/// Specification and corresponding documentation for how to use this to make query\n/// calls to your canister tamperproof.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Set the certified data.\n ///\n /// Must be called from an update method, else traps.\n /// Must be passed a blob of at most 32 bytes, else traps.\n public let set : (data : Blob) -> () = Prim.setCertifiedData;\n\n /// Gets a certificate\n ///\n /// Returns `null` if no certificate is available, e.g. when processing an\n /// update call or inter-canister call. This returns a non-`null` value only\n /// when processing a query call.\n public let getCertificate : () -> ?Blob = Prim.getCertificate;\n\n}\n"},"Error.mo":{"content":"/// Error values and inspection.\n///\n/// The `Error` type is the argument to `throw`, parameter of `catch`.\n/// The `Error` type is opaque.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Error values resulting from `async` computations\n public type Error = Prim.Types.Error;\n\n /// Error codes (user and system), where module `Prim` defines:\n /// ```motoko\n /// type ErrorCode = {\n /// // Fatal error.\n /// #system_fatal;\n /// // Transient error.\n /// #system_transient;\n /// // Destination invalid.\n /// #destination_invalid;\n /// // Explicit reject by canister code.\n /// #canister_reject;\n /// // Canister trapped.\n /// #canister_error;\n /// // Future error code (with unrecognized numeric code)\n /// #future : Nat32;\n /// };\n /// ```\n public type ErrorCode = Prim.ErrorCode;\n\n /// Create an error from message `m` with code #canister_reject.\n public let reject : (m : Text) -> Error = Prim.error;\n\n /// Returns the code of an error `e`.\n public let code : (e : Error) -> ErrorCode = Prim.errorCode;\n\n /// Returns the message of an error `e`.\n public let message : (e : Error) -> Text = Prim.errorMessage;\n\n}\n"},"Array.mo":{"content":"/// Provides extended utility functions on Arrays. Note the difference between\n/// mutable and non-mutable arrays below.\n///\n/// WARNING: If you are looking for a list that can grow and shrink in size,\n/// it is recommended you use either the Buffer class or the List class for\n/// those purposes. Arrays must be created with a fixed size.\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Array \"mo:base/Array\";\n/// ```\n\nimport I \"IterType\";\nimport Option \"Option\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\nimport Result \"Result\";\n\nmodule {\n /// Create a mutable array with `size` copies of the initial value.\n ///\n /// ```motoko include=import\n /// let array = Array.init<Nat>(4, 2);\n /// ```\n ///\n /// Runtime: O(size)\n /// Space: O(size)\n public func init<X>(size : Nat, initValue : X) : [var X] =\n Prim.Array_init<X>(size, initValue);\n\n /// Create an immutable array of size `size`. Each element at index i\n /// is created by applying `generator` to i.\n ///\n /// ```motoko include=import\n /// let array : [Nat] = Array.tabulate<Nat>(4, func i = i * 2);\n /// ```\n ///\n /// Runtime: O(size)\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `generator` runs in O(1) time and space.\n public func tabulate<X>(size : Nat, generator : Nat -> X) : [X] =\n Prim.Array_tabulate<X>(size, generator);\n\n /// Create a mutable array of size `size`. Each element at index i\n /// is created by applying `generator` to i.\n ///\n /// ```motoko include=import\n /// let array : [var Nat] = Array.tabulateVar<Nat>(4, func i = i * 2);\n /// array[2] := 0;\n /// array\n /// ```\n ///\n /// Runtime: O(size)\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `generator` runs in O(1) time and space.\n public func tabulateVar<X>(size : Nat, generator : Nat -> X) : [var X] {\n // FIXME add this as a primitive in the RTS\n if (size == 0) { return [var] };\n let array = Prim.Array_init<X>(size, generator 0);\n var i = 0;\n while (i < size) {\n array[i] := generator i;\n i += 1;\n };\n array\n };\n\n /// Transforms a mutable array into an immutable array.\n ///\n /// ```motoko include=import\n ///\n /// let varArray = [var 0, 1, 2];\n /// varArray[2] := 3;\n /// let array = Array.freeze<Nat>(varArray);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func freeze<X>(varArray : [var X]) : [X] =\n Prim.Array_tabulate<X>(varArray.size(), func i = varArray[i]);\n\n /// Transforms an immutable array into a mutable array.\n ///\n /// ```motoko include=import\n ///\n /// let array = [0, 1, 2];\n /// let varArray = Array.thaw<Nat>(array);\n /// varArray[2] := 3;\n /// varArray\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func thaw<A>(array : [A]) : [var A] {\n let size = array.size();\n if (size == 0) {\n return [var];\n };\n let newArray = Prim.Array_init<A>(size, array[0]);\n var i = 0;\n while (i < size) {\n newArray[i] := array[i];\n i += 1;\n };\n newArray\n };\n\n /// Tests if two arrays contain equal values (i.e. they represent the same\n /// list of elements). Uses `equal` to compare elements in the arrays.\n ///\n /// ```motoko include=import\n /// // Use the equal function from the Nat module to compare Nats\n /// import {equal} \"mo:base/Nat\";\n ///\n /// let array1 = [0, 1, 2, 3];\n /// let array2 = [0, 1, 2, 3];\n /// Array.equal(array1, array2, equal)\n /// ```\n ///\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func equal<X>(array1 : [X], array2 : [X], equal : (X, X) -> Bool) : Bool {\n let size1 = array1.size();\n let size2 = array2.size();\n if (size1 != size2) {\n return false;\n };\n var i = 0;\n while (i < size1) {\n if (not equal(array1[i], array2[i])) {\n return false;\n };\n i += 1;\n };\n return true;\n };\n\n /// Returns the first value in `array` for which `predicate` returns true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// ```motoko include=import\n /// let array = [1, 9, 4, 8];\n /// Array.find<Nat>(array, func x = x > 8)\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func find<X>(array : [X], predicate : X -> Bool) : ?X {\n for (element in array.vals()) {\n if (predicate element) {\n return ?element;\n }\n };\n return null;\n };\n\n /// Create a new array by appending the values of `array1` and `array2`.\n /// @deprecated `Array.append` copies its arguments and has linear complexity;\n /// when used in a loop, consider using a `Buffer`, and `Buffer.append`, instead.\n ///\n /// ```motoko include=import\n /// let array1 = [1, 2, 3];\n /// let array2 = [4, 5, 6];\n /// Array.append<Nat>(array1, array2)\n /// ```\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(size1 + size2)\n public func append<X>(array1 : [X], array2 : [X]) : [X] {\n let size1 = array1.size();\n let size2 = array2.size();\n Prim.Array_tabulate<X>(size1 + size2, func i {\n if (i < size1) {\n array1[i];\n } else {\n array2[i - size1];\n };\n });\n };\n\n // FIXME this example stack overflows. Should test with new implementation of sortInPlace\n /// Sorts the elements in the array according to `compare`.\n /// Sort is deterministic and stable.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 6];\n /// Array.sort(array, Nat.compare)\n /// ```\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func sort<X>(array : [X], compare : (X, X) -> Order.Order) : [X] {\n let temp : [var X] = thaw(array);\n sortInPlace(temp, compare);\n freeze(temp)\n };\n\n /// Sorts the elements in the array, __in place__, according to `compare`.\n /// Sort is deterministic, stable, and in-place.\n ///\n /// ```motoko include=import\n ///\n /// import {compare} \"mo:base/Nat\";\n ///\n /// let array = [var 4, 2, 6];\n /// Array.sortInPlace(array, compare);\n /// array\n /// ```\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func sortInPlace<X>(array : [var X], compare : (X, X) -> Order.Order) {\n // Stable merge sort in a bottom-up iterative style. Same algorithm as the sort in Buffer.\n let size = array.size();\n if (size == 0) {\n return;\n };\n let scratchSpace = Prim.Array_init<X>(size, array[0]);\n\n let sizeDec = size - 1 : Nat;\n var currSize = 1; // current size of the subarrays being merged\n // when the current size == size, the array has been merged into a single sorted array\n while (currSize < size) {\n var leftStart = 0; // selects the current left subarray being merged\n while (leftStart < sizeDec) {\n let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {\n leftStart + currSize - 1;\n } else { sizeDec };\n let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {\n leftStart + (2 * currSize) - 1;\n } else { sizeDec };\n\n // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]\n var left = leftStart;\n var right = mid + 1;\n var nextSorted = leftStart;\n while (left < mid + 1 and right < rightEnd + 1) {\n let leftElement = array[left];\n let rightElement = array[right];\n switch (compare(leftElement, rightElement)) {\n case (#less or #equal) {\n scratchSpace[nextSorted] := leftElement;\n left += 1;\n };\n case (#greater) {\n scratchSpace[nextSorted] := rightElement;\n right += 1;\n };\n };\n nextSorted += 1;\n };\n while (left < mid + 1) {\n scratchSpace[nextSorted] := array[left];\n nextSorted += 1;\n left += 1;\n };\n while (right < rightEnd + 1) {\n scratchSpace[nextSorted] := array[right];\n nextSorted += 1;\n right += 1;\n };\n\n // Copy over merged elements\n var i = leftStart;\n while (i < rightEnd + 1) {\n array[i] := scratchSpace[i];\n i += 1;\n };\n\n leftStart += 2 * currSize;\n };\n currSize *= 2;\n };\n };\n\n /// Creates a new array by reversing the order of elements in `array`.\n ///\n /// ```motoko include=import\n ///\n /// let array = [10, 11, 12];\n ///\n /// Array.reverse(array)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func reverse<X>(array : [X]) : [X] {\n let size = array.size();\n Prim.Array_tabulate<X>(size, func i = array[size - i - 1]);\n };\n\n /// Creates a new array by applying `f` to each element in `array`. `f` \"maps\"\n /// each element it is applied to of type `X` to an element of type `Y`.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n ///\n /// let array = [0, 1, 2, 3];\n /// Array.map<Nat, Nat>(array, func x = x * 3)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func map<X, Y>(array : [X], f : X -> Y) : [Y] =\n Prim.Array_tabulate<Y>(array.size(), func i = f(array[i]));\n\n /// Creates a new array by applying `predicate` to every element\n /// in `array`, retaining the elements for which `predicate` returns true.\n ///\n /// ```motoko include=import\n /// let array = [4, 2, 6, 1, 5];\n /// let evenElements = Array.filter<Nat>(array, func x = x % 2 == 0);\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func filter<X>(array : [X], predicate : X -> Bool) : [X] {\n var count = 0;\n let keep =\n Prim.Array_tabulate<Bool>(\n array.size(),\n func i {\n if (predicate(array[i])) {\n count += 1;\n true\n } else {\n false\n }\n }\n );\n var nextKeep = 0;\n Prim.Array_tabulate<X>(\n count,\n func _ {\n while (not keep[nextKeep]) {\n nextKeep += 1;\n };\n nextKeep += 1;\n array[nextKeep - 1];\n }\n )\n };\n\n // FIXME the arguments ordering to the higher order function are flipped\n // between this and the buffer class\n // probably can't avoid breaking changes at some point\n /// Creates a new array by applying `f` to each element in `array` and its index.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n ///\n /// let array = [10, 10, 10, 10];\n /// Array.mapEntries<Nat, Nat>(array, func (i, x) = i * x)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapEntries<X, Y>(array : [X], f : (X, Nat) -> Y) : [Y] =\n Prim.Array_tabulate<Y>(array.size(), func i = f(array[i], i));\n\n /// Creates a new array by applying `f` to each element in `array`,\n /// and keeping all non-null elements. The ordering is retained.\n ///\n /// ```motoko include=import\n /// import {toText} \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 0, 1];\n /// let newArray =\n /// Array.mapFilter<Nat, Text>( // mapping from Nat to Text values\n /// array,\n /// func x = if (x == 0) { null } else { ?toText(100 / x) } // can't divide by 0, so return null\n /// );\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapFilter<X, Y>(array : [X], f : X -> ?Y) : [Y] {\n var count = 0;\n let options =\n Prim.Array_tabulate<?Y>(\n array.size(),\n func i {\n let result = f(array[i]);\n switch (result) {\n case (?element) {\n count += 1;\n result\n };\n case null {\n null\n }\n }\n }\n );\n\n var nextSome = 0;\n Prim.Array_tabulate<Y>(\n count,\n func _ {\n while (Option.isNull(options[nextSome])) {\n nextSome += 1;\n };\n nextSome += 1;\n switch(options[nextSome - 1]) {\n case(?element) element;\n case null {\n Prim.trap \"Malformed array in mapFilter\"\n }\n }\n }\n )\n };\n\n /// Creates a new array by applying `f` to each element in `array`.\n /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n /// returns an `#ok` containing the new array.\n ///\n /// ```motoko include=import\n /// let array = [4, 3, 2, 1, 0];\n /// // divide 100 by every element in the array\n /// Array.mapResult<Nat, Nat, Text>(array, func x {\n /// if (x > 0) {\n /// #ok(100 / x)\n /// } else {\n /// #err \"Cannot divide by zero\"\n /// }\n /// })\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapResult<X, Y, E>(array : [X], f : X -> Result.Result<Y, E>) : Result.Result<[Y], E> {\n let size = array.size();\n var target : [var Y] = [var];\n var isInit = false;\n\n var error : ?Result.Result<[Y], E> = null;\n let results = Prim.Array_tabulate<?Y>(size, func i {\n switch (f(array[i])) {\n case (#ok element) {\n ?element\n };\n case (#err e) {\n switch (error) {\n case null { // only take the first error\n error := ?(#err e);\n };\n case _ { };\n };\n null\n }\n }\n });\n\n switch error {\n case null {\n // unpack the option\n #ok(map<?Y, Y>(results, func element {\n switch element {\n case (?element) {\n element\n };\n case null {\n Prim.trap \"Malformed array in mapResults\"\n };\n }\n }));\n };\n case (?error) {\n error\n };\n }\n };\n\n /// Creates a new array by applying `k` to each element in `array`,\n /// and concatenating the resulting arrays in order. This operation\n /// is similar to what in other functional languages is known as monadic bind.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:base/Nat\";\n ///\n /// let array = [1, 2, 3, 4];\n /// Array.chain<Nat, Int>(array, func x = [x, -x])\n ///\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `k` runs in O(1) time and space.\n public func chain<X, Y>(array : [X], k : X -> [Y]) : [Y] {\n var flatSize = 0;\n let subArrays = Prim.Array_tabulate<[Y]>(array.size(), func i {\n let subArray = k(array[i]);\n flatSize += subArray.size();\n subArray\n });\n // could replace with a call to flatten,\n // but it would require an extra pass (to compute `flatSize`)\n var outer = 0;\n var inner = 0;\n Prim.Array_tabulate<Y>(flatSize, func _ {\n let subArray = subArrays[outer];\n let element = subArray[inner];\n inner += 1;\n if (inner == subArray.size()) {\n inner := 0;\n outer += 1;\n };\n element\n })\n };\n\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// ```motoko include=import\n /// import {add} \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 0, 1];\n /// let sum =\n /// Array.foldLeft<Nat, Nat>(\n /// array,\n /// 0, // start the sum at 0\n /// func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!\n /// );\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldLeft<X, A>(array : [X], base : A, combine : (A, X) -> A) : A {\n var accumulation = base;\n\n for (element in array.vals()) {\n accumulation := combine(accumulation, element);\n };\n\n accumulation\n };\n\n // FIXME the type arguments are reverse order from Buffer\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// ```motoko include=import\n /// import {toText} \"mo:base/Nat\";\n ///\n /// let array = [1, 9, 4, 8];\n /// let bookTitle = Array.foldRight<Nat, Text>(array, \"\", func(x, acc) = toText(x) # acc);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldRight<X, A>(array : [X], base : A, combine : (X, A) -> A) : A {\n var accumulation = base;\n let size = array.size();\n\n var i = size;\n while (i > 0) {\n i -= 1;\n accumulation := combine(array[i], accumulation);\n };\n\n accumulation;\n };\n\n /// Flattens the array of arrays into a single array. Retains the original\n /// ordering of the elements.\n ///\n /// ```motoko include=import\n ///\n /// let arrays = [[0, 1, 2], [2, 3], [], [4]];\n /// Array.flatten<Nat>(arrays)\n /// ```\n ///\n /// Runtime: O(number of elements in array)\n ///\n /// Space: O(number of elements in array)\n public func flatten<X>(arrays : [[X]]) : [X] {\n var flatSize = 0;\n for (subArray in arrays.vals()) {\n flatSize += subArray.size()\n };\n\n var outer = 0;\n var inner = 0;\n Prim.Array_tabulate<X>(flatSize, func _ {\n while (inner == arrays[outer].size()) {\n inner := 0;\n outer += 1;\n };\n let element = arrays[outer][inner];\n inner += 1;\n element\n })\n };\n\n /// Create an array containing a single value.\n ///\n /// ```motoko include=import\n /// Array.make(2)\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func make<X>(element : X) : [X] = [element];\n\n /// Returns an Iterator (`Iter`) over the elements of `array`.\n /// Iterator provides a single method `next()`, which returns\n /// elements in order, or `null` when out of elements to iterate over.\n ///\n /// NOTE: You can also use `array.vals()` instead of this function. See example\n /// below.\n ///\n /// ```motoko include=import\n ///\n /// let array = [10, 11, 12];\n ///\n /// var sum = 0;\n /// for (element in array.vals()) {\n /// sum += element;\n /// };\n /// sum\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func vals<X>(array : [X]) : I.Iter<X> = array.vals();\n\n /// Returns an Iterator (`Iter`) over the indices of `array`.\n /// Iterator provides a single method `next()`, which returns\n /// indices in order, or `null` when out of index to iterate over.\n ///\n /// NOTE: You can also use `array.keys()` instead of this function. See example\n /// below.\n ///\n /// ```motoko include=import\n ///\n /// let array = [10, 11, 12];\n ///\n /// var sum = 0;\n /// for (element in array.keys()) {\n /// sum += element;\n /// };\n /// sum\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func keys<X>(array : [X]) : I.Iter<Nat> = array.keys();\n}\n"},"Char.mo":{"content":"/// Characters\nimport Prim \"mo:⛔\";\nmodule {\n\n /// Characters represented as Unicode code points.\n public type Char = Prim.Types.Char;\n\n /// Convert character `c` to a word containing its Unicode scalar value.\n public let toNat32 : (c : Char) -> Nat32 = Prim.charToNat32;\n\n /// Convert `w` to a character.\n /// Traps if `w` is not a valid Unicode scalar value.\n /// Value `w` is valid if, and only if, `w < 0xD800 or (0xE000 <= w and w <= 0x10FFFF)`.\n public let fromNat32 : (w : Nat32) -> Char = Prim.nat32ToChar;\n\n /// Convert character `c` to single character text.\n public let toText : (c : Char) -> Text = Prim.charToText;\n\n // Not exposed pending multi-char implementation.\n private let toUpper : (c : Char) -> Char = Prim.charToUpper;\n\n // Not exposed pending multi-char implementation.\n private let toLower : (c : Char) -> Char = Prim.charToLower;\n\n /// Returns `true` when `c` is a decimal digit between `0` and `9`, otherwise `false`.\n public func isDigit(c : Char) : Bool {\n Prim.charToNat32(c) -% Prim.charToNat32('0') <= (9 : Nat32)\n };\n\n /// Returns the Unicode _White_Space_ property of `c`.\n public let isWhitespace : (c : Char) -> Bool = Prim.charIsWhitespace;\n\n /// Returns the Unicode _Lowercase_ property of `c`.\n public let isLowercase : (c : Char) -> Bool = Prim.charIsLowercase;\n\n /// Returns the Unicode _Uppercase_ property of `c`.\n public let isUppercase : (c : Char) -> Bool = Prim.charIsUppercase;\n\n /// Returns the Unicode _Alphabetic_ property of `c`.\n public let isAlphabetic : (c : Char) -> Bool = Prim.charIsAlphabetic;\n\n /// Returns `x == y`.\n public func equal(x : Char, y : Char) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Char, y : Char) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Char, y : Char) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Char, y : Char) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Char, y : Char) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Char, y : Char) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Char, y : Char) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n}\n"},"ExperimentalInternetComputer.mo":{"content":"/// Low-level interface to the Internet Computer.\n///\n/// **WARNING:** This low-level API is **experimental** and likely to change or even disappear.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Calls ``canister``'s update or query function, `name`, with the binary contents of `data` as IC argument.\n /// Returns the response to the call, an IC _reply_ or _reject_, as a Motoko future:\n ///\n /// * The message data of an IC reply determines the binary contents of `reply`.\n /// * The error code and textual message data of an IC reject determines the future's `Error` value.\n ///\n /// Note: `call` is an asynchronous function and can only be applied in an asynchronous context.\n public let call : (canister : Principal, name : Text, data : Blob) ->\n async (reply : Blob) = Prim.call_raw;\n\n /// Given computation, `comp`, counts the number of actual and (for IC system calls) notional WebAssembly\n /// instructions performed during the execution of `comp()`.\n ///\n /// More precisely, returns the difference between the state of the IC instruction counter (_performance counter_ `0`) before and after executing `comp()`\n /// (see [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter)).\n ///\n /// NB: `countInstructions(comp)` will _not_ account for any deferred garbage collection costs incurred by `comp()`.\n public func countInstructions(comp : () -> ()) : Nat64 {\n let init = Prim.performanceCounter(0);\n let pre = Prim.performanceCounter(0);\n comp();\n let post = Prim.performanceCounter(0);\n // performance_counter costs around 200 extra instructions, we perform an empty measurement to decide the overhead\n let overhead = pre - init;\n post - pre - overhead\n }\n\n}\n"},"Deque.mo":{"content":"/// Functions for persistent, double-ended queues.\n\nimport List \"List\";\nimport P \"Prelude\";\n\nmodule {\n type List<T> = List.List<T>;\n\n /// Double-ended queue\n public type Deque<T> = (List<T>, List<T>);\n\n /// Empty queue\n public func empty<T> () : Deque<T> { (List.nil(), List.nil()); };\n\n /// True when the queue is empty\n public func isEmpty<T>(q : Deque<T>) : Bool {\n switch q {\n case (f, r) { List.isNil(f) and List.isNil(r) };\n }\n };\n\n func check<T>(q : Deque<T>) : Deque<T> {\n switch q {\n case (null, r) { let (a,b) = List.split(List.size(r) / 2, r); (List.reverse(b), a) };\n case (f, null) { let (a,b) = List.split(List.size(f) / 2, f); (a, List.reverse(b)) };\n case q { q };\n }\n };\n\n /// Insert a new element on the front end of the queue\n public func pushFront<T>(q : Deque<T>, x : T) : Deque<T> {\n check (List.push(x, q.0), q.1);\n };\n\n /// Inspect the (optional) first element on the front end of the queue\n public func peekFront<T>(q : Deque<T>) : ?T {\n switch q {\n case (?(x, f), r) { ?x };\n case (null, ?(x, r)) { ?x };\n case _ { null };\n };\n };\n\n /// Remove the first element on the front end of the queue; Returns null when empty.\n public func popFront<T>(q : Deque<T>) : ?(T, Deque<T>) {\n switch q {\n case (?(x, f), r) { ?(x, check(f, r)) };\n case (null, ?(x, r)) { ?(x, check(null, r)) };\n case _ { null };\n };\n };\n\n /// Insert a new element on the back end of the queue\n public func pushBack<T>(q : Deque<T>, x : T) : Deque<T> {\n check (q.0, List.push(x, q.1));\n };\n\n /// Inspect the (optional) first element on the back end of the queue\n public func peekBack<T>(q : Deque<T>) : ?T {\n switch q {\n case (f, ?(x, r)) { ?x };\n case (?(x, r), null) { ?x };\n case _ { null };\n };\n };\n\n /// Remove the first element on the back end of the queue; Returns null when empty.\n public func popBack<T>(q : Deque<T>) : ?(Deque<T>, T) {\n switch q {\n case (f, ?(x, r)) { ?(check(f, r), x) };\n case (?(x, f), null) { ?(check(f, null), x) };\n case _ { null };\n };\n };\n};\n"},"Debug.mo":{"content":"/// Debugging aids\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// `print(t)` emits text `t` to the debug output stream.\n /// How this stream is stored or displayed depends on the\n /// execution environment.\n public let print : Text -> () = Prim.debugPrint;\n\n /// `trap(t)` traps execution with a user-provided message.\n public let trap : Text -> None = Prim.trap;\n\n\n}\n"},"HashMap.mo":{"content":"/// Mutable hash map (aka Hashtable)\n///\n/// This module defines an imperative hash map (hash table), with a general key and value type.\n///\n/// It has a minimal object-oriented interface: `get`, `set`, `delete`, `count` and `entries`.\n///\n/// The class is parameterized by the key's equality and hash functions,\n/// and an initial capacity. However, as with the `Buffer` class, no array allocation\n/// happens until the first `set`.\n///\n/// Internally, table growth policy is very simple, for now:\n/// Double the current capacity when the expected bucket list size grows beyond a certain constant.\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport A \"Array\";\nimport Hash \"Hash\";\nimport Iter \"Iter\";\nimport AssocList \"AssocList\";\nimport Nat32 \"Nat32\";\n\nmodule {\n\n\n // hash field avoids re-hashing the key when the array grows.\n type Key<K> = (Hash.Hash, K);\n\n // key-val list type\n type KVs<K, V> = AssocList.AssocList<Key<K>, V>;\n\n /// An imperative HashMap with a minimal object-oriented interface.\n /// Maps keys of type `K` to values of type `V`.\n public class HashMap<K, V>(\n initCapacity : Nat,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash) {\n\n var table : [var KVs<K, V>] = [var];\n var _count : Nat = 0;\n\n /// Returns the number of entries in this HashMap.\n public func size() : Nat = _count;\n\n /// Deletes the entry with the key `k`. Doesn't do anything if the key doesn't\n /// exist.\n public func delete(k : K) = ignore remove(k);\n\n func keyHash_(k : K) : Key<K> = (keyHash(k), k);\n\n func keyHashEq(k1 : Key<K>, k2 : Key<K>) : Bool { k1.0 == k2.0 and keyEq(k1.1, k2.1) };\n\n /// Removes the entry with the key `k` and returns the associated value if it\n /// existed or `null` otherwise.\n public func remove(k : K) : ?V {\n let m = table.size();\n if (m > 0) {\n let h = Prim.nat32ToNat(keyHash(k));\n let pos = h % m;\n let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(k), keyHashEq, null);\n table[pos] := kvs2;\n switch(ov){\n case null { };\n case _ { _count -= 1; }\n };\n ov\n } else {\n null\n };\n };\n\n /// Gets the entry with the key `k` and returns its associated value if it\n /// existed or `null` otherwise.\n public func get(k : K) : ?V {\n let h = Prim.nat32ToNat(keyHash(k));\n let m = table.size();\n let v = if (m > 0) {\n AssocList.find<Key<K>, V>(table[h % m], keyHash_(k), keyHashEq)\n } else {\n null\n };\n };\n\n /// Insert the value `v` at key `k`. Overwrites an existing entry with key `k`\n public func put(k : K, v : V) = ignore replace(k, v);\n\n /// Insert the value `v` at key `k` and returns the previous value stored at\n /// `k` or `null` if it didn't exist.\n public func replace(k : K, v : V) : ?V {\n if (_count >= table.size()) {\n let size =\n if (_count == 0) {\n if (initCapacity > 0) {\n initCapacity\n } else {\n 1\n }\n } else {\n table.size() * 2;\n };\n let table2 = A.init<KVs<K, V>>(size, null);\n for (i in table.keys()) {\n var kvs = table[i];\n label moveKeyVals : ()\n loop {\n switch kvs {\n case null { break moveKeyVals };\n case (?((k, v), kvsTail)) {\n let pos2 = Nat32.toNat(k.0) % table2.size(); // critical: uses saved hash. no re-hash.\n table2[pos2] := ?((k,v), table2[pos2]);\n kvs := kvsTail;\n };\n }\n };\n };\n table := table2;\n };\n let h = Prim.nat32ToNat(keyHash(k));\n let pos = h % table.size();\n let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(k), keyHashEq, ?v);\n table[pos] := kvs2;\n switch(ov){\n case null { _count += 1 };\n case _ {}\n };\n ov\n };\n\n /// An `Iter` over the keys.\n public func keys() : Iter.Iter<K>\n { Iter.map(entries(), func (kv : (K, V)) : K { kv.0 }) };\n\n /// An `Iter` over the values.\n public func vals() : Iter.Iter<V>\n { Iter.map(entries(), func (kv : (K, V)) : V { kv.1 }) };\n\n /// Returns an iterator over the key value pairs in this\n /// `HashMap`. Does _not_ modify the `HashMap`.\n public func entries() : Iter.Iter<(K, V)> {\n if (table.size() == 0) {\n object { public func next() : ?(K, V) { null } }\n }\n else {\n object {\n var kvs = table[0];\n var nextTablePos = 1;\n public func next () : ?(K, V) {\n switch kvs {\n case (?(kv, kvs2)) {\n kvs := kvs2;\n ?(kv.0.1, kv.1)\n };\n case null {\n if (nextTablePos < table.size()) {\n kvs := table[nextTablePos];\n nextTablePos += 1;\n next()\n } else {\n null\n }\n }\n }\n }\n }\n }\n };\n\n };\n\n /// clone cannot be an efficient object method,\n /// ...but is still useful in tests, and beyond.\n public func clone<K, V> (\n h : HashMap<K, V>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : HashMap<K, V> {\n let h2 = HashMap<K, V>(h.size(), keyEq, keyHash);\n for ((k,v) in h.entries()) {\n h2.put(k,v);\n };\n h2\n };\n\n /// Clone from any iterator of key-value pairs\n public func fromIter<K, V>(\n iter : Iter.Iter<(K, V)>,\n initCapacity : Nat,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : HashMap<K, V> {\n let h = HashMap<K, V>(initCapacity, keyEq, keyHash);\n for ((k, v) in iter) {\n h.put(k, v);\n };\n h\n };\n\n public func map<K, V1, V2>(\n h : HashMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n mapFn : (K, V1) -> V2,\n ) : HashMap<K, V2> {\n let h2 = HashMap<K, V2>(h.size(), keyEq, keyHash);\n for ((k, v1) in h.entries()) {\n let v2 = mapFn(k, v1);\n h2.put(k, v2);\n };\n h2\n };\n\n public func mapFilter<K, V1, V2>(\n h : HashMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n mapFn : (K, V1) -> ?V2,\n ) : HashMap<K, V2> {\n let h2 = HashMap<K, V2>(h.size(), keyEq, keyHash);\n for ((k, v1) in h.entries()) {\n switch (mapFn(k, v1)) {\n case null { };\n case (?v2) {\n h2.put(k, v2);\n };\n }\n };\n h2\n };\n\n}\n"},"ExperimentalCycles.mo":{"content":"/// Managing cycles\n///\n/// Usage of the Internet Computer is measured, and paid for, in _cycles_.\n/// This library provides imperative operations for observing cycles, transferring cycles and\n/// observing refunds of cycles.\n///\n/// **WARNING:** This low-level API is **experimental** and likely to change or even disappear.\n/// Dedicated syntactic support for manipulating cycles may be added to the language in future, obsoleting this library.\n///\n/// **NOTE:** Since cycles measure computational resources, the value of\n/// `balance()` can change from one call to the next.\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// Returns the actor's current balance of cycles as `amount`.\n public let balance : () -> (amount : Nat) = Prim.cyclesBalance;\n\n /// Returns the currently available `amount` of cycles.\n /// The amount available is the amount received in the current call,\n /// minus the cumulative amount `accept`ed by this call.\n /// On exit from the current shared function or async expression via `return` or `throw`\n /// any remaining available amount is automatically\n /// refunded to the caller/context.\n public let available : () -> (amount : Nat) = Prim.cyclesAvailable;\n\n /// Transfers up to `amount` from `available()` to `balance()`.\n /// Returns the amount actually transferred, which may be less than\n /// requested, for example, if less is available, or if canister balance limits are reached.\n public let accept : (amount : Nat) -> (accepted : Nat) = Prim.cyclesAccept;\n\n /// Indicates additional `amount` of cycles to be transferred in\n /// the next call, that is, evaluation of a shared function call or\n /// async expression.\n /// Traps if the current total would exceed 2^128 cycles.\n /// Upon the call, but not before, the total amount of cycles ``add``ed since\n /// the last call is deducted from `balance()`.\n /// If this total exceeds `balance()`, the caller traps, aborting the call.\n ///\n /// **Note**: the implicit register of added amounts is reset to zero on entry to\n /// a shared function and after each shared function call or resume from an await.\n public let add : (amount : Nat) -> () = Prim.cyclesAdd;\n\n /// Reports `amount` of cycles refunded in the last `await` of the current\n /// context, or zero if no await has occurred yet.\n /// Calling `refunded()` is solely informational and does not affect `balance()`.\n /// Instead, refunds are automatically added to the current balance,\n /// whether or not `refunded` is used to observe them.\n public let refunded : () -> (amount : Nat) = Prim.cyclesRefunded;\n\n}\n"},"Hash.mo":{"content":"/// Hash values\n\nimport Prim \"mo:⛔\";\nimport Iter \"Iter\";\n\nmodule {\n\n /// Hash values represent a string of _hash bits_, packed into a `Nat32`.\n public type Hash = Nat32;\n\n /// The hash length, always 31.\n public let length : Nat = 31; // Why not 32?\n\n /// Project a given bit from the bit vector.\n public func bit(h : Hash, pos : Nat) : Bool {\n assert (pos <= length);\n (h & (Prim.natToNat32(1) << Prim.natToNat32(pos))) != Prim.natToNat32(0)\n };\n\n /// Test if two hashes are equal\n public func equal(ha : Hash, hb : Hash) : Bool {\n ha == hb\n };\n\n /// Computes a hash from the least significant 32-bits of `n`, ignoring other bits.\n /// @deprecated For large `Nat` values consider using a bespoke hash function that considers all of the argument's bits.\n public func hash(n : Nat) : Hash {\n let j = Prim.intToNat32Wrap(n);\n hashNat8(\n [j & (255 << 0),\n j & (255 << 8),\n j & (255 << 16),\n j & (255 << 24)\n ]);\n };\n\n /// @deprecated This function will be removed in future.\n public func debugPrintBits(bits : Hash) {\n for (j in Iter.range(0, length - 1)) {\n if (bit(bits, j)) {\n Prim.debugPrint(\"1\")\n } else {\n Prim.debugPrint(\"0\")\n }\n }\n };\n\n /// @deprecated This function will be removed in future.\n public func debugPrintBitsRev(bits : Hash) {\n for (j in Iter.revRange(length - 1, 0)) {\n if (bit(bits, Prim.abs(j))) {\n Prim.debugPrint(\"1\")\n } else {\n Prim.debugPrint(\"0\")\n }\n }\n };\n\n\n /// Jenkin's one at a time:\n ///\n /// https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time\n ///\n /// The input type should actually be `[Nat8]`.\n /// Note: Be sure to explode each `Nat8` of a `Nat32` into its own `Nat32`, and to shift into lower 8 bits.\n\n // should this really be public?\n // NB: Int.mo contains a local copy of hashNat8 (redefined to suppress the deprecation warning).\n /// @deprecated This function may be removed or changed in future.\n public func hashNat8(key : [Hash]) : Hash {\n var hash : Nat32 = 0;\n for (natOfKey in key.vals()) {\n hash := hash +% natOfKey;\n hash := hash +% hash << 10;\n hash := hash ^ (hash >> 6);\n };\n hash := hash +% hash << 3;\n hash := hash ^ (hash >> 11);\n hash := hash +% hash << 15;\n return hash;\n };\n\n}\n"},"Float.mo":{"content":"/// 64-bit Floating-point numbers\n\nimport Prim \"mo:⛔\";\nimport Int \"Int\";\n\nmodule {\n\n /// 64-bit floating point numbers.\n public type Float = Prim.Types.Float;\n\n /// Ratio of the circumference of a circle to its diameter.\n public let pi : Float = 3.14159265358979323846; // taken from musl math.h\n\n /// Base of the natural logarithm.\n public let e : Float = 2.7182818284590452354; // taken from musl math.h\n\n /// Returns the absolute value of `x`.\n public let abs : (x : Float) -> Float = Prim.floatAbs;\n\n /// Returns the square root of `x`.\n public let sqrt : (x : Float) -> Float = Prim.floatSqrt;\n\n /// Returns the smallest integral float greater than or equal to `x`.\n public let ceil : (x : Float) -> Float = Prim.floatCeil;\n\n /// Returns the largest integral float less than or equal to `x`.\n public let floor : (x : Float) -> Float = Prim.floatFloor;\n\n /// Returns the nearest integral float not greater in magnitude than `x`.\n public let trunc : (x : Float) -> Float = Prim.floatTrunc;\n\n /// Returns the nearest integral float to `x`.\n public let nearest : (x : Float) -> Float = Prim.floatNearest;\n\n /// Returns `x` if `x` and `y` have same sign, otherwise `x` with negated sign.\n public let copySign : (x : Float, y : Float) -> Float = Prim.floatCopySign;\n\n /// Returns the smaller value of `x` and `y`.\n public let min : (x : Float, y : Float) -> Float = Prim.floatMin;\n\n /// Returns the larger value of `x` and `y`.\n public let max : (x : Float, y : Float) -> Float = Prim.floatMax;\n\n /// Returns the sine of the radian angle `x`.\n public let sin : (x : Float) -> Float = Prim.sin;\n\n /// Returns the cosine of the radian angle `x`.\n public let cos : (x : Float) -> Float = Prim.cos;\n\n /// Returns the tangent of the radian angle `x`.\n public let tan : (x : Float) -> Float = Prim.tan;\n\n /// Returns the arc sine of `x` in radians.\n public let arcsin: (x : Float) -> Float = Prim.arcsin;\n\n /// Returns the arc cosine of `x` in radians.\n public let arccos : (x : Float) -> Float = Prim.arccos;\n\n /// Returns the arc tangent of `x` in radians.\n public let arctan : (x : Float) -> Float = Prim.arctan;\n\n /// Given `(y,x)`, returns the arc tangent in radians of `y/x` based on the signs of both values to determine the correct quadrant.\n public let arctan2 : (y : Float, x : Float) -> Float = Prim.arctan2;\n\n /// Returns the value of `e` raised to the `x`-th power.\n public let exp : (x : Float) -> Float = Prim.exp;\n\n /// Returns the natural logarithm (base-`e`) of `x`.\n public let log : (x : Float) -> Float = Prim.log;\n\n /// Formatting. `format(fmt, x)` formats `x` to `Text` according to the\n /// formatting directive `fmt`, which can take one of the following forms:\n ///\n /// * `#fix prec` as fixed-point format with `prec` digits\n /// * `#exp prec` as exponential format with `prec` digits\n /// * `#gen prec` as generic format with `prec` digits\n /// * `#hex prec` as hexadecimal format with `prec` digits\n /// * `#exact` as exact format that can be decoded without loss.\n public func format\n (fmt : { #fix : Nat8; #exp : Nat8; #gen : Nat8; #hex : Nat8; #exact }, x : Float) : Text =\n switch fmt {\n case (#fix(prec)) { Prim.floatToFormattedText(x, prec, 0) };\n case (#exp(prec)) { Prim.floatToFormattedText(x, prec, 1) };\n case (#gen(prec)) { Prim.floatToFormattedText(x, prec, 2) };\n case (#hex(prec)) { Prim.floatToFormattedText(x, prec, 3) };\n case (#exact) { Prim.floatToFormattedText(x, 17, 2) };\n };\n\n /// Conversion to Text. Use `format(fmt, x)` for more detailed control.\n public let toText : Float -> Text = Prim.floatToText;\n\n /// Conversion to Int64 by truncating Float, equivalent to `toInt64(trunc(f))`\n public let toInt64 : Float -> Int64 = Prim.floatToInt64;\n\n /// Conversion from Int64.\n public let fromInt64 : Int64 -> Float = Prim.int64ToFloat;\n\n /// Conversion to Int.\n public let toInt : Float -> Int = Prim.floatToInt;\n\n /// Conversion from Int. May result in `Inf`.\n public let fromInt : Int -> Float = Prim.intToFloat;\n\n /// Returns `x == y`.\n public func equal(x : Float, y : Float) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Float, y : Float) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Float, y : Float) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Float, y : Float) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Float, y : Float) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Float, y : Float) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Float, y : Float) : { #less; #equal; #greater} {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x` .\n public func neq(x : Float) : Float { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n public func add(x : Float, y : Float) : Float { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n public func sub(x : Float, y : Float) : Float { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n public func mul(x : Float, y : Float) : Float { x * y };\n\n /// Returns the division of `x` by `y`, `x / y`.\n public func div(x : Float, y : Float) : Float { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n public func rem(x : Float, y : Float) : Float { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n public func pow(x : Float, y : Float) : Float { x ** y };\n\n};\n"},"Heap.mo":{"content":"/// Priority Queue\n///\n/// This module provides purely-functional priority queue based on leftist heap\n\nimport O \"Order\";\nimport P \"Prelude\";\nimport L \"List\";\nimport I \"Iter\";\n\nmodule {\n\n public type Tree<T> = ?(Int, T, Tree<T>, Tree<T>);\n\n public class Heap<T>(ord : (T, T) -> O.Order) {\n var heap : Tree<T> = null;\n\n /// Get purely-functional representation\n public func share() : Tree<T> {\n heap\n };\n\n /// Put purely-functional representation into class. Need to make sure the tree is constructed with the same compare function\n public func unsafeUnshare(t : Tree<T>) {\n heap := t;\n };\n\n /// Insert an element to the heap\n public func put(x : T) {\n heap := merge(heap, ?(1, x, null, null), ord);\n };\n\n /// Return the minimal element\n public func peekMin() : ?T {\n switch heap {\n case (null) { null };\n case (?(_, x, _, _)) { ?x };\n }\n };\n\n /// Delete the minimal element\n public func deleteMin() {\n switch heap {\n case null {};\n case (?(_, _, a, b)) { heap := merge(a, b, ord) };\n }\n };\n\n /// Remove the minimal element and return its value\n public func removeMin() : ?T {\n switch heap {\n case null { null };\n case (?(_, x, a, b)) {\n heap := merge(a, b, ord);\n ?x\n };\n }\n };\n };\n\n func rank<T>(heap : Tree<T>) : Int {\n switch heap {\n case null { 0 };\n case (?(r, _, _, _)) { r };\n }\n };\n\n func makeT<T>(x : T, a : Tree<T>, b : Tree<T>) : Tree<T> {\n if (rank(a) >= rank(b)) {\n ?(rank(b) + 1, x, a, b)\n } else {\n ?(rank(a) + 1, x, b, a)\n };\n };\n\n func merge<T>(h1 : Tree<T>, h2 : Tree<T>, ord : (T, T) -> O.Order) : Tree<T> {\n switch (h1, h2) {\n case (null, h) { h };\n case (h, null) { h };\n case (?(_, x, a, b), ?(_, y, c, d)) {\n switch (ord(x,y)) {\n case (#less) { makeT(x, a, merge(b, h2, ord)) };\n case _ { makeT(y, c, merge(d, h1, ord)) };\n };\n };\n };\n };\n\n /// Convert iterator into a heap in O(N) time.\n public func fromIter<T>(iter : I.Iter<T>, ord : (T, T) -> O.Order) : Heap<T> {\n let heap = Heap<T>(ord);\n func build(xs : L.List<Tree<T>>) : Tree<T> {\n func join(xs : L.List<Tree<T>>) : L.List<Tree<T>> {\n switch(xs) {\n case (null) { null };\n case (?(hd, null)) { ?(hd, null) };\n case (?(h1, ?(h2, tl))) { ?(merge(h1, h2, ord), join(tl)) };\n }\n };\n switch(xs) {\n case null { P.unreachable() };\n case (?(hd, null)) { hd };\n case _ { build(join(xs)) };\n };\n };\n let list = I.toList(I.map(iter, func (x : T) : Tree<T> { ?(1, x, null, null) } ));\n if (not L.isNil(list)) {\n let t = build(list);\n heap.unsafeUnshare(t);\n };\n heap\n };\n\n};\n"},"Func.mo":{"content":"/// Functions on functions\n///\n/// (Most commonly used when programming in functional style using higher-order\n/// functions.)\n\nmodule {\n\n /// The composition of two functions `f` and `g` is a function that applies `g` and then `f`.\n ///\n /// ```\n /// compose(f, g)(x) = f(g(x))\n /// ```\n public func compose<A, B, C>(f : B -> C, g : A -> B) : A -> C {\n func (x : A) : C {\n f(g(x));\n };\n };\n\n /// The `identity` function returns its argument.\n /// ```motoko\n /// import Func \"mo:base/Func\";\n /// assert(Func.identity(10) == 10);\n /// assert(Func.identity(true) == true);\n /// ```\n public func identity<A>(x : A) : A = x;\n\n /// The const function is a _curried_ function that accepts an argument `x`,\n /// and then returns a function that discards its argument and always returns\n /// the `x`.\n ///\n /// ```motoko\n /// import Func \"mo:base/Func\";\n /// assert(Func.const<Nat, Text>(10)(\"hello\") == 10);\n /// assert(Func.const<Bool, Nat>(true)(20) == true);\n /// ```\n public func const<A, B>(x : A) : B -> A =\n func (_) = x;\n}\n"},"Int.mo":{"content":"/// Integer numbers\n///\n/// Most operations on integers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n\nimport Prim \"mo:⛔\";\nimport Prelude \"Prelude\";\nimport Hash \"Hash\";\n\nmodule {\n\n /// Infinite precision signed integers.\n public type Int = Prim.Types.Int;\n\n /// Returns the absolute value of the number\n public let abs : Int -> Nat = Prim.abs;\n\n /// Conversion.\n public let toText : Int -> Text = func(x) {\n if (x == 0) {\n return \"0\";\n };\n\n let isNegative = x < 0;\n var int = if isNegative { -x } else { x };\n\n var text = \"\";\n let base = 10;\n\n while (int > 0) {\n let rem = int % base;\n text := (switch (rem) {\n case 0 { \"0\" };\n case 1 { \"1\" };\n case 2 { \"2\" };\n case 3 { \"3\" };\n case 4 { \"4\" };\n case 5 { \"5\" };\n case 6 { \"6\" };\n case 7 { \"7\" };\n case 8 { \"8\" };\n case 9 { \"9\" };\n case _ { Prelude.unreachable() };\n }) # text;\n int := int / base;\n };\n\n return if isNegative { \"-\" # text } else { text };\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int, y : Int) : Int {\n if (x < y) { x } else { y };\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max(x : Int, y : Int) : Int {\n if (x < y) { y } else { x };\n };\n\n // this is a local copy of deprecated Hash.hashNat8 (redefined to suppress the warning)\n private func hashNat8(key : [Nat32]) : Hash.Hash {\n var hash : Nat32 = 0;\n for (natOfKey in key.vals()) {\n hash := hash +% natOfKey;\n hash := hash +% hash << 10;\n hash := hash ^ (hash >> 6);\n };\n hash := hash +% hash << 3;\n hash := hash ^ (hash >> 11);\n hash := hash +% hash << 15;\n return hash;\n };\n\n /// Computes a hash from the least significant 32-bits of `i`, ignoring other bits.\n /// @deprecated For large `Int` values consider using a bespoke hash function that considers all of the argument's bits.\n public func hash(i : Int) : Hash.Hash {\n // CAUTION: This removes the high bits!\n let j = Prim.int32ToNat32(Prim.intToInt32Wrap(i));\n hashNat8(\n [j & (255 << 0),\n j & (255 << 8),\n j & (255 << 16),\n j & (255 << 24)\n ]);\n };\n\n /// @deprecated This function will be removed in future.\n public func hashAcc(h1 : Hash.Hash, i : Int) : Hash.Hash {\n // CAUTION: This removes the high bits!\n let j = Prim.int32ToNat32(Prim.intToInt32Wrap(i));\n hashNat8(\n [h1,\n j & (255 << 0),\n j & (255 << 8),\n j & (255 << 16),\n j & (255 << 24)\n ]);\n };\n\n /// Returns `x == y`.\n public func equal(x : Int, y : Int) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int, y : Int) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int, y : Int) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int, y : Int) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int, y : Int) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int, y : Int) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int, y : Int) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x` .\n public func neq(x : Int) : Int { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n public func add(x : Int, y : Int) : Int { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n public func sub(x : Int, y : Int) : Int { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n public func mul(x : Int, y : Int) : Int { x * y };\n\n /// Returns the division of `x` by `y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int, y : Int) : Int { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int, y : Int) : Int { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n public func pow(x : Int, y : Int) : Int { x ** y };\n\n}\n\n"},"Int32.mo":{"content":"/// 32-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 32-bit signed integers.\n public type Int32 = Prim.Types.Int32;\n\n /// Conversion.\n public let toInt : Int32 -> Int = Prim.int32ToInt;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromInt : Int -> Int32 = Prim.intToInt32;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Int32 = Prim.intToInt32Wrap;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromNat32 : Nat32 -> Int32 = Prim.nat32ToInt32;\n\n /// Conversion. Wraps on overflow/underflow.\n public let toNat32 : Int32 -> Nat32 = Prim.int32ToNat32;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Int32) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`. Traps when `x = -2^31`.\n public func abs(x : Int32) : Int32 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int32, y : Int32) : Int32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Int32, y : Int32) : Int32 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Int32, y : Int32) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int32, y : Int32) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int32, y : Int32) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int32, y : Int32) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int32, y : Int32) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int32, y : Int32) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int32, y : Int32) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`. Traps on overflow.\n public func neg(x : Int32) : Int32 { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Int32, y : Int32) : Int32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Int32, y : Int32) : Int32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Int32, y : Int32) : Int32 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int32, y : Int32) : Int32 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int32, y : Int32) : Int32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Int32, y : Int32) : Int32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Int32, y : Int32) : Int32 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Int32, y : Int32) : Int32 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Int32, y : Int32) : Int32 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Int32, y : Int32) : Int32 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Int32, y : Int32) : Int32 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Int32, y : Int32) : Int32 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Int32, y : Int32) : Int32 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Int32, y : Int32) : Int32 { x <>> y };\n\n /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n public func bittest(x : Int32, p : Nat) : Bool {\n Prim.btstInt32(x, Prim.intToInt32(p));\n };\n\n /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n public func bitset(x : Int32, p : Nat) : Int32 {\n x | (1 << Prim.intToInt32(p));\n };\n\n /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n public func bitclear(x : Int32, p : Nat) : Int32 {\n x & ^(1 << Prim.intToInt32(p));\n };\n\n /// Returns the value of flipping bit `p mod 16` in `x`.\n public func bitflip(x : Int32, p : Nat) : Int32 {\n x ^ (1 << Prim.intToInt32(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Int32) -> Int32 = Prim.popcntInt32;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Int32) -> Int32 = Prim.clzInt32;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Int32) -> Int32 = Prim.ctzInt32;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Int32, y : Int32) : Int32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Int32, y : Int32) : Int32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Int32, y : Int32) : Int32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n public func powWrap(x : Int32, y : Int32) : Int32 { x **% y };\n\n}\n"},"Int8.mo":{"content":"/// 8-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 8-bit signed integers.\n public type Int8 = Prim.Types.Int8;\n\n /// Conversion.\n public let toInt : Int8 -> Int = Prim.int8ToInt;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromInt : Int -> Int8 = Prim.intToInt8;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Int8 = Prim.intToInt8Wrap;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromNat8 : Nat8 -> Int8 = Prim.nat8ToInt8;\n\n /// Conversion. Wraps on overflow/underflow.\n public let toNat8 : Int8 -> Nat8 = Prim.int8ToNat8;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Int8) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`. Traps when `x = -2^7`.\n public func abs(x : Int8) : Int8 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int8, y : Int8) : Int8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Int8, y : Int8) : Int8 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Int8, y : Int8) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int8, y : Int8) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int8, y : Int8) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int8, y : Int8) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int8, y : Int8) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int8, y : Int8) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int8, y : Int8) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`. Traps on overflow.\n public func neg(x : Int8) : Int8 { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Int8, y : Int8) : Int8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Int8, y : Int8) : Int8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Int8, y : Int8) : Int8 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int8, y : Int8) : Int8 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int8, y : Int8) : Int8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Int8, y : Int8) : Int8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Int8, y : Int8) : Int8 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Int8, y : Int8) : Int8 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Int8, y : Int8) : Int8 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Int8, y : Int8) : Int8 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Int8, y : Int8) : Int8 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Int8, y : Int8) : Int8 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Int8, y : Int8) : Int8 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Int8, y : Int8) : Int8 { x <>> y };\n\n /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`.\n public func bittest(x : Int8, p : Nat) : Bool {\n Prim.btstInt8(x, Prim.intToInt8(p));\n };\n\n /// Returns the value of setting bit `p mod 8` in `x` to `1`.\n public func bitset(x : Int8, p : Nat) : Int8 {\n x | (1 << Prim.intToInt8(p));\n };\n\n /// Returns the value of clearing bit `p mod 8` in `x` to `0`.\n public func bitclear(x : Int8, p : Nat) : Int8 {\n x & ^(1 << Prim.intToInt8(p));\n };\n\n /// Returns the value of flipping bit `p mod 8` in `x`.\n public func bitflip(x : Int8, p : Nat) : Int8 {\n x ^ (1 << Prim.intToInt8(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Int8) -> Int8 = Prim.popcntInt8;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Int8) -> Int8 = Prim.clzInt8;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Int8) -> Int8 = Prim.ctzInt8;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Int8, y : Int8) : Int8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Int8, y : Int8) : Int8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Int8, y : Int8) : Int8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n public func powWrap(x : Int8, y : Int8) : Int8 { x **% y };\n\n}\n"},"Int16.mo":{"content":"/// 16-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 16-bit signed integers\n public type Int16 = Prim.Types.Int16;\n\n /// Conversion.\n public let toInt : Int16 -> Int = Prim.int16ToInt;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromInt : Int -> Int16 = Prim.intToInt16;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Int16 = Prim.intToInt16Wrap;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromNat16 : Nat16 -> Int16 = Prim.nat16ToInt16;\n\n /// Conversion. Wraps on overflow/underflow.\n public let toNat16 : Int16 -> Nat16 = Prim.int16ToNat16;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Int16) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`. Traps when `x = -2^15`.\n public func abs(x : Int16) : Int16 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int16, y : Int16) : Int16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Int16, y : Int16) : Int16 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Int16, y : Int16) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int16, y : Int16) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int16, y : Int16) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int16, y : Int16) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int16, y : Int16) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int16, y : Int16) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int16, y : Int16) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`. Traps on overflow.\n public func neg(x : Int16) : Int16 { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Int16, y : Int16) : Int16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Int16, y : Int16) : Int16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Int16, y : Int16) : Int16 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int16, y : Int16) : Int16 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int16, y : Int16) : Int16 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Int16, y : Int16) : Int16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Int16, y : Int16) : Int16 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Int16, y : Int16) : Int16 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Int16, y : Int16) : Int16 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Int16, y : Int16) : Int16 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Int16, y : Int16) : Int16 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Int16, y : Int16) : Int16 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Int16, y : Int16) : Int16 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Int16, y : Int16) : Int16 { x <>> y };\n\n /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n public func bittest(x : Int16, p : Nat) : Bool {\n Prim.btstInt16(x, Prim.intToInt16(p));\n };\n\n /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n public func bitset(x : Int16, p : Nat) : Int16 {\n x | (1 << Prim.intToInt16(p));\n };\n\n /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n public func bitclear(x : Int16, p : Nat) : Int16 {\n x & ^(1 << Prim.intToInt16(p));\n };\n\n /// Returns the value of flipping bit `p mod 16` in `x`.\n public func bitflip(x : Int16, p : Nat) : Int16 {\n x ^ (1 << Prim.intToInt16(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Int16) -> Int16 = Prim.popcntInt16;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Int16) -> Int16 = Prim.clzInt16;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Int16) -> Int16 = Prim.ctzInt16;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Int16, y : Int16) : Int16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Int16, y : Int16) : Int16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Int16, y : Int16) : Int16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n public func powWrap(x : Int16, y : Int16) : Int16 { x **% y };\n}\n"},"Iter.mo":{"content":"/// Iterators\n\nimport Array \"Array\";\nimport Buffer \"Buffer\";\nimport List \"List\";\nimport Order \"Order\";\n\nmodule {\n\n /// An iterator that produces values of type `T`. Calling `next` returns\n /// `null` when iteration is finished.\n ///\n /// Iterators are inherently stateful. Calling `next` \"consumes\" a value from\n /// the Iterator that cannot be put back, so keep that in mind when sharing\n /// iterators between consumers.\n ///\n /// An iterater `i` can be iterated over using\n /// ```\n /// for (x in i) {\n /// …do something with x…\n /// }\n /// ```\n public type Iter<T> = { next : () -> ?T };\n\n /// Creates an iterator that produces all `Nat`s from `x` to `y` including\n /// both of the bounds.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// assert(?1 == iter.next());\n /// assert(?2 == iter.next());\n /// assert(?3 == iter.next());\n /// assert(null == iter.next());\n /// ```\n public class range(x : Nat, y : Int) {\n var i = x;\n public func next() : ?Nat { if (i > y) { null } else {let j = i; i += 1; ?j} };\n };\n\n /// Like `range` but produces the values in the opposite\n /// order.\n public class revRange(x : Int, y : Int) {\n var i = x;\n public func next() : ?Int { if (i < y) { null } else {let j = i; i -= 1; ?j} };\n };\n\n /// Calls a function `f` on every value produced by an iterator and discards\n /// the results. If you're looking to keep these results use `map` instead.\n ///\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// var sum = 0;\n /// Iter.iterate<Nat>(Iter.range(1, 3), func(x, _index) {\n /// sum += x;\n /// });\n /// assert(6 == sum)\n /// ```\n public func iterate<A>(\n xs : Iter<A>,\n f : (A, Nat) -> ()\n ) {\n var i = 0;\n label l loop {\n switch (xs.next()) {\n case (?next) {\n f(next, i);\n };\n case (null) {\n break l;\n };\n };\n i += 1;\n continue l;\n };\n };\n\n /// Consumes an iterator and counts how many elements were produced\n /// (discarding them in the process).\n public func size<A>(xs : Iter<A>) : Nat {\n var len = 0;\n iterate<A>(xs, func (x, i) { len += 1; });\n len;\n };\n\n /// Takes a function and an iterator and returns a new iterator that lazily applies\n /// the function to every element produced by the argument iterator.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// let mappedIter = Iter.map(iter, func (x : Nat) : Nat { x * 2 });\n /// assert(?2 == mappedIter.next());\n /// assert(?4 == mappedIter.next());\n /// assert(?6 == mappedIter.next());\n /// assert(null == mappedIter.next());\n /// ```\n public func map<A, B>(xs : Iter<A>, f : A -> B) : Iter<B> = object {\n public func next() : ?B {\n switch (xs.next()) {\n case (?next) {\n ?f(next);\n };\n case (null) {\n null;\n };\n };\n };\n };\n\n /// Takes a function and an iterator and returns a new iterator that produces\n /// elements from the original iterator if and only if the predicate is true.\n /// ```motoko\n /// import Iter \"o:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// let mappedIter = Iter.filter(iter, func (x : Nat) : Bool { x % 2 == 1 });\n /// assert(?1 == mappedIter.next());\n /// assert(?3 == mappedIter.next());\n /// assert(null == mappedIter.next());\n /// ```\n public func filter<A>(xs : Iter<A>, f : A -> Bool) : Iter<A> = object {\n public func next() : ?A {\n loop {\n switch (xs.next()) {\n case (null) {\n return null;\n };\n case (?x) {\n if (f(x)) {\n return ?x;\n };\n };\n };\n };\n null;\n };\n };\n\n /// Creates an iterator that produces an infinite sequence of `x`.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.make(10);\n /// assert(?10 == iter.next());\n /// assert(?10 == iter.next());\n /// assert(?10 == iter.next());\n /// // ...\n /// ```\n public func make<A>(x : A) : Iter<A> = object {\n public func next() : ?A {\n ?x;\n };\n };\n\n /// Creates an iterator that produces the elements of an Array in ascending index order.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.fromArray([1, 2, 3]);\n /// assert(?1 == iter.next());\n /// assert(?2 == iter.next());\n /// assert(?3 == iter.next());\n /// assert(null == iter.next());\n /// ```\n public func fromArray<A>(xs : [A]) : Iter<A> {\n var ix : Nat = 0;\n let size = xs.size();\n object {\n public func next() : ?A {\n if (ix >= size) {\n return null\n } else {\n let res = ?(xs[ix]);\n ix += 1;\n return res\n }\n }\n }\n };\n\n /// Like `fromArray` but for Arrays with mutable elements. Captures\n /// the elements of the Array at the time the iterator is created, so\n /// further modifications won't be reflected in the iterator.\n public func fromArrayMut<A>(xs : [var A]) : Iter<A> {\n fromArray<A>(Array.freeze<A>(xs));\n };\n\n /// Like `fromArray` but for Lists.\n public let fromList = List.toIter;\n\n /// Consumes an iterator and collects its produced elements in an Array.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// assert([1, 2, 3] == Iter.toArray(iter));\n /// ```\n public func toArray<A>(xs : Iter<A>) : [A] {\n let buffer = Buffer.Buffer<A>(8);\n iterate(xs, func(x : A, ix : Nat) { buffer.add(x) });\n return Buffer.toArray(buffer)\n };\n\n /// Like `toArray` but for Arrays with mutable elements.\n public func toArrayMut<A>(xs : Iter<A>) : [var A] {\n Array.thaw<A>(toArray<A>(xs));\n };\n\n /// Like `toArray` but for Lists.\n public func toList<A>(xs : Iter<A>) : List.List<A> {\n var result = List.nil<A>();\n iterate<A>(xs, func (x, _i) {\n result := List.push<A>(x, result);\n });\n List.reverse<A>(result);\n };\n\n /// Sorted iterator. Will iterate over *all* elements to sort them, necessarily.\n public func sort<A>(xs : Iter<A>, compare : (A, A) -> Order.Order) : Iter<A> {\n let a = toArrayMut<A>(xs);\n Array.sortInPlace<A>(a, compare);\n fromArrayMut<A>(a)\n };\n\n};\n"},"Nat32.mo":{"content":"/// 32-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 32-bit natural numbers.\n public type Nat32 = Prim.Types.Nat32;\n\n /// Conversion.\n public let toNat : Nat32 -> Nat = Prim.nat32ToNat;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromNat : Nat -> Nat32 = Prim.natToNat32;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Nat32 = Prim.intToNat32Wrap;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Nat32) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat32, y : Nat32) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat32, y : Nat32) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat32, y : Nat32) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat32, y : Nat32) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat32, y : Nat32) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat32, y : Nat32) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat32, y : Nat32) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Nat32, y : Nat32) : Nat32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Nat32, y : Nat32) : Nat32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Nat32, y : Nat32) : Nat32 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat32, y : Nat32) : Nat32 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat32, y : Nat32) : Nat32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Nat32, y : Nat32) : Nat32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Nat32, y : Nat32) : Nat32 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Nat32, y : Nat32) : Nat32 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Nat32, y : Nat32) : Nat32 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Nat32, y : Nat32) : Nat32 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Nat32, y : Nat32) : Nat32 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Nat32, y : Nat32) : Nat32 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Nat32, y : Nat32) : Nat32 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Nat32, y : Nat32) : Nat32 { x <>> y };\n\n /// Returns the value of bit `p mod 32` in `x`, `(x & 2^(p mod 32)) == 2^(p mod 32)`.\n public func bittest(x : Nat32, p : Nat) : Bool {\n Prim.btstNat32(x, Prim.natToNat32(p));\n };\n\n /// Returns the value of setting bit `p mod 32` in `x` to `1`.\n public func bitset(x : Nat32, p : Nat) : Nat32 {\n x | (1 << Prim.natToNat32(p));\n };\n\n /// Returns the value of clearing bit `p mod 32` in `x` to `0`.\n public func bitclear(x : Nat32, p : Nat) : Nat32 {\n x & ^(1 << Prim.natToNat32(p));\n };\n\n /// Returns the value of flipping bit `p mod 32` in `x`.\n public func bitflip(x : Nat32, p : Nat) : Nat32 {\n x ^ (1 << Prim.natToNat32(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Nat32) -> Nat32 = Prim.popcntNat32;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Nat32) -> Nat32 = Prim.clzNat32;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Nat32) -> Nat32 = Prim.ctzNat32;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Nat32, y : Nat32) : Nat32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Nat32, y : Nat32) : Nat32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Nat32, y : Nat32) : Nat32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n public func powWrap(x : Nat32, y : Nat32) : Nat32 { x **% y };\n\n}\n"},"Int64.mo":{"content":"/// 64-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 64-bit signed integers.\n public type Int64 = Prim.Types.Int64;\n\n /// Conversion.\n public let toInt : Int64 -> Int = Prim.int64ToInt;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromInt : Int -> Int64 = Prim.intToInt64;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Int64 = Prim.intToInt64Wrap;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromNat64 : Nat64 -> Int64 = Prim.nat64ToInt64;\n\n /// Conversion. Wraps on overflow/underflow.\n public let toNat64 : Int64 -> Nat64 = Prim.int64ToNat64;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Int64) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`. Traps when `x = -2^63`.\n public func abs(x : Int64) : Int64 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int64, y : Int64) : Int64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Int64, y : Int64) : Int64 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Int64, y : Int64) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int64, y : Int64) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int64, y : Int64) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int64, y : Int64) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int64, y : Int64) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int64, y : Int64) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int64, y : Int64) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`. Traps on overflow.\n public func neg(x : Int64) : Int64 { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Int64, y : Int64) : Int64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Int64, y : Int64) : Int64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Int64, y : Int64) : Int64 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int64, y : Int64) : Int64 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int64, y : Int64) : Int64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Int64, y : Int64) : Int64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Int64, y : Int64) : Int64 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Int64, y : Int64) : Int64 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Int64, y : Int64) : Int64 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Int64, y : Int64) : Int64 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Int64, y : Int64) : Int64 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Int64, y : Int64) : Int64 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Int64, y : Int64) : Int64 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Int64, y : Int64) : Int64 { x <>> y };\n\n /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`.\n public func bittest(x : Int64, p : Nat) : Bool {\n Prim.btstInt64(x, Prim.intToInt64(p));\n };\n\n /// Returns the value of setting bit `p mod 64` in `x` to `1`.\n public func bitset(x : Int64, p : Nat) : Int64 {\n x | (1 << Prim.intToInt64(p));\n };\n\n /// Returns the value of clearing bit `p mod 64` in `x` to `0`.\n public func bitclear(x : Int64, p : Nat) : Int64 {\n x & ^(1 << Prim.intToInt64(p));\n };\n\n /// Returns the value of flipping bit `p mod 64` in `x`.\n public func bitflip(x : Int64, p : Nat) : Int64 {\n x ^ (1 << Prim.intToInt64(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Int64) -> Int64 = Prim.popcntInt64;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Int64) -> Int64 = Prim.clzInt64;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Int64) -> Int64 = Prim.ctzInt64;\n\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Int64, y : Int64) : Int64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Int64, y : Int64) : Int64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Int64, y : Int64) : Int64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n public func powWrap(x : Int64, y : Int64) : Int64 { x **% y };\n\n}\n"},"Nat.mo":{"content":"/// Natural numbers\n///\n/// Most operations on natural numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n\nimport Int \"Int\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n\n /// Infinite precision natural numbers.\n public type Nat = Prim.Types.Nat;\n\n /// Conversion.\n public let toText : Nat -> Text = Int.toText;\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat, y : Nat) : Nat {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat, y : Nat) : Nat {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat, y : Nat) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat, y : Nat) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat, y : Nat) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat, y : Nat) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat, y : Nat) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat, y : Nat) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat, y : Nat) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n public func add(x : Nat, y : Nat) : Nat { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n public func sub(x : Nat, y : Nat) : Nat { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n public func mul(x : Nat, y : Nat) : Nat { x * y };\n\n /// Returns the division of `x` by `y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat, y : Nat) : Nat { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat, y : Nat) : Nat { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n public func pow(x : Nat, y : Nat) : Nat { x ** y };\n\n}\n"},"Nat64.mo":{"content":"/// 64-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 64-bit natural numbers.\n public type Nat64 = Prim.Types.Nat64;\n\n /// Conversion.\n public let toNat : Nat64 -> Nat = Prim.nat64ToNat;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromNat : Nat -> Nat64 = Prim.natToNat64;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Nat64 = Prim.intToNat64Wrap;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Nat64) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat64, y : Nat64) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat64, y : Nat64) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat64, y : Nat64) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat64, y : Nat64) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat64, y : Nat64) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat64, y : Nat64) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat64, y : Nat64) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Nat64, y : Nat64) : Nat64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Nat64, y : Nat64) : Nat64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Nat64, y : Nat64) : Nat64 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat64, y : Nat64) : Nat64 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat64, y : Nat64) : Nat64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Nat64, y : Nat64) : Nat64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Nat64, y : Nat64) : Nat64 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Nat64, y : Nat64) : Nat64 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Nat64, y : Nat64) : Nat64 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Nat64, y : Nat64) : Nat64 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Nat64, y : Nat64) : Nat64 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Nat64, y : Nat64) : Nat64 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Nat64, y : Nat64) : Nat64 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Nat64, y : Nat64) : Nat64 { x <>> y };\n\n /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`.\n public func bittest(x : Nat64, p : Nat) : Bool {\n Prim.btstNat64(x, Prim.natToNat64(p));\n };\n\n /// Returns the value of setting bit `p mod 64` in `x` to `1`.\n public func bitset(x : Nat64, p : Nat) : Nat64 {\n x | (1 << Prim.natToNat64(p));\n };\n\n /// Returns the value of clearing bit `p mod 64` in `x` to `0`.\n public func bitclear(x : Nat64, p : Nat) : Nat64 {\n x & ^(1 << Prim.natToNat64(p));\n };\n\n /// Returns the value of flipping bit `p mod 64` in `x`.\n public func bitflip(x : Nat64, p : Nat) : Nat64 {\n x ^ (1 << Prim.natToNat64(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Nat64) -> Nat64 = Prim.popcntNat64;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Nat64) -> Nat64 = Prim.clzNat64;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Nat64) -> Nat64 = Prim.ctzNat64;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Nat64, y : Nat64) : Nat64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Nat64, y : Nat64) : Nat64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Nat64, y : Nat64) : Nat64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n public func powWrap(x : Nat64, y : Nat64) : Nat64 { x **% y };\n\n}\n"},"Option.mo":{"content":"/// Typesafe nulls\n///\n/// Optional values can be seen as a typesafe `null`. A value of type `?Int` can\n/// be constructed with either `null` or `?42`. The simplest way to get at the\n/// contents of an optional is to use pattern matching:\n///\n/// ```motoko\n/// let optionalInt1 : ?Int = ?42;\n/// let optionalInt2 : ?Int = null;\n///\n/// let int1orZero : Int = switch optionalInt1 {\n/// case null 0;\n/// case (?int) int;\n/// };\n/// assert int1orZero == 42;\n///\n/// let int2orZero : Int = switch optionalInt2 {\n/// case null 0;\n/// case (?int) int;\n/// };\n/// assert int2orZero == 0;\n/// ```\n///\n/// The functions in this module capture some common operations when working\n/// with optionals that can be more succinct than using pattern matching.\n\nimport P \"Prelude\";\n\nmodule {\n\n /// Unwraps an optional value, with a default value, i.e. `get(?x, d) = x` and\n /// `get(null, d) = d`.\n public func get<T>(x : ?T, default : T) : T =\n switch x {\n case null { default };\n case (?x_) { x_ };\n };\n\n /// Unwraps an optional value using a function, or returns the default, i.e.\n /// `option(?x, f, d) = f x` and `option(null, f, d) = d`.\n public func getMapped<A, B>(x : ?A, f : A -> B, default : B) : B =\n switch x {\n case null { default };\n case (?x_) { f(x_) };\n };\n\n /// Applies a function to the wrapped value. `null`'s are left untouched.\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// assert Option.map<Nat, Nat>(?42, func x = x + 1) == ?43;\n /// assert Option.map<Nat, Nat>(null, func x = x + 1) == null;\n /// ```\n public func map<A, B>(x : ?A, f : A -> B) : ?B =\n switch x {\n case null { null };\n case (?x_) { ?f(x_) };\n };\n\n /// Applies a function to the wrapped value, but discards the result. Use\n /// `iterate` if you're only interested in the side effect `f` produces.\n ///\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// var counter : Nat = 0;\n /// Option.iterate(?5, func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// Option.iterate(null, func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// ```\n public func iterate<A>(x : ?A, f : A -> ()) =\n switch x {\n case null {};\n case (?x_) { f(x_) };\n };\n\n /// Applies an optional function to an optional value. Returns `null` if at\n /// least one of the arguments is `null`.\n public func apply<A, B>(x : ?A, f : ?(A -> B)) : ?B {\n switch (f, x) {\n case (?f_, ?x_) {\n ?f_(x_);\n };\n case (_, _) {\n null;\n };\n };\n };\n\n /// Applies a function to an optional value. Returns `null` if the argument is\n /// `null`, or the function returns `null`.\n public func chain<A, B>(x : ?A, f : A -> ?B) : ?B {\n switch(x) {\n case (?x_) {\n f(x_);\n };\n case (null) {\n null;\n };\n };\n };\n\n /// Given an optional optional value, removes one layer of optionality.\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// assert Option.flatten(?(?(42))) == ?42;\n /// assert Option.flatten(?(null)) == null;\n /// assert Option.flatten(null) == null;\n /// ```\n public func flatten<A>(x : ??A) : ?A {\n chain<?A, A>(x, func (x_ : ?A) : ?A {\n x_;\n });\n };\n\n /// Creates an optional value from a definite value.\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// assert Option.make(42) == ?42;\n /// ```\n public func make<A>(x: A) : ?A = ?x;\n\n /// Returns true if the argument is not `null`, otherwise returns false.\n public func isSome(x : ?Any) : Bool =\n switch x {\n case null { false };\n case _ { true };\n };\n\n /// Returns true if the argument is `null`, otherwise returns false.\n public func isNull(x : ?Any) : Bool =\n switch x {\n case null { true };\n case _ { false };\n };\n\n /// Asserts that the value is not `null`; fails otherwise.\n /// @deprecated Option.assertSome will be removed soon; use an assert expression instead\n public func assertSome(x : ?Any) =\n switch x {\n case null { P.unreachable() };\n case _ {};\n };\n\n /// Asserts that the value _is_ `null`; fails otherwise.\n /// @deprecated Option.assertNull will be removed soon; use an assert expression instead\n public func assertNull(x : ?Any) =\n switch x {\n case null { };\n case _ { P.unreachable() };\n };\n\n /// Unwraps an optional value, i.e. `unwrap(?x) = x`.\n ///\n /// @deprecated Option.unwrap is unsafe and fails if the argument is null; it will be removed soon; use a `switch` or `do?` expression instead\n public func unwrap<T>(x : ?T) : T =\n switch x {\n case null { P.unreachable() };\n case (?x_) { x_ };\n };\n}\n"},"Nat16.mo":{"content":"/// 16-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 16-bit natural numbers.\n public type Nat16 = Prim.Types.Nat16;\n\n /// Conversion.\n public let toNat : Nat16 -> Nat = Prim.nat16ToNat;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromNat : Nat -> Nat16 = Prim.natToNat16;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Nat16 = Prim.intToNat16Wrap;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Nat16) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat16, y : Nat16) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat16, y : Nat16) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat16, y : Nat16) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat16, y : Nat16) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat16, y : Nat16) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat16, y : Nat16) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat16, y : Nat16) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Nat16, y : Nat16) : Nat16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Nat16, y : Nat16) : Nat16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Nat16, y : Nat16) : Nat16 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat16, y : Nat16) : Nat16 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat16, y : Nat16) : Nat16 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Nat16, y : Nat16) : Nat16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Nat16, y : Nat16) : Nat16 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Nat16, y : Nat16) : Nat16 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Nat16, y : Nat16) : Nat16 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Nat16, y : Nat16) : Nat16 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Nat16, y : Nat16) : Nat16 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Nat16, y : Nat16) : Nat16 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Nat16, y : Nat16) : Nat16 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Nat16, y : Nat16) : Nat16 { x <>> y };\n\n /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n public func bittest(x : Nat16, p : Nat) : Bool {\n Prim.btstNat16(x, Prim.natToNat16(p));\n };\n\n /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n public func bitset(x : Nat16, p : Nat) : Nat16 {\n x | (1 << Prim.natToNat16(p));\n };\n\n /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n public func bitclear(x : Nat16, p : Nat) : Nat16 {\n x & ^(1 << Prim.natToNat16(p));\n };\n\n /// Returns the value of flipping bit `p mod 16` in `x`.\n public func bitflip(x : Nat16, p : Nat) : Nat16 {\n x ^ (1 << Prim.natToNat16(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Nat16) -> Nat16 = Prim.popcntNat16;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Nat16) -> Nat16 = Prim.clzNat16;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Nat16) -> Nat16 = Prim.ctzNat16;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Nat16, y : Nat16) : Nat16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Nat16, y : Nat16) : Nat16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Nat16, y : Nat16) : Nat16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n public func powWrap(x : Nat16, y : Nat16) : Nat16 { x **% y };\n\n}\n"},"List.mo":{"content":"/// Purely-functional, singly-linked lists.\n\nimport Array \"Array\";\nimport Iter \"IterType\";\nimport Option \"Option\";\nimport Order \"Order\";\nimport Result \"Result\";\n\nmodule {\n\n // A singly-linked list consists of zero or more _cons cells_, wherein\n // each cell contains a single list element (the cell's _head_), and a pointer to the\n // remainder of the list (the cell's _tail_).\n public type List<T> = ?(T, List<T>);\n\n /// Create an empty list.\n public func nil<T>() : List<T> = null;\n\n /// Check whether a list is empty and return true if the list is empty.\n public func isNil<T>(l : List<T>) : Bool {\n switch l {\n case null { true };\n case _ { false };\n }\n };\n\n /// Construct a list by pre-pending a value.\n /// This function is similar to a `list.cons(item)` function.\n public func push<T>(x : T, l : List<T>) : List<T> = ?(x, l);\n\n /// Return the last element of the list, if present.\n public func last<T>(l : List<T>) : ?T {\n switch l {\n case null { null };\n case (?(x, null)) { ?x };\n case (?(_, t)) { last<T>(t) };\n }\n };\n\n /// Treat the list as a stack.\n /// This function combines the `head` and (non-failing) `tail` operations into one operation.\n public func pop<T>(l : List<T>) : (?T, List<T>) {\n switch l {\n case null { (null, null) };\n case (?(h, t)) { (?h, t) };\n }\n };\n\n /// Return the length of the list.\n public func size<T>(l : List<T>) : Nat {\n func rec(l : List<T>, n : Nat) : Nat {\n switch l {\n case null { n };\n case (?(_, t)) { rec(t, n + 1) };\n }\n };\n rec(l,0)\n };\n /// Access any item in a list, zero-based.\n ///\n /// NOTE: Indexing into a list is a linear operation, and usually an\n /// indication that a list might not be the best data structure\n /// to use.\n public func get<T>(l : List<T>, n : Nat) : ?T {\n switch (n, l) {\n case (_, null) { null };\n case (0, (?(h, t))) { ?h };\n case (_, (?(_, t))) { get<T>(t, n - 1) };\n }\n };\n\n /// Reverses the list\n public func reverse<T>(l : List<T>) : List<T> {\n func rec(l : List<T>, r : List<T>) : List<T> {\n switch l {\n case null { r };\n case (?(h, t)) { rec(t, ?(h, r)) };\n }\n };\n rec(l, null)\n };\n\n /// Call the given function with each list element in turn.\n ///\n /// This function is equivalent to the `app` function in Standard ML Basis,\n /// and the `iter` function in OCaml.\n public func iterate<T>(l : List<T>, f : T -> ()) {\n switch l {\n case null { () };\n case (?(h, t)) { f(h); iterate<T>(t, f) };\n }\n };\n\n /// Call the given function on each list element and collect the results\n /// in a new list.\n public func map<T, S>(l : List<T>, f : T -> S) : List<S> {\n switch l {\n case null { null };\n case (?(h, t)) { ?(f(h), map<T, S>(t, f)) };\n }\n };\n\n /// Create a new list with only those elements of the original list for which\n /// the given function (often called the _predicate_) returns true.\n public func filter<T>(l : List<T>, f : T -> Bool) : List<T> {\n switch l {\n case null { null };\n case (?(h,t)) {\n if (f(h)) {\n ?(h,filter<T>(t, f))\n } else {\n filter<T>(t, f)\n }\n };\n };\n };\n\n /// Create two new lists from the results of a given function (`f`).\n /// The first list only includes the elements for which the given\n /// function `f` returns true and the second list only includes\n /// the elements for which the function returns false.\n public func partition<T>(l : List<T>, f : T -> Bool) : (List<T>, List<T>) {\n switch l {\n case null { (null, null) };\n case (?(h, t)) {\n if (f(h)) { // call f in-order\n let (l, r) = partition<T>(t, f);\n (?(h, l), r)\n } else {\n let (l, r) = partition<T>(t, f);\n (l, ?(h, r))\n }\n };\n };\n };\n\n /// Call the given function on each list element, and collect the non-null results\n /// in a new list.\n public func mapFilter<T,S>(l : List<T>, f : T -> ?S) : List<S> {\n switch l {\n case null { null };\n case (?(h,t)) {\n switch (f(h)) {\n case null { mapFilter<T,S>(t, f) };\n case (?h_){ ?(h_,mapFilter<T,S>(t, f)) };\n }\n };\n };\n };\n\n /// Maps a Result-returning function over a List and returns either\n /// the first error or a list of successful values.\n public func mapResult<A, R, E>(xs : List<A>, f : A -> Result.Result<R, E>) : Result.Result<List<R>, E> {\n func go(xs : List<A>, acc : List<R>) : Result.Result<List<R>, E> {\n switch xs {\n case null { #ok(acc) };\n case (?(head, tail)) {\n switch (f(head)) {\n case (#err(err)) { #err(err) };\n case (#ok(ok)) { go(tail, ?(ok, acc)) };\n };\n };\n }\n };\n Result.mapOk(go(xs, null), func (xs : List<R>) : List<R> = reverse(xs))\n };\n\n /// Append the elements from the reverse of one list to another list.\n func revAppend<T>(l : List<T>, m : List<T>) : List<T> {\n switch l {\n case null { m };\n case (?(h, t)) { revAppend(t, ?(h, m)) };\n }\n };\n\n /// Append the elements from one list to another list.\n public func append<T>(l : List<T>, m : List<T>) : List<T> {\n revAppend(reverse(l), m);\n };\n\n /// Concatenate a list of lists.\n ///\n /// In some languages, this operation is also known as a `list join`.\n public func flatten<T>(l : List<List<T>>) : List<T> {\n foldLeft<List<T>, List<T>>(l, null, func(a, b) { append<T>(a,b) });\n };\n\n /// Returns the first `n` elements of the given list.\n /// If the given list has fewer than `n` elements, this function returns\n /// a copy of the full input list.\n public func take<T>(l : List<T>, n:Nat) : List<T> {\n switch (l, n) {\n case (_, 0) { null };\n case (null, _) { null };\n case (?(h, t), m) {?(h, take<T>(t, m - 1))};\n }\n };\n\n /// Drop the first `n` elements from the given list.\n public func drop<T>(l : List<T>, n:Nat) : List<T> {\n switch (l, n) {\n case (l_, 0) { l_ };\n case (null, _) { null };\n case ((?(h, t)), m) { drop<T>(t, m - 1) };\n }\n };\n\n /// Fold the list left-to-right using the given function (`f`).\n public func foldLeft<T, S>(l : List<T>, a : S, f : (S, T) -> S) : S {\n switch l {\n case null { a };\n case (?(h, t)) { foldLeft(t, f(a, h), f) };\n };\n };\n\n /// Fold the list right-to-left using the given function (`f`).\n public func foldRight<T, S>(l : List<T>, a : S, f : (T, S) -> S) : S {\n switch l {\n case null { a };\n case (?(h, t)) { f(h, foldRight<T,S>(t, a, f)) };\n };\n };\n\n /// Return the first element for which the given predicate `f` is true,\n /// if such an element exists.\n public func find<T>(l: List<T>, f:T -> Bool) : ?T {\n switch l {\n case null { null };\n case (?(h, t)) { if (f(h)) { ?h } else { find<T>(t, f) } };\n };\n };\n\n /// Return true if there exists a list element for which\n /// the given predicate `f` is true.\n public func some<T>(l : List<T>, f : T -> Bool) : Bool {\n switch l {\n case null { false };\n case (?(h, t)) { f(h) or some<T>(t, f)};\n };\n };\n\n /// Return true if the given predicate `f` is true for all list\n /// elements.\n public func all<T>(l : List<T>, f : T -> Bool) : Bool {\n switch l {\n case null { true };\n case (?(h, t)) { f(h) and all<T>(t, f) };\n }\n };\n\n /// Merge two ordered lists into a single ordered list.\n /// This function requires both list to be ordered as specified\n /// by the given relation `lte`.\n public func merge<T>(l1 : List<T>, l2 : List<T>, lte : (T, T) -> Bool) : List<T> {\n switch (l1, l2) {\n case (null, _) { l2 };\n case (_, null) { l1 };\n case (?(h1, t1), ?(h2, t2)) {\n if (lte(h1, h2)) {\n ?(h1, merge<T>(t1, l2, lte))\n } else {\n ?(h2, merge<T>(l1, t2, lte))\n }\n };\n }\n };\n\n /// Compare two lists using lexicographic ordering specified by the given relation `lte`.\n public func compare<T>(l1 : List<T>, l2 : List<T>, compElm: (T, T) -> Order.Order) : Order.Order {\n switch (l1, l2) {\n case (null, null) { #equal };\n case (null, _) { #less };\n case (_, null) { #greater };\n case (?(h1, t1), ?(h2, t2)) {\n let hOrder = compElm(h1, h2);\n if (Order.isEqual(hOrder)) {\n compare<T>(t1, t2, compElm)\n } else {\n hOrder\n }\n };\n };\n };\n\n /// Compare two lists for equality as specified by the given relation `eq` on the elements.\n ///\n /// The function `isEq(l1, l2)` is equivalent to `lessThanEq(l1, l2) && lessThanEq(l2, l1)`,\n /// but the former is more efficient.\n public func equal<T>(l1 : List<T>, l2 : List<T>, eq :(T, T) -> Bool) : Bool {\n switch (l1, l2) {\n case (null, null) { true };\n case (null, _) { false };\n case (_, null) { false };\n case (?(h1, t1), ?(h2, t2)) { eq(h1, h2) and equal<T>(t1, t2, eq) };\n }\n };\n\n /// Generate a list based on a length and a function that maps from\n /// a list index to a list element.\n public func tabulate<T>(n : Nat, f : Nat -> T) : List<T> {\n var i = 0;\n var l : List<T> = null;\n while (i < n) {\n l := ?(f(i), l);\n i += 1;\n };\n reverse(l);\n };\n\n /// Create a list with exactly one element.\n public func make<X>(x : X) : List<X> = ?(x, null);\n\n /// Create a list of the given length with the same value in each position.\n public func replicate<X>(n : Nat, x : X) : List<X> {\n var i = 0;\n var l : List<X> = null;\n while (i < n) {\n l := ?(x, l);\n i += 1;\n };\n l;\n };\n\n /// Create a list of pairs from a pair of lists.\n ///\n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n public func zip<X, Y>(xs : List<X>, ys : List<Y>) : List<(X, Y)> =\n zipWith<X, Y, (X, Y)>(xs, ys, func (x, y) { (x, y) });\n\n /// Create a list in which elements are calculated from the function `f` and\n /// include elements occuring at the same position in the given lists.\n ///\n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n public func zipWith<X, Y, Z>(\n xs : List<X>,\n ys : List<Y>,\n f : (X, Y) -> Z\n ) : List<Z> {\n switch (pop<X>(xs)) {\n case (null, _) { null };\n case (?x, xt) {\n switch (pop<Y>(ys)) {\n case (null, _) { null };\n case (?y, yt) {\n push<Z>(f(x, y), zipWith<X, Y, Z>(xt, yt, f))\n }\n }\n }\n }\n };\n\n /// Split the given list at the given zero-based index.\n public func split<X>(n : Nat, xs : List<X>) : (List<X>, List<X>) {\n if (n == 0) {\n (null, xs)\n } else {\n func rec(n : Nat, xs : List<X>) : (List<X>, List<X>) {\n switch (pop<X>(xs)) {\n case (null, _) {\n (null, null)\n };\n case (?h, t) {\n if (n == 1) {\n (make<X>(h), t)\n } else {\n let (l, r) = rec(n - 1, t);\n (push<X>(h, l), r)\n }\n }\n }\n };\n rec(n, xs)\n }\n };\n\n /// Split the given list into chunks of length `n`.\n /// The last chunk will be shorter if the length of the given list\n /// does not divide by `n` evenly.\n public func chunks<X>(n : Nat, xs : List<X>) : List<List<X>> {\n let (l, r) = split<X>(n, xs);\n if (isNil<X>(l)) {\n null\n } else {\n push<List<X>>(l, chunks<X>(n, r))\n }\n };\n\n /// Convert an array into a list.\n public func fromArray<A>(xs : [A]) : List<A> {\n Array.foldRight<A, List<A>>(\n xs, nil<A>(),\n func (x : A, ys : List<A>) : List<A> {\n push<A>(x, ys);\n });\n };\n\n /// Convert a mutable array into a list.\n public func fromVarArray<A>(xs : [var A]) : List<A> =\n fromArray<A>(Array.freeze<A>(xs));\n\n /// Create an array from a list.\n public func toArray<A>(xs : List<A>) : [A] {\n let length = size<A>(xs);\n var list = xs;\n Array.tabulate<A>(length, func (i) {\n let popped = pop<A>(list);\n list := popped.1;\n switch (popped.0) {\n case null { loop { assert false } };\n case (?x) x;\n }\n });\n };\n\n /// Create a mutable array from a list.\n public func toVarArray<A>(xs : List<A>) : [var A] =\n Array.thaw<A>(toArray<A>(xs));\n\n /// Create an iterator from a list.\n public func toIter<A>(xs : List<A>) : Iter.Iter<A> {\n var state = xs;\n object {\n public func next() : ?A =\n switch state {\n case (?(hd, tl)) { state := tl; ?hd };\n case _ null\n }\n }\n }\n\n}\n"},"Nat8.mo":{"content":"/// 8-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 8-bit natural numbers.\n public type Nat8 = Prim.Types.Nat8;\n\n /// Conversion.\n public let toNat : Nat8 -> Nat = Prim.nat8ToNat;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromNat : Nat -> Nat8 = Prim.natToNat8;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Nat8 = Prim.intToNat8Wrap;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Nat8) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat8, y : Nat8) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat8, y : Nat8) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat8, y : Nat8) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat8, y : Nat8) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat8, y : Nat8) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat8, y : Nat8) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat8, y : Nat8) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Nat8, y : Nat8) : Nat8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Nat8, y : Nat8) : Nat8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Nat8, y : Nat8) : Nat8 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat8, y : Nat8) : Nat8 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat8, y : Nat8) : Nat8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Nat8, y : Nat8) : Nat8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Nat8, y : Nat8) : Nat8 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Nat8, y : Nat8) : Nat8 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Nat8, y : Nat8) : Nat8 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Nat8, y : Nat8) : Nat8 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Nat8, y : Nat8) : Nat8 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Nat8, y : Nat8) : Nat8 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Nat8, y : Nat8) : Nat8 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Nat8, y : Nat8) : Nat8 { x <>> y };\n\n /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`.\n public func bittest(x : Nat8, p : Nat) : Bool {\n Prim.btstNat8(x, Prim.natToNat8(p));\n };\n\n /// Returns the value of setting bit `p mod 8` in `x` to `1`.\n public func bitset(x : Nat8, p : Nat) : Nat8 {\n x | (1 << Prim.natToNat8(p));\n };\n\n /// Returns the value of clearing bit `p mod 8` in `x` to `0`.\n public func bitclear(x : Nat8, p : Nat) : Nat8 {\n x & ^(1 << Prim.natToNat8(p));\n };\n\n /// Returns the value of flipping bit `p mod 8` in `x`.\n public func bitflip(x : Nat8, p : Nat) : Nat8 {\n x ^ (1 << Prim.natToNat8(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Nat8) -> Nat8 = Prim.popcntNat8;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Nat8) -> Nat8 = Prim.clzNat8;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Nat8) -> Nat8 = Prim.ctzNat8;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Nat8, y : Nat8) : Nat8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Nat8, y : Nat8) : Nat8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Nat8, y : Nat8) : Nat8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n public func powWrap(x : Nat8, y : Nat8) : Nat8 { x **% y };\n\n}\n"},"ExperimentalStableMemory.mo":{"content":"/// Byte-level access to (virtual) _stable memory_.\n///\n/// **WARNING**: As its name suggests, this library is **experimental**, subject to change\n/// and may be replaced by safer alternatives in later versions of Motoko.\n/// Use at your own risk and discretion.\n///\n/// This is a lightweight abstraction over IC _stable memory_ and supports persisting\n/// raw binary data across Motoko upgrades.\n/// Use of this module is fully compatible with Motoko's use of\n/// _stable variables_, whose persistence mechanism also uses (real) IC stable memory internally, but does not interfere with this API.\n///\n/// Memory is allocated, using `grow(pages)`, sequentially and on demand, in units of 64KiB pages, starting with 0 allocated pages.\n/// New pages are zero initialized.\n/// Growth is capped by a soft limit on page count controlled by compile-time flag\n/// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n///\n/// Each `load` operation loads from byte address `offset` in little-endian\n/// format using the natural bit-width of the type in question.\n/// The operation traps if attempting to read beyond the current stable memory size.\n///\n/// Each `store` operation stores to byte address `offset` in little-endian format using the natural bit-width of the type in question.\n/// The operation traps if attempting to write beyond the current stable memory size.\n///\n/// Text values can be handled by using `Text.decodeUtf8` and `Text.encodeUtf8`, in conjunction with `loadBlob` and `storeBlob`.\n///\n/// The current page allocation and page contents is preserved across upgrades.\n///\n/// NB: The IC's actual stable memory size (`ic0.stable_size`) may exceed the\n/// page size reported by Motoko function `size()`.\n/// This (and the cap on growth) are to accommodate Motoko's stable variables.\n/// Applications that plan to use Motoko stable variables sparingly or not at all can\n/// increase `--max-stable-pages` as desired, approaching the IC maximum (currently 8GiB).\n/// All applications should reserve at least one page for stable variable data, even when no stable variables are used.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Current size of the stable memory, in pages.\n /// Each page is 64KiB (65536 bytes).\n /// Initially `0`.\n /// Preserved across upgrades, together with contents of allocated\n /// stable memory.\n public let size : () -> (pages : Nat64) =\n Prim.stableMemorySize;\n\n /// Grow current `size` of stable memory by `pagecount` pages.\n /// Each page is 64KiB (65536 bytes).\n /// Returns previous `size` when able to grow.\n /// Returns `0xFFFF_FFFF_FFFF_FFFF` if remaining pages insufficient.\n /// Every new page is zero-initialized, containing byte 0 at every offset.\n /// Function `grow` is capped by a soft limit on `size` controlled by compile-time flag\n /// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n public let grow : (new_pages : Nat64) -> (oldpages : Nat64) =\n Prim.stableMemoryGrow;\n\n /// Returns a query that, when called, returns the number of bytes of (real) IC stable memory that would be\n /// occupied by persisting its current stable variables before an upgrade.\n /// This function may be used to monitor or limit real stable memory usage.\n /// The query computes the estimate by running the first half of an upgrade, including any `preupgrade` system method.\n /// Like any other query, its state changes are discarded so no actual upgrade (or other state change) takes place.\n /// The query can only be called by the enclosing actor and will trap for other callers.\n public let stableVarQuery : () -> (shared query () -> async {size : Nat64}) =\n Prim.stableVarQuery;\n\n public let loadNat32 : (offset : Nat64) -> Nat32 =\n Prim.stableMemoryLoadNat32;\n public let storeNat32 : (offset : Nat64, value: Nat32) -> () =\n Prim.stableMemoryStoreNat32;\n\n public let loadNat8 : (offset : Nat64) -> Nat8 =\n Prim.stableMemoryLoadNat8;\n public let storeNat8 : (offset : Nat64, value : Nat8) -> () =\n Prim.stableMemoryStoreNat8;\n\n public let loadNat16 : (offset : Nat64) -> Nat16 =\n Prim.stableMemoryLoadNat16;\n public let storeNat16 : (offset : Nat64, value : Nat16) -> () =\n Prim.stableMemoryStoreNat16;\n\n public let loadNat64 : (offset : Nat64) -> Nat64 =\n Prim.stableMemoryLoadNat64;\n public let storeNat64 : (offset : Nat64, value : Nat64) -> () =\n Prim.stableMemoryStoreNat64;\n\n public let loadInt32 : (offset : Nat64) -> Int32 =\n Prim.stableMemoryLoadInt32;\n public let storeInt32 : (offset : Nat64, value : Int32) -> () =\n Prim.stableMemoryStoreInt32;\n\n public let loadInt8 : (offset : Nat64) -> Int8 =\n Prim.stableMemoryLoadInt8;\n public let storeInt8 : (offset : Nat64, value : Int8) -> () =\n Prim.stableMemoryStoreInt8;\n\n public let loadInt16 : (offset : Nat64) -> Int16 =\n Prim.stableMemoryLoadInt16;\n public let storeInt16 : (offset : Nat64, value : Int16) -> () =\n Prim.stableMemoryStoreInt16;\n\n public let loadInt64 : (offset : Nat64) -> Int64 =\n Prim.stableMemoryLoadInt64;\n public let storeInt64 : (offset : Nat64, value : Int64) -> () =\n Prim.stableMemoryStoreInt64;\n\n public let loadFloat : (offset : Nat64) -> Float =\n Prim.stableMemoryLoadFloat;\n public let storeFloat : (offset : Nat64, value : Float) -> () =\n Prim.stableMemoryStoreFloat;\n\n /// Load `size` bytes starting from `offset` as a `Blob`.\n /// Traps on out-of-bounds access.\n public let loadBlob : (offset : Nat64, size : Nat) -> Blob =\n Prim.stableMemoryLoadBlob;\n\n /// Write bytes of `blob` beginning at `offset`.\n /// Traps on out-of-bounds access.\n public let storeBlob : (offset : Nat64, value : Blob) -> () =\n Prim.stableMemoryStoreBlob;\n\n}\n"},"IterType.mo":{"content":"/// The Iterator type\n\n// Just here to break cyclic module definitions\n\nmodule {\n public type Iter<T> = { next : () -> ?T };\n}\n"},"TrieMap.mo":{"content":"/// Key-value hash maps.\n///\n/// An imperative hash map, with a general key and value type.\n///\n/// - The `class` `TrieMap` exposes the same interface as `HashMap`.\n///\n/// - Unlike HashMap, the internal representation uses a functional representation (via `Trie` module).\n///\n/// - This class does not permit a direct `clone` operation (neither does `HashMap`), but it does permit creating iterators via `iter()`. Each iterator costs `O(1)` to create, but represents a fixed view of the mapping that does not interfere with mutations (it will _not_ reflect subsequent insertions or mutations, if any).\n\nimport T \"Trie\";\nimport P \"Prelude\";\nimport I \"Iter\";\nimport Hash \"Hash\";\nimport List \"List\";\n\n/// An imperative hash-based map with a minimal object-oriented interface.\n/// Maps keys of type `K` to values of type `V`.\n///\n/// See also the `HashMap` module, with a matching interface.\n/// Unlike HashMap, the iterators are persistent (pure), clones are cheap and the maps have an efficient persistent representation.\n\nmodule {\n\n public class TrieMap<K, V> (isEq : (K, K) -> Bool, hashOf : K -> Hash.Hash) {\n\n var map = T.empty<K, V>();\n var _size : Nat = 0;\n\n /// Returns the number of entries in the map.\n public func size() : Nat { _size };\n\n /// Associate a key and value, overwriting any prior association for the key.\n public func put(k : K, v : V) =\n ignore replace(k, v);\n\n /// Put the key and value, _and_ return the (optional) prior value for the key.\n public func replace(k : K, v : V) : ?V {\n let keyObj = { key = k; hash = hashOf(k) };\n let (map2, ov) =\n T.put<K,V>(map, keyObj, isEq, v);\n map := map2;\n switch (ov) {\n case null { _size += 1 };\n case _ {}\n };\n ov\n };\n\n /// Get the (optional) value associated with the given key.\n public func get(k : K) : ?V {\n let keyObj = {key = k; hash = hashOf(k);};\n T.find<K, V>(map, keyObj, isEq)\n };\n\n /// Delete the (optional) value associated with the given key.\n public func delete(k : K) =\n ignore remove(k);\n\n /// Delete and return the (optional) value associated with the given key.\n public func remove(k : K) : ?V {\n let keyObj = { key = k; hash = hashOf(k) };\n let (t, ov) = T.remove<K, V>(map, keyObj, isEq);\n map := t;\n switch (ov) {\n case null {};\n case (?_) { _size -= 1 }\n };\n ov\n };\n\n /// An `Iter` over the keys.\n ///\n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n public func keys() : I.Iter<K>\n { I.map(entries(), func (kv : (K, V)) : K { kv.0 }) };\n\n /// An `Iter` over the values.\n ///\n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n public func vals() : I.Iter<V>\n { I.map(entries(), func (kv : (K, V)) : V { kv.1 }) };\n\n /// Returns an `Iter` over the entries.\n ///\n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n public func entries() : I.Iter<(K, V)> {\n object {\n var stack = ?(map, null) : List.List<T.Trie<K, V>>;\n public func next() : ?(K, V) {\n switch stack {\n case null { null };\n case (?(trie, stack2)) {\n switch trie {\n case (#empty) {\n stack := stack2;\n next()\n };\n case (#leaf({keyvals = null})) {\n stack := stack2;\n next()\n };\n case (#leaf({size = c; keyvals = ?((k, v), kvs)})) {\n stack := ?(#leaf({size=c-1; keyvals=kvs}), stack2);\n ?(k.key, v)\n };\n case (#branch(br)) {\n stack := ?(br.left, ?(br.right, stack2));\n next()\n };\n }\n }\n }\n }\n }\n }\n };\n\n\n /// Clone the map, given its key operations.\n public func clone<K, V>(\n h : TrieMap<K, V>,\n keyEq : (K,K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : TrieMap<K, V> {\n let h2 = TrieMap<K, V>(keyEq, keyHash);\n for ((k, v) in h.entries()) {\n h2.put(k, v);\n };\n h2\n };\n\n /// Clone an iterator of key-value pairs.\n public func fromEntries<K, V>(\n entries : I.Iter<(K, V)>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : TrieMap<K, V> {\n let h = TrieMap<K, V>(keyEq, keyHash);\n for ((k, v) in entries) {\n h.put(k, v);\n };\n h\n };\n\n /// Transform (map) the values of a map, retaining its keys.\n public func map<K, V1, V2> (\n h : TrieMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n mapFn : (K, V1) -> V2,\n ) : TrieMap<K, V2> {\n let h2 = TrieMap<K, V2>(keyEq, keyHash);\n for ((k, v1) in h.entries()) {\n let v2 = mapFn(k, v1);\n h2.put(k, v2);\n };\n h2\n };\n\n /// Transform and filter the values of a map, retaining its keys.\n public func mapFilter<K, V1, V2>(\n h : TrieMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n mapFn : (K, V1) -> ?V2,\n ) : TrieMap<K, V2> {\n let h2 = TrieMap<K, V2>(keyEq, keyHash);\n for ((k, v1) in h.entries()) {\n switch (mapFn(k, v1)) {\n case null { };\n case (?v2) {\n h2.put(k, v2);\n };\n }\n };\n h2\n };\n\n}\n"},"Prelude.mo":{"content":"/// General utilities\n///\n/// This prelude file proposes standard library features that _may_\n/// belong in the _language_ (compiler-internal) prelude sometime, after\n/// some further experience and discussion. Until then, they live here.\n\nimport Debug \"Debug\";\n\nmodule {\n\n /// Not yet implemented\n ///\n /// Mark incomplete code with the `nyi` and `xxx` functions.\n ///\n /// Each have calls are well-typed in all typing contexts, which\n /// trap in all execution contexts.\n public func nyi() : None {\n Debug.trap(\"Prelude.nyi()\");\n };\n\n public func xxx() : None {\n Debug.trap(\"Prelude.xxx()\");\n };\n\n /// Mark unreachable code with the `unreachable` function.\n ///\n /// Calls are well-typed in all typing contexts, and they\n /// trap in all execution contexts.\n public func unreachable() : None {\n Debug.trap(\"Prelude.unreachable()\")\n };\n\n}\n"},"Stack.mo":{"content":"/// Stack collection (LIFO discipline).\n///\n/// Minimal LIFO (last in first out) implementation, as a class.\n/// See library `Deque` for mixed LIFO/FIFO behavior.\n///\nimport List \"List\";\n\nmodule {\n\n public class Stack<T>() {\n\n var stack : List.List<T> = List.nil<T>();\n\n /// Push an element on the top of the stack.\n public func push(x:T) {\n stack := ?(x, stack)\n };\n\n /// True when the stack is empty.\n public func isEmpty() : Bool {\n List.isNil<T>(stack)\n };\n\n /// Return and retain the top element, or return null.\n public func peek() : ?T {\n switch stack {\n case null { null };\n case (?(h, t)) { ?h };\n }\n };\n\n /// Remove and return the top element, or return null.\n public func pop() : ?T {\n switch stack {\n case null { null };\n case (?(h, t)) { stack := t; ?h };\n }\n };\n };\n}\n"},"TrieSet.mo":{"content":"/// Functional set\n///\n/// Sets are partial maps from element type to unit type,\n/// i.e., the partial map represents the set with its domain.\n\n// TODO-Matthew:\n// ---------------\n//\n// - for now, we pass a hash value each time we pass an element value;\n// in the future, we might avoid passing element hashes with each element in the API;\n// related to: https://dfinity.atlassian.net/browse/AST-32\n//\n// - similarly, we pass an equality function when we do some operations.\n// in the future, we might avoid this via https://dfinity.atlassian.net/browse/AST-32\nimport Trie \"Trie\";\nimport Hash \"Hash\";\nimport List \"List\";\n\nmodule {\n\n public type Hash = Hash.Hash;\n public type Set<T> = Trie.Trie<T,()>;\n\n /// Empty set.\n public func empty<T>() : Set<T> { Trie.empty<T,()>(); };\n\n /// Put an element into the set.\n public func put<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n let (s2, _) = Trie.put<T,()>(s, { key = x; hash = xh }, eq, ());\n s2\n };\n\n /// Delete an element from the set.\n public func delete<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n let (s2, _) = Trie.remove<T, ()>(s, { key = x; hash = xh }, eq);\n s2\n };\n\n /// Test if two sets are equal.\n public func equal<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Bool {\n // XXX: Todo: use a smarter check\n func unitEqual (_ : (),_ : ()) : Bool { true };\n Trie.equalStructure<T, ()>(s1, s2, eq, unitEqual)\n };\n\n /// The number of set elements, set's cardinality.\n public func size<T>(s : Set<T>) : Nat {\n Trie.foldUp<T, (), Nat>(\n s,\n func(n : Nat, m : Nat) : Nat { n + m },\n func(_ : T, _ : ()) : Nat { 1 },\n 0\n )\n };\n\n /// Test if a set contains a given element.\n public func mem<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Bool {\n switch (Trie.find<T, ()>(s, { key = x; hash = xh }, eq)) {\n case null { false };\n case (?_) { true };\n }\n };\n\n /// [Set union](https://en.wikipedia.org/wiki/Union_(set_theory)).\n public func union<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let s3 = Trie.merge<T, ()>(s1, s2, eq);\n s3\n };\n\n /// [Set difference](https://en.wikipedia.org/wiki/Difference_(set_theory)).\n public func diff<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let s3 = Trie.diff<T, (), ()>(s1, s2, eq);\n s3\n };\n\n /// [Set intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)).\n public func intersect<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let noop : ((), ()) -> (()) = func (_ : (), _ : ()) : (()) = ();\n let s3 = Trie.join<T, (), (), ()>(s1, s2, eq, noop);\n s3\n };\n\n //// Construct a set from an array.\n public func fromArray<T>(arr : [T], elemHash : T -> Hash, eq : (T, T) -> Bool) : Set<T> {\n var s = empty<T>();\n for (elem in arr.vals()) {\n s := put<T>(s, elem, elemHash(elem), eq);\n };\n s\n };\n\n //// Returns the set as an array.\n public func toArray<T>(s : Set<T>): [T] {\n Trie.toArray(s, func (t : T, _ : ()) : T { t })\n }\n\n}\n"},"Time.mo":{"content":"/// System time\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// System time is represent as nanoseconds since 1970-01-01.\n public type Time = Int;\n\n /// Current system time given as nanoseconds since 1970-01-01. The system guarantees that:\n ///\n /// * the time, as observed by the canister smart contract, is monotonically increasing, even across canister upgrades.\n /// * within an invocation of one entry point, the time is constant.\n ///\n /// The system times of different canisters are unrelated, and calls from one canister to another may appear to travel \"backwards in time\"\n ///\n /// Note: While an implementation will likely try to keep the system time close to the real time, this is not formally guaranteed.\n public let now : () -> Time =\n func () : Int = Prim.nat64ToNat(Prim.time());\n ///\n /// The following example illustrates using the system time:\n ///\n /// ```motoko\n /// import Int = \"mo:base/Int\";\n /// import Time = \"mo:base/Time\";\n ///\n /// actor {\n /// var lastTime = Time.now();\n /// public func greet(name : Text) : async Text {\n /// let now = Time.now();\n /// let elapsedSeconds = (now - lastTime) / 1000_000_000;\n /// lastTime := now;\n /// return \"Hello, \" # name # \"!\" #\n /// \" I was last called \" # Int.toText(elapsedSeconds) # \" seconds ago\";\n /// };\n /// };\n /// ```\n}\n"},"Order.mo":{"content":"/// Order\n\nmodule {\n\n /// A type to represent an order.\n public type Order = {\n #less;\n #equal;\n #greater;\n };\n\n /// Check if an order is #less.\n public func isLess(order : Order) : Bool {\n switch order {\n case (#less) { true };\n case _ { false };\n };\n };\n\n /// Check if an order is #equal.\n public func isEqual(order : Order) : Bool {\n switch order {\n case (#equal) { true };\n case _ { false };\n };\n };\n\n /// Check if an order is #greater.\n public func isGreater(order : Order) : Bool {\n switch order {\n case (#greater) { true };\n case _ { false };\n };\n };\n\n /// Returns true if only if `o1` and `o2` are the same ordering.\n public func equal(o1 : Order, o2: Order) : Bool {\n switch (o1, o2) {\n case (#less, #less) { true };\n case (#equal, #equal) { true };\n case (#greater, #greater) { true };\n case _ { false };\n };\n };\n\n};\n"},"None.mo":{"content":"/// The absent value\n///\n/// The `None` type represents a type with _no_ value.\n///\n/// It is often used to type code that fails to return control (e.g. an infinite loop)\n/// or to designate impossible values (e.g. the type `?None` only contains `null`).\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// The empty type. A subtype of all types.\n public type None = Prim.Types.None;\n\n /// Turns an absurd value into an arbitrary type.\n public let impossible : <A> None -> A = func<A>(x : None) : A {\n switch (x) {};\n };\n}\n"},"Principal.mo":{"content":"/// IC principals (user and canister smart contract IDs)\n\nimport Prim \"mo:⛔\";\nimport Blob \"Blob\";\nimport Hash \"Hash\";\nmodule {\n\n /// Internet Computer principal identifiers.\n /// Convert to `Blob` for access to bytes.\n public type Principal = Prim.Types.Principal;\n\n /// Conversion.\n public let fromActor : (a : actor {}) -> Principal = Prim.principalOfActor;\n\n /// Conversion.\n public let toBlob : (p : Principal) -> Blob = Prim.blobOfPrincipal;\n\n /// Conversion.\n public let fromBlob : (b : Blob) -> Principal = Prim.principalOfBlob;\n \n /// Conversion.\n public func toText(p : Principal) : Text = debug_show(p);\n\n private let anonymousPrincipal : Blob = \"\\04\";\n\n public func isAnonymous(p : Principal) : Bool =\n Prim.blobOfPrincipal p == anonymousPrincipal;\n\n public func hash(principal : Principal) : Hash.Hash =\n Blob.hash (Prim.blobOfPrincipal(principal));\n\n public func fromText(t : Text) : Principal = fromActor(actor(t));\n\n /// Returns `x == y`.\n public func equal(x : Principal, y : Principal) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Principal, y : Principal) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Principal, y : Principal) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Principal, y : Principal) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Principal, y : Principal) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Principal, y : Principal) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Principal, y : Principal) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n}\n"},"RBTree.mo":{"content":"/// Red-Black Trees\n\nimport Debug \"Debug\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\nmodule {\n\n /// Node color: red or black.\n public type Color = { #R; #B };\n\n /// Ordered, (red-black) tree of entries.\n public type Tree<X, Y> = {\n #node : (Color, Tree<X, Y>, (X, ?Y), Tree<X, Y>);\n #leaf;\n };\n\n /// Create an order map from an order function for its keys.\n public class RBTree<X, Y>(compareTo : (X, X) -> O.Order) {\n\n var tree : Tree<X, Y> = (#leaf : Tree<X, Y>);\n\n /// Tree as sharable data.\n ///\n /// Get non-OO, purely-functional representation:\n /// for drawing, pretty-printing and non-OO contexts\n /// (e.g., async args and results):\n public func share() : Tree<X, Y> {\n tree\n };\n\n /// Get the value associated with a given key.\n public func get(x : X) : ?Y {\n getRec(x, compareTo, tree);\n };\n\n /// Replace the value associated with a given key.\n public func replace(x : X, y : Y) : ?Y {\n let (res, t) = insertRoot(x, compareTo, y, tree);\n tree := t;\n res\n };\n\n /// Put an entry: A value associated with a given key.\n public func put(x : X, y : Y) {\n let (res, t) = insertRoot(x, compareTo, y, tree);\n tree := t;\n };\n\n /// Delete the entry associated with a given key.\n public func delete(x : X) {\n let (res, t) = removeRec(x, compareTo, tree);\n tree := t\n };\n\n /// Remove the entry associated with a given key.\n public func remove(x : X) : ?Y {\n let (res, t) = removeRec(x, compareTo, tree);\n tree := t;\n res\n };\n\n /// An iterator for the key-value entries of the map, in ascending key order.\n ///\n /// iterator is persistent, like the tree itself\n public func entries() : I.Iter<(X, Y)> { iter(tree, #fwd) };\n\n /// An iterator for the key-value entries of the map, in descending key order.\n ///\n /// iterator is persistent, like the tree itself\n public func entriesRev() : I.Iter<(X, Y)> { iter(tree, #bwd) };\n\n };\n\n\n type IterRep<X, Y> = List.List<{ #tr:Tree<X, Y>; #xy:(X, ?Y) }>;\n\n /// An iterator for the entries of the map, in ascending (`#fwd`) or descending (`#bwd`) order.\n public func iter<X, Y>(t : Tree<X, Y>, dir : { #fwd; #bwd }) : I.Iter<(X, Y)> {\n object {\n var trees : IterRep<X, Y> = ?(#tr(t), null);\n public func next() : ?(X, Y) {\n switch (dir, trees) {\n case (_, null) { null };\n case (_, ?(#tr(#leaf), ts)){\n trees := ts;\n next()\n };\n case (_, ?(#xy(xy), ts)) {\n trees := ts;\n switch (xy.1) {\n case null { next() };\n case (?y) { ?(xy.0, y) }\n }\n };\n case (#fwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n trees := ?(#tr(l), ?(#xy(xy), ?(#tr(r), ts)));\n next()\n };\n case (#bwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n trees := ?(#tr(r), ?(#xy(xy), ?(#tr(l), ts)));\n next()\n };\n }\n };\n }\n };\n\n /// Remove the value associated with a given key.\n func removeRec<X, Y>(x : X, compareTo : (X, X) -> O.Order, t : Tree<X, Y>)\n : (?Y, Tree<X, Y>) {\n switch t {\n case (#leaf) { (null, #leaf) };\n case (#node(c, l, xy, r)) {\n switch (compareTo(x, xy.0)) {\n case (#less) {\n let (yo, l2) = removeRec(x, compareTo, l);\n (yo, #node(c, l2, xy, r))\n };\n case (#equal) {\n (xy.1, #node(c, l, (x, null), r))\n };\n case (#greater) {\n let (yo, r2) = removeRec(x, compareTo, r);\n (yo, #node(c, l, xy, r2))\n };\n }\n }\n }\n };\n\n\n\n func bal<X, Y>(color : Color, lt : Tree<X, Y>, kv : (X, ?Y), rt : Tree<X, Y>) : Tree<X, Y> {\n // thank you, algebraic pattern matching!\n // following notes from [Ravi Chugh](https://www.classes.cs.uchicago.edu/archive/2019/spring/22300-1/lectures/RedBlackTrees/index.html)\n switch (color, lt, kv, rt) {\n case (#B, #node(#R, #node(#R, a, x, b), y, c), z, d) {\n #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n };\n case (#B, #node(#R, a, x, #node(#R, b, y, c)), z, d) {\n #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n };\n case (#B, a, x, #node(#R, #node(#R, b, y, c), z, d)) {\n #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n };\n case (#B, a, x, #node(#R, b, y, #node(#R, c, z, d))) {\n #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n };\n case _ { #node(color, lt, kv, rt) };\n }\n };\n\n func insertRoot<X, Y>(x : X, compareTo : (X, X) -> O.Order, y : Y, t : Tree<X, Y>)\n : (?Y, Tree<X, Y>) {\n switch (insertRec(x, compareTo, y, t)) {\n case (_, #leaf) { assert false; loop { } };\n case (yo, #node(_, l, xy, r)) { (yo, #node(#B, l, xy, r)) };\n }\n };\n\n func insertRec<X, Y>(x : X, compareTo : (X, X) -> O.Order, y : Y, t : Tree<X, Y>)\n : (?Y, Tree<X, Y>) {\n switch t {\n case (#leaf) { (null, #node(#R, #leaf, (x, ?y), #leaf)) };\n case (#node(c, l, xy, r)) {\n switch (compareTo(x, xy.0)) {\n case (#less) {\n let (yo, l2) = insertRec(x, compareTo, y, l);\n (yo, bal(c, l2, xy, r))\n };\n case (#equal) {\n (xy.1, #node(c, l, (x, ?y), r))\n };\n case (#greater) {\n let (yo, r2) = insertRec(x, compareTo, y, r);\n (yo, bal(c, l, xy, r2))\n };\n }\n }\n }\n };\n\n func getRec<X, Y>(x : X, compareTo : (X, X) -> O.Order, t : Tree<X, Y>) : ?Y {\n switch t {\n case (#leaf) { null };\n case (#node(c, l, xy, r)) {\n switch (compareTo(x, xy.0)) {\n case (#less) { getRec(x, compareTo, l) };\n case (#equal) { xy.1 };\n case (#greater) { getRec(x, compareTo, r) };\n }\n };\n }\n };\n\n func height<X, Y>(t : Tree<X, Y>) : Nat {\n switch t {\n case (#leaf) { 0 };\n case (#node(_, l, _, r)) {\n Nat.max(height(l), height(r)) + 1\n }\n }\n };\n\n /// The size of the tree as the number of key-value entries.\n public func size<X, Y>(t : Tree<X, Y>) : Nat {\n switch t {\n case (#leaf) { 0 };\n case (#node(_, l, xy, r)) {\n size(l) + size(r) + (switch (xy.1) { case null 0; case _ 1 });\n };\n }\n };\n\n}\n"},"Result.mo":{"content":"/// Error handling with the Result type.\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport Order \"Order\";\n\nmodule {\n\n /// `Result<Ok, Err>` is the type used for returning and propagating errors. It\n /// is a type with the variants, `#ok(Ok)`, representing success and containing\n /// a value, and `#err(Err)`, representing error and containing an error value.\n ///\n /// The simplest way of working with `Result`s is to pattern match on them:\n ///\n /// For example, given a function `createUser(user : User) : Result<Id, String>`\n /// where `String` is an error message we could use it like so:\n /// ```motoko no-repl\n /// switch(createUser(myUser)) {\n /// case (#ok(id)) { Debug.print(\"Created new user with id: \" # id) };\n /// case (#err(msg)) { Debug.print(\"Failed to create user with the error: \" # msg) };\n /// }\n /// ```\n public type Result<Ok, Err> = {\n #ok : Ok;\n #err : Err;\n };\n\n // Compares two Result's for equality.\n public func equal<Ok, Err>(\n eqOk : (Ok, Ok) -> Bool,\n eqErr : (Err, Err) -> Bool,\n r1 : Result<Ok, Err>,\n r2 : Result<Ok, Err>\n ) : Bool {\n switch (r1, r2) {\n case (#ok(ok1), #ok(ok2)) {\n eqOk(ok1, ok2)\n };\n case (#err(err1), #err(err2)) {\n eqErr(err1, err2);\n };\n case _ { false };\n };\n };\n\n // Compares two Results. `#ok` is larger than `#err`. This ordering is\n // arbitrary, but it lets you for example use Results as keys in ordered maps.\n public func compare<Ok, Err>(\n compareOk : (Ok, Ok) -> Order.Order,\n compareErr : (Err, Err) -> Order.Order,\n r1 : Result<Ok, Err>,\n r2 : Result<Ok, Err>\n ) : Order.Order {\n switch (r1, r2) {\n case (#ok(ok1), #ok(ok2)) {\n compareOk(ok1, ok2)\n };\n case (#err(err1), #err(err2)) {\n compareErr(err1, err2)\n };\n case (#ok(_), _) { #greater };\n case (#err(_), _) { #less };\n };\n };\n\n /// Allows sequencing of `Result` values and functions that return\n /// `Result`'s themselves.\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// type Result<T,E> = Result.Result<T, E>;\n /// func largerThan10(x : Nat) : Result<Nat, Text> =\n /// if (x > 10) { #ok(x) } else { #err(\"Not larger than 10.\") };\n ///\n /// func smallerThan20(x : Nat) : Result<Nat, Text> =\n /// if (x < 20) { #ok(x) } else { #err(\"Not smaller than 20.\") };\n ///\n /// func between10And20(x : Nat) : Result<Nat, Text> =\n /// Result.chain(largerThan10(x), smallerThan20);\n ///\n /// assert(between10And20(15) == #ok(15));\n /// assert(between10And20(9) == #err(\"Not larger than 10.\"));\n /// assert(between10And20(21) == #err(\"Not smaller than 20.\"));\n /// ```\n public func chain<R1, R2, Error>(\n x : Result<R1, Error>,\n y : R1 -> Result<R2, Error>\n ) : Result<R2, Error> {\n switch x {\n case (#err(e)) { #err(e) };\n case (#ok(r)) { y(r) };\n }\n };\n\n /// Flattens a nested Result.\n ///\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// assert(Result.flatten<Nat, Text>(#ok(#ok(10))) == #ok(10));\n /// assert(Result.flatten<Nat, Text>(#err(\"Wrong\")) == #err(\"Wrong\"));\n /// assert(Result.flatten<Nat, Text>(#ok(#err(\"Wrong\"))) == #err(\"Wrong\"));\n /// ```\n public func flatten<Ok, Error>(\n result : Result<Result<Ok, Error>, Error>\n ) : Result<Ok, Error> {\n switch result {\n case (#ok(ok)) { ok };\n case (#err(err)) { #err(err) };\n }\n };\n\n\n /// Maps the `Ok` type/value, leaving any `Error` type/value unchanged.\n public func mapOk<Ok1, Ok2, Error>(\n x : Result<Ok1, Error>,\n f : Ok1 -> Ok2\n ) : Result<Ok2, Error> {\n switch x {\n case (#err(e)) { #err(e) };\n case (#ok(r)) { #ok(f(r)) };\n }\n };\n\n /// Maps the `Err` type/value, leaving any `Ok` type/value unchanged.\n public func mapErr<Ok, Error1, Error2>(\n x : Result<Ok, Error1>,\n f : Error1 -> Error2\n ) : Result<Ok, Error2> {\n switch x {\n case (#err(e)) { #err (f(e)) };\n case (#ok(r)) { #ok(r) };\n }\n };\n\n /// Create a result from an option, including an error value to handle the `null` case.\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// assert(Result.fromOption(?42, \"err\") == #ok(42));\n /// assert(Result.fromOption(null, \"err\") == #err(\"err\"));\n /// ```\n public func fromOption<R, E>(x : ?R, err : E) : Result<R, E> {\n switch x {\n case (?x) { #ok(x) };\n case null { #err(err) };\n }\n };\n\n /// Create an option from a result, turning all #err into `null`.\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// assert(Result.toOption(#ok(42)) == ?42);\n /// assert(Result.toOption(#err(\"err\")) == null);\n /// ```\n public func toOption<R, E>(r : Result<R, E>) : ?R {\n switch r {\n case (#ok(x)) { ?x };\n case (#err(_)) { null };\n }\n };\n\n /// Applies a function to a successful value, but discards the result. Use\n /// `iterate` if you're only interested in the side effect `f` produces.\n ///\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// var counter : Nat = 0;\n /// Result.iterate<Nat, Text>(#ok(5), func (x : Nat) { counter += x });\n /// assert(counter == 5);\n /// Result.iterate<Nat, Text>(#err(\"Wrong\"), func (x : Nat) { counter += x });\n /// assert(counter == 5);\n /// ```\n public func iterate<Ok, Err>(res : Result<Ok, Err>, f : Ok -> ()) {\n switch res {\n case (#ok(ok)) { f(ok) };\n case _ {};\n }\n };\n\n // Whether this Result is an `#ok`\n public func isOk(r : Result<Any, Any>) : Bool {\n switch r {\n case (#ok(_)) { true };\n case (#err(_)) { false };\n }\n };\n\n // Whether this Result is an `#err`\n public func isErr(r : Result<Any, Any>) : Bool {\n switch r {\n case (#ok(_)) { false };\n case (#err(_)) { true };\n }\n };\n\n /// Asserts that its argument is an `#ok` result, traps otherwise.\n public func assertOk(r : Result<Any,Any>) {\n switch(r) {\n case (#err(_)) { assert false };\n case (#ok(_)) {};\n }\n };\n\n /// Asserts that its argument is an `#err` result, traps otherwise.\n public func assertErr(r : Result<Any,Any>) {\n switch(r) {\n case (#err(_)) {};\n case (#ok(_)) assert false;\n }\n };\n\n}\n"},"Text.mo":{"content":"/// Text values\n///\n/// This type represents human-readable text as sequences of characters of type `Char`.\n/// If `t` is a value of type `Text`, then:\n///\n/// * `t.chars()` returns an _iterator_ of type `Iter<Char>` enumerating its characters from first to last.\n/// * `t.size()` returns the _size_ (or length) of `t` (and `t.chars()`) as a `Nat`.\n/// * `t1 # t2` concatenates texts `t1` and `t2`.\n///\n/// Represented as ropes of UTF-8 character sequences with O(1) concatenation.\n///\n/// This module defines additional operations on `Text` values.\n\nimport Char \"Char\";\nimport Iter \"Iter\";\nimport Hash \"Hash\";\nimport Stack \"Stack\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Text values.\n public type Text = Prim.Types.Text;\n\n /// Conversion.\n /// Returns the text value of size 1 containing the single character `c`.\n public let fromChar : (c : Char) -> Text = Prim.charToText;\n\n /// Conversion.\n /// Creates an iterator that traverses the characters of the text `t`.\n public func toIter(t : Text) : Iter.Iter<Char> =\n t.chars();\n\n /// Conversion.\n /// Returns the text value containing the sequence of characters in `cs`.\n public func fromIter(cs : Iter.Iter<Char>) : Text {\n var r = \"\";\n for (c in cs) {\n r #= Prim.charToText(c);\n };\n return r;\n };\n\n /// Returns `t.size()`, the number of characters in `t` (and `t.chars()`).\n public func size(t : Text) : Nat { t.size(); };\n\n /// Returns a hash obtained by using the `djb2` algorithm from http://www.cse.yorku.ca/~oz/hash.html\n ///\n /// This function is _good enough_ for use in a hash-table but it's not a cryptographic hash function!\n public func hash(t : Text) : Hash.Hash {\n var x : Nat32 = 5381;\n for (char in t.chars()) {\n let c : Nat32 = Prim.charToNat32(char);\n x := ((x << 5) +% x) +% c;\n };\n return x\n };\n\n /// Returns the concatenation of `t1` and `t2`, `t1 # t2`.\n public func concat(t1 : Text, t2 : Text) : Text =\n t1 # t2;\n\n /// Returns `t1 == t2`.\n public func equal(t1 : Text, t2 : Text) : Bool { t1 == t2 };\n\n /// Returns `t1 != t2`.\n public func notEqual(t1 : Text, t2 : Text) : Bool { t1 != t2 };\n\n /// Returns `t1 < t2`.\n public func less(t1 : Text, t2 : Text) : Bool { t1 < t2 };\n\n /// Returns `t1 <= t2`.\n public func lessOrEqual(t1 : Text, t2 : Text) : Bool { t1 <= t2 };\n\n /// Returns `t1 > t2`.\n public func greater(t1 : Text, t2 : Text) : Bool { t1 > t2 };\n\n /// Returns `t1 >= t2`.\n public func greaterOrEqual(t1 : Text, t2 : Text) : Bool { t1 >= t2 };\n\n /// Returns the order of `t1` and `t2`.\n public func compare(t1 : Text, t2 : Text) : { #less; #equal; #greater } {\n let c = Prim.textCompare(t1, t2);\n if (c < 0) #less else if (c == 0) #equal else #greater\n };\n\n\n private func extract(t : Text, i : Nat, j : Nat) : Text {\n let size = t.size();\n if (i == 0 and j == size) return t;\n assert (j <= size);\n let cs = t.chars();\n var r = \"\";\n var n = i;\n while (n > 0) {\n ignore cs.next();\n n -= 1;\n };\n n := j;\n while (n > 0) {\n switch (cs.next()) {\n case null { assert false };\n case (?c) { r #= Prim.charToText(c) }\n };\n n -= 1;\n };\n return r;\n };\n\n /// Returns the concatenation of text values in `ts`, separated by `sep`.\n public func join(sep : Text, ts : Iter.Iter<Text>) : Text {\n var r = \"\";\n if (sep.size() == 0) {\n for (t in ts) {\n r #= t\n };\n return r;\n };\n let next = ts.next;\n switch (next()) {\n case null { return r; };\n case (?t) {\n r #= t;\n }\n };\n loop {\n switch (next()) {\n case null { return r; };\n case (?t) {\n r #= sep;\n r #= t;\n }\n }\n }\n };\n\n\n /// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate single-character text values.\n public func map(t : Text, f : Char -> Char) : Text {\n var r = \"\";\n for (c in t.chars()) {\n r #= Prim.charToText(f(c));\n };\n return r;\n };\n\n /// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate text values.\n public func translate(t : Text, f : Char -> Text) : Text {\n var r = \"\";\n for (c in t.chars()) {\n r #= f(c);\n };\n return r;\n };\n\n\n /// A pattern `p` describes a sequence of characters. A pattern has one of the following forms:\n ///\n /// * `#char c` matches the single character sequence, `c`.\n /// * `#predicate p` matches any single character sequence `c` satisfying predicate `p(c)`.\n /// * `#text t` matches multi-character text sequence `t`.\n ///\n /// A _match_ for `p` is any sequence of characters matching the pattern `p`.\n public type Pattern = { #char : Char; #text : Text; #predicate : (Char -> Bool) };\n\n private func take(n : Nat, cs : Iter.Iter<Char>) : Iter.Iter<Char> {\n var i = n;\n object {\n public func next() : ?Char {\n if (i == 0) return null;\n i -= 1;\n return cs.next();\n }\n }\n };\n\n private func empty() : Iter.Iter<Char> {\n object {\n public func next() : ?Char = null;\n };\n };\n\n private type Match = {\n /// #success on complete match\n #success;\n /// #fail(cs,c) on partial match of cs, but failing match on c\n #fail : (cs : Iter.Iter<Char>, c : Char);\n /// #empty(cs) on partial match of cs and empty stream\n #empty : (cs : Iter.Iter<Char> )\n };\n\n private func sizeOfPattern(pat : Pattern) : Nat {\n switch pat {\n case (#text(t)) { t.size() };\n case (#predicate(_) or #char(_)) { 1 };\n }\n };\n\n private func matchOfPattern(pat : Pattern) : (cs : Iter.Iter<Char>) -> Match {\n switch pat {\n case (#char(p)) {\n func (cs : Iter.Iter<Char>) : Match {\n switch (cs.next()) {\n case (?c) {\n if (p == c) {\n #success\n } else {\n #fail(empty(), c) }\n };\n case null { #empty(empty()) };\n }\n }\n };\n case (#predicate(p)) {\n func (cs : Iter.Iter<Char>) : Match {\n switch (cs.next()) {\n case (?c) {\n if (p(c)) {\n #success\n } else {\n #fail(empty(), c) }\n };\n case null { #empty(empty()) };\n }\n }\n };\n case (#text(p)) {\n func (cs : Iter.Iter<Char>) : Match {\n var i = 0;\n let ds = p.chars();\n loop {\n switch (ds.next()) {\n case (?d) {\n switch (cs.next()) {\n case (?c) {\n if (c != d) {\n return #fail(take(i, p.chars()), c)\n };\n i += 1;\n };\n case null {\n return #empty(take(i, p.chars()));\n }\n }\n };\n case null { return #success };\n }\n }\n }\n }\n }\n };\n\n private class CharBuffer(cs : Iter.Iter<Char>) : Iter.Iter<Char> = {\n\n var stack : Stack.Stack<(Iter.Iter<Char>, Char)> = Stack.Stack();\n\n public func pushBack(cs0: Iter.Iter<Char>, c : Char) {\n stack.push((cs0, c));\n };\n\n public func next() : ?Char {\n switch (stack.peek()) {\n case (?(buff, c)) {\n switch (buff.next()) {\n case null {\n ignore stack.pop();\n return ?c;\n };\n case oc {\n return oc;\n };\n }\n };\n case null {\n return cs.next();\n };\n };\n };\n };\n\n /// Returns the sequence of fields in `t`, derived from start to end,\n /// separated by text matching pattern `p`.\n /// Two fields are separated by exactly one match.\n public func split(t : Text, p : Pattern) : Iter.Iter<Text> {\n let match = matchOfPattern(p);\n let cs = CharBuffer(t.chars());\n var state = 0;\n var field = \"\";\n object {\n public func next() : ?Text {\n switch state {\n case (0 or 1) {\n loop {\n switch (match(cs)) {\n case (#success) {\n let r = field;\n field := \"\";\n state := 1;\n return ?r\n };\n case (#empty(cs1)) {\n for (c in cs1) {\n field #= fromChar(c);\n };\n let r =\n if (state == 0 and field == \"\") {\n null\n } else {\n ?field\n };\n state := 2;\n return r;\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1,c);\n switch (cs.next()) {\n case (?ci) {\n field #= fromChar(ci);\n };\n case null {\n let r =\n if (state == 0 and field == \"\") {\n null\n } else {\n ?field\n };\n state := 2;\n return r;\n }\n }\n }\n }\n }\n };\n case _ { return null };\n }\n }\n }\n };\n\n /// Returns the sequence of tokens in `t`, derived from start to end.\n /// A _token_ is a non-empty maximal subsequence of `t` not containing a match for pattern `p`.\n /// Two tokens may be separated by one or more matches of `p`.\n public func tokens(t : Text, p : Pattern) : Iter.Iter<Text> {\n let fs = split(t, p);\n object {\n public func next() : ?Text {\n switch (fs.next()) {\n case (?\"\") { next() };\n case ot { ot };\n }\n }\n }\n };\n\n /// Returns true if `t` contains a match for pattern `p`.\n public func contains(t : Text, p : Pattern) : Bool {\n let match = matchOfPattern(p);\n let cs = CharBuffer(t.chars());\n loop {\n switch (match(cs)) {\n case (#success) {\n return true\n };\n case (#empty(cs1)) {\n return false;\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c);\n switch (cs.next()) {\n case null {\n return false\n };\n case _ { }; // continue\n }\n }\n }\n }\n };\n\n /// Returns `true` if `t` starts with a prefix matching pattern `p`, otherwise returns `false`.\n public func startsWith(t : Text, p : Pattern) : Bool {\n var cs = t.chars();\n let match = matchOfPattern(p);\n switch (match(cs)) {\n case (#success) { true };\n case _ { false };\n }\n };\n\n /// Returns `true` if `t` ends with a suffix matching pattern `p`, otherwise returns `false`.\n public func endsWith(t : Text, p : Pattern) : Bool {\n let s2 = sizeOfPattern(p);\n if (s2 == 0) return true;\n let s1 = t.size();\n if (s2 > s1) return false;\n let match = matchOfPattern(p);\n var cs1 = t.chars();\n var diff : Nat = s1 - s2;\n while (diff > 0) {\n ignore cs1.next();\n diff -= 1;\n };\n switch (match(cs1)) {\n case (#success) { true };\n case _ { false };\n }\n };\n\n /// Returns `t` with all matches of pattern `p` replaced by text `r`.\n public func replace(t : Text, p : Pattern, r : Text) : Text {\n let match = matchOfPattern(p);\n let size = sizeOfPattern(p);\n let cs = CharBuffer(t.chars());\n var res = \"\";\n label l\n loop {\n switch (match(cs)) {\n case (#success) {\n res #= r;\n if (size > 0) {\n continue l;\n }\n };\n case (#empty(cs1)) {\n for (c1 in cs1) {\n res #= fromChar(c1);\n };\n break l;\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c);\n }\n };\n switch (cs.next()) {\n case null {\n break l;\n };\n case (?c1) {\n res #= fromChar(c1);\n }; // continue\n }\n };\n return res;\n };\n\n\n\n /// Returns the optioned suffix of `t` obtained by eliding exactly one leading match of pattern `p`, otherwise `null`.\n public func stripStart(t : Text, p : Pattern) : ?Text {\n let s = sizeOfPattern(p);\n if (s == 0) return ?t;\n var cs = t.chars();\n let match = matchOfPattern(p);\n switch (match(cs)) {\n case (#success) return ?fromIter(cs);\n case _ return null;\n }\n };\n\n /// Returns the optioned prefix of `t` obtained by eliding exactly one trailing match of pattern `p`, otherwise `null`.\n public func stripEnd(t : Text, p : Pattern) : ?Text {\n let s2 = sizeOfPattern(p);\n if (s2 == 0) return ?t;\n let s1 = t.size();\n if (s2 > s1) return null;\n let match = matchOfPattern(p);\n var cs1 = t.chars();\n var diff : Nat = s1 - s2;\n while (diff > 0) {\n ignore cs1.next();\n diff -= 1;\n };\n switch (match(cs1)) {\n case (#success) return ?extract(t, 0, s1 - s2);\n case _ return null;\n }\n };\n\n /// Returns the suffix of `t` obtained by eliding all leading matches of pattern `p`.\n public func trimStart(t : Text, p : Pattern) : Text {\n let cs = t.chars();\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n var matchSize = 0;\n let match = matchOfPattern(p);\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size;\n }; // continue\n case (#empty(cs1)) {\n return if (matchSize == 0) {\n t\n } else {\n fromIter(cs1)\n }\n };\n case (#fail(cs1, c)) {\n return if (matchSize == 0) {\n t\n } else {\n fromIter(cs1) # fromChar(c) # fromIter(cs)\n }\n }\n }\n }\n };\n\n /// Returns the prefix of `t` obtained by eliding all trailing matches of pattern `p`.\n public func trimEnd(t : Text, p : Pattern) : Text {\n let cs = CharBuffer(t.chars());\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n let match = matchOfPattern(p);\n var matchSize = 0;\n label l\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size;\n }; // continue\n case (#empty(cs1)) {\n switch (cs1.next()) {\n case null break l;\n case (?_) return t;\n }\n };\n case (#fail(cs1, c)) {\n matchSize := 0;\n cs.pushBack(cs1, c);\n ignore cs.next();\n }\n }\n };\n extract(t, 0, t.size() - matchSize)\n };\n\n /// Returns the subtext of `t` obtained by eliding all leading and trailing matches of pattern `p`.\n public func trim(t : Text, p : Pattern) : Text {\n let cs = t.chars();\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n var matchSize = 0;\n let match = matchOfPattern(p);\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size;\n }; // continue\n case (#empty(cs1)) {\n return if (matchSize == 0) { t } else { fromIter(cs1) }\n };\n case (#fail(cs1, c)) {\n let start = matchSize;\n let cs2 = CharBuffer(cs);\n cs2.pushBack(cs1, c);\n ignore cs2.next();\n matchSize := 0;\n label l\n loop {\n switch (match(cs2)) {\n case (#success) {\n matchSize += size;\n }; // continue\n case (#empty(cs3)) {\n switch (cs1.next()) {\n case null break l;\n case (?_) return t;\n }\n };\n case (#fail(cs3, c1)) {\n matchSize := 0;\n cs2.pushBack(cs3, c1);\n ignore cs2.next();\n }\n }\n };\n return extract(t, start, t.size() - matchSize - start);\n }\n }\n }\n };\n\n /// Returns the lexicographic comparison of `t1` and `t2`, using the given character ordering `cmp`.\n public func compareWith(\n t1 : Text,\n t2 : Text,\n cmp : (Char, Char)-> { #less; #equal; #greater })\n : { #less; #equal; #greater } {\n let cs1 = t1.chars();\n let cs2 = t2.chars();\n loop {\n switch (cs1.next(), cs2.next()) {\n case (null, null) { return #equal };\n case (null, ?_) { return #less };\n case (?_, null) { return #greater };\n case (?c1, ?c2) {\n switch (cmp(c1, c2)) {\n case (#equal) { }; // continue\n case other { return other; }\n }\n }\n }\n }\n };\n\n /// Returns the UTF-8 encoding of the given text\n public let encodeUtf8 : Text -> Blob = Prim.encodeUtf8;\n\n /// Tries to decode the given `Blob` as UTF-8.\n /// Returns `null` if the blob is _not_ valid UTF-8.\n public let decodeUtf8 : Blob -> ?Text = Prim.decodeUtf8;\n}\n"},"Random.mo":{"content":"/// A module for obtaining randomness on the Internet Computer (IC).\n///\n/// This module provides the fundamentals for user abstractions to build on.\n///\n/// Dealing with randomness on a deterministic computing platform, such\n/// as the IC, is intricate. Some basic rules need to be followed by the\n/// user of this module to obtain (and maintain) the benefits of crypto-\n/// graphic randomness:\n///\n/// - cryptographic entropy (randomness source) is only obtainable\n/// asyncronously in discrete chunks of 256 bits (32-byte sized `Blob`s)\n/// - all bets must be closed *before* entropy is being asked for in\n/// order to decide them\n/// - this implies that the same entropy (i.e. `Blob`) - or surplus entropy\n/// not utilised yet - cannot be used for a new round of bets without\n/// losing the cryptographic guarantees.\n///\n/// Concretely, the below class `Finite`, as well as the\n/// `*From` methods risk the carrying-over of state from previous rounds.\n/// These are provided for performance (and convenience) reasons, and need\n/// special care when used. Similar caveats apply for user-defined (pseudo)\n/// random number generators.\n\nimport I \"Iter\";\nimport Option \"Option\";\nimport P \"Prelude\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Drawing from a finite supply of entropy, `Finite` provides\n /// methods to obtain random values. When the entropy is used up,\n /// `null` is returned. Otherwise the outcomes' distributions are\n /// stated for each method. The uniformity of outcomes is\n /// guaranteed only when the supplied entropy is originally obtained\n /// by the `blob()` call, and is never reused.\n public class Finite(entropy : Blob) {\n let it : I.Iter<Nat8> = entropy.vals();\n\n /// Uniformly distributes outcomes in the numeric range [0 .. 255].\n /// Consumes 1 byte of entropy.\n public func byte() : ?Nat8 {\n it.next()\n };\n\n /// Bool iterator splitting up a byte of entropy into 8 bits\n let bit : I.Iter<Bool> = object {\n var mask = 0x80 : Nat8;\n var byte = 0x00 : Nat8;\n public func next() : ?Bool {\n if (0 : Nat8 == mask) {\n switch (it.next()) {\n case null { null };\n case (?w) {\n byte := w;\n mask := 0x40;\n ?(0 : Nat8 != byte & (0x80 : Nat8))\n }\n }\n } else {\n let m = mask;\n mask >>= (1 : Nat8);\n ?(0 : Nat8 != byte & m)\n }\n }\n };\n\n /// Simulates a coin toss. Both outcomes have equal probability.\n /// Consumes 1 bit of entropy (amortised).\n public func coin() : ?Bool {\n bit.next()\n };\n\n /// Uniformly distributes outcomes in the numeric range [0 .. 2^p - 1].\n /// Consumes ⌈p/8⌉ bytes of entropy.\n public func range(p : Nat8) : ?Nat {\n var pp = p;\n var acc : Nat = 0;\n for (i in it) {\n if (8 : Nat8 <= pp)\n { acc := acc * 256 + Prim.nat8ToNat(i) }\n else if (0 : Nat8 == pp)\n { return ?acc }\n else {\n acc *= Prim.nat8ToNat(1 << pp);\n let mask : Nat8 = 0xff >> (8 - pp);\n return ?(acc + Prim.nat8ToNat(i & mask))\n };\n pp -= 8\n };\n null\n };\n\n /// Counts the number of heads in `n` fair coin tosses.\n /// Consumes ⌈p/8⌉ bytes of entropy.\n public func binomial(n : Nat8) : ?Nat8 {\n var nn = n;\n var acc : Nat8 = 0;\n for (i in it) {\n if (8 : Nat8 <= nn)\n { acc +%= Prim.popcntNat8(i) }\n else if (0 : Nat8 == nn)\n { return ?acc }\n else {\n let mask : Nat8 = 0xff << (8 - nn);\n let residue = Prim.popcntNat8(i & mask);\n return ?(acc +% residue)\n };\n nn -= 8\n };\n null\n }\n };\n\n let raw_rand = (actor \"aaaaa-aa\" : actor { raw_rand : () -> async Blob }).raw_rand;\n\n /// Distributes outcomes in the numeric range [0 .. 255].\n /// Seed blob must contain at least a byte.\n public func byteFrom(seed : Blob) : Nat8 {\n switch (seed.vals().next()) {\n case (?w) { w };\n case _ { P.unreachable() };\n }\n };\n\n /// Simulates a coin toss.\n /// Seed blob must contain at least a byte.\n public func coinFrom(seed : Blob) : Bool {\n switch (seed.vals().next()) {\n case (?w) { w > (127 : Nat8) };\n case _ { P.unreachable() };\n }\n };\n\n /// Obtains a full blob (32 bytes) worth of fresh entropy.\n public let blob : shared () -> async Blob = raw_rand;\n\n /// Distributes outcomes in the numeric range [0 .. 2^p - 1].\n /// Seed blob must contain at least ((p+7) / 8) bytes.\n public func rangeFrom(p : Nat8, seed : Blob) : Nat {\n rangeIter(p, seed.vals())\n };\n\n // internal worker method, expects iterator with sufficient supply\n func rangeIter(p : Nat8, it : I.Iter<Nat8>) : Nat {\n var pp = p;\n var acc : Nat = 0;\n for (i in it) {\n if (8 : Nat8 <= pp)\n { acc := acc * 256 + Prim.nat8ToNat(i) }\n else if (0 : Nat8 == pp)\n { return acc }\n else {\n acc *= Prim.nat8ToNat(1 << pp);\n let mask : Nat8 = 0xff >> (8 - pp);\n return acc + Prim.nat8ToNat(i & mask)\n };\n pp -= 8\n };\n P.unreachable()\n };\n\n /// Counts the number of heads in `n` coin tosses.\n /// Seed blob must contain at least ((n+7) / 8) bytes.\n public func binomialFrom(n : Nat8, seed : Blob) : Nat8 {\n binomialIter(n, seed.vals())\n };\n\n // internal worker method, expects iterator with sufficient supply\n func binomialIter(n : Nat8, it : I.Iter<Nat8>) : Nat8 {\n var nn = n;\n var acc : Nat8 = 0;\n for (i in it) {\n if (8 : Nat8 <= nn)\n { acc +%= Prim.popcntNat8(i) }\n else if (0 : Nat8 == nn)\n { return acc }\n else {\n let mask : Nat8 = 0xff << (8 - nn);\n let residue = Prim.popcntNat8(i & mask);\n return (acc +% residue)\n };\n nn -= 8\n };\n P.unreachable()\n }\n\n}\n"},"Trie.mo":{"content":"/// Functional key-value hash maps.\n///\n/// Functional maps (and sets) whose representation is \"canonical\", and\n/// independent of operation history (unlike other popular search trees).\n///\n/// The representation we use here comes from Section 6 of [\"Incremental computation via function caching\", Pugh & Teitelbaum](https://dl.acm.org/citation.cfm?id=75305).\n///\n/// ## User's overview\n///\n/// This module provides an applicative (functional) hash map.\n/// Notably, each `put` produces a **new trie _and value being replaced, if any_**.\n///\n/// Those looking for a more familiar (imperative,\n/// object-oriented) hash map should consider `TrieMap` or `HashMap` instead.\n///\n/// The basic `Trie` operations consist of:\n/// - `put` - put a key-value into the trie, producing a new version.\n/// - `get` - get a key's value from the trie, or `null` if none.\n/// - `iter` - visit every key-value in the trie.\n///\n/// The `put` and `get` operations work over `Key` records,\n/// which group the hash of the key with its non-hash key value.\n///\n/// ```motoko\n/// import Trie \"mo:base/Trie\";\n/// import Text \"mo:base/Text\";\n///\n/// type Trie<K, V> = Trie.Trie<K, V>;\n/// type Key<K> = Trie.Key<K>;\n///\n/// func key(t: Text) : Key<Text> { { key = t; hash = Text.hash t } };\n///\n/// let t0 : Trie<Text, Nat> = Trie.empty();\n/// let t1 : Trie<Text, Nat> = Trie.put(t0, key \"hello\", Text.equal, 42).0;\n/// let t2 : Trie<Text, Nat> = Trie.put(t1, key \"world\", Text.equal, 24).0;\n/// let n : ?Nat = Trie.put(t1, key \"hello\", Text.equal, 0).1;\n/// assert (n == ?42);\n/// ```\n///\n\n// ## Implementation overview\n//\n// A (hash) trie is a binary tree container for key-value pairs that\n// consists of leaf and branch nodes.\n//\n// Each internal **branch node**\n// represents having distinguished its key-value pairs on a single bit of\n// the keys.\n// By following paths in the trie, we determine an increasingly smaller\n// and smaller subset of the keys.\n//\n// Each **leaf node** consists of an association list of key-value pairs.\n//\n// Each non-empty trie node stores a size; we discuss that more below.\n//\n// ### Adaptive depth\n//\n// We say that a leaf is valid if it contains no more than `MAX_LEAF_SIZE`\n// key-value pairs. When a leaf node grows too large, the\n// binary tree produces a new internal binary node, and splits the leaf into\n// a pair of leaves using an additional bit of their keys' hash strings.\n//\n// For small mappings, the trie structure consists of a single\n// leaf, which contains up to MAX_LEAF_SIZE key-value pairs.\n//\n// ### Cached sizes\n//\n// At each branch and leaf, we use a stored size to support a\n// memory-efficient `toArray` function, which itself relies on\n// per-element projection via `nth`; in turn, `nth` directly uses the\n// O(1)-time function `size` for achieving an acceptable level of\n// algorithmic efficiency. Notably, leaves are generally lists of\n// key-value pairs, and we do not store a size for each Cons cell in the\n// list.\n//\n\nimport Debug \"mo:base/Debug\";\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport Option \"Option\";\nimport Hash \"Hash\";\nimport A \"Array\";\n\nimport List \"List\";\nimport AssocList \"AssocList\";\nimport I \"Iter\";\n\nmodule {\n\n let MAX_LEAF_SIZE = 8; // to do -- further profiling and tuning\n\n /// Binary hash tries: either empty, a leaf node, or a branch node\n public type Trie<K, V> = {\n #empty;\n #leaf : Leaf<K, V>;\n #branch : Branch<K, V>;\n };\n\n /// Leaf nodes of trie consist of key-value pairs as a list.\n public type Leaf<K, V> = {\n size : Nat ;\n keyvals : AssocList<Key<K>, V> ;\n };\n\n /// Branch nodes of the trie discriminate on a bit position of the keys' hashes.\n /// we never store this bitpos; rather,\n /// we enforce a style where this position is always known from context.\n public type Branch<K, V> = {\n size : Nat;\n left : Trie<K, V>;\n right : Trie<K, V>;\n };\n\n public type AssocList<K, V> = AssocList.AssocList<K, V>;\n\n //// A `Key` for the trie has an associated hash value\n public type Key<K> = {\n /// `hash` permits fast inequality checks, and permits collisions\n hash: Hash.Hash;\n /// `key` permits precise equality checks, but only used after equal hashes.\n key: K;\n };\n\n type List<T> = List.List<T>;\n\n /// Equality function for two `Key<K>`s, in terms of equality of `K`'s.\n public func equalKey<K>(keq : (K, K) -> Bool) : ((Key<K>, Key<K>) -> Bool) {\n func (key1 : Key<K>, key2 : Key<K>) : Bool {\n Hash.equal(key1.hash, key2.hash) and keq(key1.key, key2.key)\n }\n };\n\n /// @deprecated `isValid` is an internal predicate and will be removed in future.\n public func isValid<K, V>(t : Trie<K, V>, _enforceNormal : Bool) : Bool {\n func rec(t : Trie<K, V>, bitpos : ?Hash.Hash, bits : Hash.Hash, mask : Hash.Hash) : Bool {\n switch t {\n case (#empty) {\n true;\n };\n case (#leaf(l)) {\n let len = List.size(l.keyvals);\n len <= MAX_LEAF_SIZE + 1\n and\n len == l.size\n and\n List.all(\n l.keyvals,\n func ((k : Key<K>, v : V)) : Bool {\n ((k.hash & mask) == bits)\n }\n )\n };\n case (#branch(b)) {\n let bitpos1 =\n switch bitpos {\n case null {Prim.natToNat32(0)};\n case (?bp) {Prim.natToNat32(Prim.nat32ToNat(bp) + 1)}\n };\n let mask1 = mask | (Prim.natToNat32(1) << bitpos1);\n let bits1 = bits | (Prim.natToNat32(1) << bitpos1);\n let sum = size(b.left) + size(b.right);\n (b.size == sum) and\n rec(b.left, ?bitpos1, bits, mask1) and\n rec(b.right, ?bitpos1, bits1, mask1)\n };\n }\n };\n rec(t, null, 0, 0)\n };\n\n\n /// A 2D trie maps dimension-1 keys to another\n /// layer of tries, each keyed on the dimension-2 keys.\n public type Trie2D<K1, K2, V> = Trie<K1, Trie<K2, V>>;\n\n /// A 3D trie maps dimension-1 keys to another\n /// layer of 2D tries, each keyed on the dimension-2 and dimension-3 keys.\n public type Trie3D<K1, K2, K3, V> = Trie<K1, Trie2D<K2, K3, V> >;\n\n /// An empty trie.\n public func empty<K, V>() : Trie<K, V> { #empty; };\n\n /// Get the number of key-value pairs in the trie, in constant time.\n\n /// Get size in O(1) time.\n public func size<K, V>(t : Trie<K, V>) : Nat {\n switch t {\n case (#empty) { 0 };\n case (#leaf(l)) { l.size };\n case (#branch(b)) { b.size };\n }\n };\n\n /// Construct a branch node, computing the size stored there.\n public func branch<K, V>(l : Trie<K, V>, r : Trie<K, V>) : Trie<K, V> {\n let sum = size(l) + size(r);\n #branch {\n size = sum;\n left = l;\n right = r\n };\n };\n\n /// Construct a leaf node, computing the size stored there.\n ///\n /// This helper function automatically enforces the MAX_LEAF_SIZE\n /// by constructing branches as necessary; to do so, it also needs the bitpos\n /// of the leaf.\n public func leaf<K, V>(kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n fromList(null, kvs, bitpos)\n };\n\n module ListUtil {\n /* Deprecated: List.lenClamp */\n /// Return the list length unless the number of items in the list exceeds\n /// a maximum value. If the list length exceed the maximum, the function\n /// returns `null`.\n public func lenClamp<T>(l : List<T>, max : Nat) : ?Nat {\n func rec(l : List<T>, max : Nat, i : Nat) : ?Nat {\n switch l {\n case null { ?i };\n case (?(_, t)) {\n if ( i > max ) { null }\n else { rec(t, max, i + 1) }\n };\n }\n };\n rec(l, max, 0)\n };\n };\n\n /// Transform a list into a trie, splitting input list into small (leaf) lists, if necessary.\n public func fromList<K, V>(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n func rec(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n switch kvc {\n case null {\n switch (ListUtil.lenClamp(kvs, MAX_LEAF_SIZE)) {\n case null {} /* fall through to branch case. */;\n case (?len) {\n return #leaf({ size = len; keyvals = kvs })\n };\n }\n };\n case (?c) {\n if ( c == 0 ) {\n return #empty\n } else if ( c <= MAX_LEAF_SIZE ) {\n return #leaf({ size = c; keyvals = kvs })\n } else {\n /* fall through to branch case */\n }\n };\n };\n let (ls, l, rs, r) = splitList(kvs, bitpos);\n if ( ls == 0 and rs == 0 ) {\n #empty\n } else if (rs == 0 and ls <= MAX_LEAF_SIZE) {\n #leaf({ size = ls; keyvals = l })\n } else if (ls == 0 and rs <= MAX_LEAF_SIZE) {\n #leaf({ size = rs; keyvals = r })\n } else {\n branch(rec(?ls, l, bitpos + 1), rec(?rs, r, bitpos + 1))\n }\n };\n rec(kvc, kvs, bitpos)\n };\n\n /// Clone the trie efficiently, via sharing.\n ///\n /// Purely-functional representation permits _O(1)_ copy, via persistent sharing.\n public func clone<K, V>(t : Trie<K, V>) : Trie<K, V> = t;\n\n /// Replace the given key's value option with the given one, returning the previous one\n public func replace<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : ?V) : (Trie<K, V>, ?V) {\n let key_eq = equalKey(k_eq);\n\n func rec(t : Trie<K, V>, bitpos : Nat) : (Trie<K, V>, ?V) {\n switch t {\n case (#empty) {\n let (kvs, _) = AssocList.replace(null, k, key_eq, v);\n (leaf(kvs, bitpos), null)\n };\n case (#branch(b)) {\n let bit = Hash.bit(k.hash, bitpos);\n // rebuild either the left or right path with the (k, v) pair\n if (not bit) {\n let (l, v_) = rec(b.left, bitpos + 1);\n (branch(l, b.right), v_)\n }\n else {\n let (r, v_) = rec(b.right, bitpos + 1);\n (branch(b.left, r), v_)\n }\n };\n case (#leaf(l)) {\n let (kvs2, old_val) =\n AssocList.replace(l.keyvals, k, key_eq, v);\n (leaf(kvs2, bitpos), old_val)\n };\n }\n };\n let (to, vo) = rec(t, 0);\n //assert(isValid<K, V>(to, false));\n (to, vo)\n };\n\n /// Put the given key's value in the trie; return the new trie, and the previous value associated with the key, if any\n public func put<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : (Trie<K, V>, ?V) {\n replace(t, k, k_eq, ?v)\n };\n\n /// Get the value of the given key in the trie, or return null if nonexistent\n public func get<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V =\n find(t, k, k_eq);\n\n /// Find the given key's value in the trie, or return null if nonexistent\n public func find<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V {\n let key_eq = equalKey(k_eq);\n func rec(t : Trie<K, V>, bitpos : Nat) : ?V {\n switch t {\n case (#empty) { null };\n case (#leaf(l)) {\n AssocList.find(l.keyvals, k, key_eq)\n };\n case (#branch(b)) {\n let bit = Hash.bit(k.hash, bitpos);\n if (not bit) {\n rec(b.left, bitpos + 1)\n }\n else {\n rec(b.right, bitpos + 1)\n }\n };\n }\n };\n rec(t, 0)\n };\n\n\n\n func splitAssocList<K, V>(al : AssocList<Key<K>, V>, bitpos : Nat)\n : (AssocList<Key<K>, V>, AssocList<Key<K>, V>)\n {\n List.partition(\n al,\n func ((k : Key<K>, v : V)) : Bool {\n not Hash.bit(k.hash, bitpos)\n }\n )\n };\n\n func splitList<K, V>(l : AssocList<Key<K>, V>, bitpos : Nat)\n : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>)\n {\n func rec(l : AssocList<Key<K>, V>) : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>) {\n switch l {\n case null { (0, null, 0, null) };\n case (?((k, v), t)) {\n let (cl, l, cr, r) = rec(t) ;\n if (not Hash.bit(k.hash, bitpos)){\n (cl + 1, ?((k, v), l), cr, r)\n } else {\n (cl, l, cr + 1, ?((k, v), r))\n }\n };\n }\n };\n rec(l)\n };\n\n /// Merge tries, preferring the right trie where there are collisions\n /// in common keys.\n ///\n /// note: the `disj` operation generalizes this `merge`\n /// operation in various ways, and does not (in general) lose\n /// information; this operation is a simpler, special case.\n public func merge<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> {\n switch (tl, tr) {\n case (#empty, _) { return tr };\n case (_, #empty) { return tl };\n case (#leaf(l1), #leaf(l2)) {\n leaf(\n AssocList.disj(\n l1.keyvals, l2.keyvals,\n key_eq,\n func (x : ?V, y : ?V) : V {\n switch (x, y) {\n case (null, null) { P.unreachable() };\n case (null, ?v) { v };\n case (?v, _) { v };\n }\n }\n ),\n bitpos)\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right))\n };\n }\n };\n rec(0, tl, tr)\n };\n\n /// Merge tries like `merge`, except signals a\n /// dynamic error if there are collisions in common keys between the\n /// left and right inputs.\n public func mergeDisjoint<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> {\n switch (tl, tr) {\n case (#empty, _) { return tr };\n case (_, #empty) { return tl };\n case (#leaf(l1), #leaf(l2)) {\n leaf(\n AssocList.disjDisjoint(\n l1.keyvals, l2.keyvals,\n func (x : ?V, y : ?V) : V {\n switch (x, y) {\n case (null, ?v) { v };\n case (?v, null) { v };\n case (_, _) { P.unreachable() };\n }\n }\n ),\n bitpos\n )\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(\n rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right)\n )\n };\n }\n };\n rec(0, tl, tr)\n };\n\n /// Difference of tries. The output consists are pairs of\n /// the left trie whose keys are not present in the right trie; the\n /// values of the right trie are irrelevant.\n public func diff<K, V, W>(tl : Trie<K, V>, tr : Trie<K, W>, k_eq : ( K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, V> {\n switch (tl, tr) {\n case (#empty, _) { return #empty };\n case (_, #empty) { return tl };\n case (#leaf(l1), #leaf(l2)) {\n leaf(\n AssocList.diff(\n l1.keyvals, l2.keyvals,\n key_eq,\n ),\n bitpos\n )\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right))\n };\n }\n };\n rec(0, tl, tr)\n };\n\n /// Map disjunction.\n ///\n /// This operation generalizes the notion of \"set union\" to finite maps.\n ///\n /// Produces a \"disjunctive image\" of the two tries, where the values of\n /// matching keys are combined with the given binary operator.\n ///\n /// For unmatched key-value pairs, the operator is still applied to\n /// create the value in the image. To accomodate these various\n /// situations, the operator accepts optional values, but is never\n /// applied to (null, null).\n ///\n /// Implements the database idea of an [\"outer join\"](https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join).\n ///\n public func disj<K, V, W, X>(\n tl : Trie<K, V>,\n tr : Trie<K, W>,\n k_eq : (K, K) -> Bool,\n vbin : (?V, ?W) -> X\n ) : Trie<K, X> {\n let key_eq = equalKey(k_eq);\n\n /* empty right case; build from left only: */\n func recL(t : Trie<K, V>, bitpos : Nat) : Trie<K, X> {\n switch t {\n case (#empty) { #empty };\n case (#leaf(l)) {\n leaf(AssocList.disj(l.keyvals, null, key_eq, vbin), bitpos)\n };\n case (#branch(b)) {\n branch(recL(b.left, bitpos + 1),\n recL(b.right, bitpos + 1)) };\n }\n };\n\n /* empty left case; build from right only: */\n func recR(t : Trie<K, W>, bitpos : Nat) : Trie<K, X> {\n switch t {\n case (#empty) { #empty };\n case (#leaf(l)) {\n leaf(AssocList.disj(null, l.keyvals, key_eq, vbin), bitpos)\n };\n case (#branch(b)) {\n branch(recR(b.left, bitpos + 1),\n recR(b.right, bitpos + 1)) };\n }\n };\n\n /* main recursion */\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, X> {\n switch (tl, tr) {\n case (#empty, #empty) { #empty };\n case (#empty, _) { recR(tr, bitpos) };\n case (_, #empty) { recL(tl, bitpos) };\n case (#leaf(l1), #leaf(l2)) {\n leaf(AssocList.disj(l1.keyvals, l2.keyvals, key_eq, vbin), bitpos)\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right))\n };\n }\n };\n\n rec(0, tl, tr)\n };\n\n /// Map join.\n ///\n /// Implements the database idea of an [\"inner join\"](https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join).\n ///\n /// This operation generalizes the notion of \"set intersection\" to\n /// finite maps. The values of matching keys are combined with the given binary\n /// operator, and unmatched key-value pairs are not present in the output.\n ///\n public func join<K, V, W, X>(\n tl : Trie<K, V>,\n tr : Trie<K, W>,\n k_eq : (K, K) -> Bool,\n vbin : (V, W) -> X\n ) : Trie<K, X> {\n let key_eq = equalKey(k_eq);\n\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, X> {\n switch (tl, tr) {\n case (#empty, _) { #empty };\n case (_, #empty) { #empty };\n case (#leaf(l1), #leaf(l2)) {\n leaf(AssocList.join(l1.keyvals, l2.keyvals, key_eq, vbin), bitpos)\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right))\n };\n }\n };\n\n rec(0, tl, tr)\n };\n\n /// This operation gives a recursor for the internal structure of\n /// tries. Many common operations are instantiations of this function,\n /// either as clients, or as hand-specialized versions (e.g., see , map,\n /// mapFilter, some and all below).\n public func foldUp<K, V, X>(t : Trie<K, V>, bin : (X, X) -> X, leaf : (K, V) -> X, empty : X) : X {\n func rec(t : Trie<K, V>) : X {\n switch t {\n case (#empty) { empty };\n case (#leaf(l)) {\n AssocList.fold(\n l.keyvals, empty,\n func (k : Key<K>, v : V, x : X) : X { bin(leaf(k.key, v), x) }\n )\n };\n case (#branch(b)) { bin(rec(b.left), rec(b.right)) };\n }\n };\n rec(t)\n };\n\n\n /// Map product.\n ///\n /// Conditional _catesian product_, where the given\n /// operation `op` _conditionally_ creates output elements in the\n /// resulting trie.\n ///\n /// The keyed structure of the input tries are not relevant for this\n /// operation: all pairs are considered, regardless of keys matching or\n /// not. Moreover, the resulting trie may use keys that are unrelated to\n /// these input keys.\n ///\n public func prod<K1, V1, K2, V2, K3, V3>(\n tl : Trie<K1, V1>,\n tr : Trie<K2, V2>,\n op : (K1, V1, K2, V2) -> ?(Key<K3>, V3),\n k3_eq : (K3, K3) -> Bool\n ) : Trie<K3, V3> {\n\n /*- binary case: merge disjoint results: */\n func merge (a : Trie<K3, V3>, b : Trie<K3, V3>) : Trie<K3, V3> =\n mergeDisjoint(a, b, k3_eq);\n\n /*- \"`foldUp` squared\" (imagine two nested loops): */\n foldUp(\n tl, merge,\n func (k1 : K1, v1 : V1) : Trie<K3, V3> {\n foldUp(\n tr, merge,\n func (k2 : K2, v2 : V2) : Trie<K3, V3> {\n switch (op(k1, v1, k2, v2)) {\n case null { #empty };\n case (?(k3, v3)) { (put(#empty, k3, k3_eq, v3)).0 };\n }\n },\n #empty\n )\n },\n #empty\n )\n };\n\n /// Returns an `Iter` over the key-value entries of the trie.\n ///\n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n public func iter<K, V>(t : Trie<K, V>) : I.Iter<(K, V)> {\n object {\n var stack = ?(t, null) : List.List<Trie<K, V>>;\n public func next() : ?(K, V) {\n switch stack {\n case null { null };\n case (?(trie, stack2)) {\n switch trie {\n case (#empty) {\n stack := stack2;\n next()\n };\n case (#leaf({ keyvals = null })) {\n stack := stack2;\n next()\n };\n case (#leaf({ size = c; keyvals = ?((k, v), kvs) })) {\n stack := ?(#leaf({ size = c-1; keyvals = kvs }), stack2);\n ?(k.key, v)\n };\n case (#branch(br)) {\n stack := ?(br.left, ?(br.right, stack2));\n next()\n };\n }\n }\n }\n }\n }\n };\n\n /// Represent the construction of tries as data.\n ///\n /// This module provides optimized variants of normal tries, for\n /// more efficient join queries.\n ///\n /// The central insight is that for (unmaterialized) join query results, we\n /// do not need to actually build any resulting trie of the resulting\n /// data, but rather, just need a collection of what would be in that\n /// trie. Since query results can be large (quadratic in the DB size),\n /// avoiding the construction of this trie provides a considerable savings.\n ///\n /// To get this savings, we use an ADT for the operations that _would_ build this trie,\n /// if evaluated. This structure specializes a rope: a balanced tree representing a\n /// sequence. It is only as balanced as the tries from which we generate\n /// these build ASTs. They have no intrinsic balance properties of their\n /// own.\n ///\n public module Build {\n /// The build of a trie, as an AST for a simple DSL.\n public type Build<K, V> = {\n #skip ;\n #put : (K, ?Hash.Hash, V) ;\n #seq : {\n size : Nat;\n left : Build<K, V>;\n right : Build<K, V>;\n } ;\n };\n\n /// Size of the build, measured in `#put` operations\n public func size<K, V>(tb : Build<K, V>) : Nat {\n switch tb {\n case (#skip) { 0 };\n case (#put(_, _, _)) { 1 };\n case (#seq(seq)) { seq.size };\n }\n };\n\n /// Build sequence of two sub-builds\n public func seq<K, V>(l : Build<K, V>, r : Build<K, V>) : Build<K, V> {\n let sum = size(l) + size(r);\n #seq({ size = sum; left = l; right = r })\n };\n\n /// Like [`prod`](#prod), except do not actually do the put calls, just\n /// record them, as a (binary tree) data structure, isomorphic to the\n /// recursion of this function (which is balanced, in expectation).\n public func prod<K1, V1, K2, V2, K3, V3>(\n tl : Trie<K1, V1>,\n tr : Trie<K2, V2>,\n op : (K1, V1, K2, V2) -> ?(K3, V3),\n k3_eq : (K3, K3) -> Bool\n ) : Build<K3, V3> {\n\n func outer_bin (a : Build<K3, V3>, b : Build<K3, V3>)\n : Build<K3, V3> {\n seq(a, b)\n };\n\n func inner_bin (a : Build<K3, V3>, b : Build<K3, V3>)\n : Build<K3, V3> {\n seq(a, b)\n };\n\n /// double-nested folds\n foldUp(\n tl, outer_bin,\n func (k1 : K1, v1 : V1) : Build<K3, V3> {\n foldUp(\n tr, inner_bin,\n func (k2 : K2, v2 : V2) : Build<K3, V3> {\n switch (op(k1, v1, k2, v2)) {\n case null { #skip };\n case (?(k3, v3)) { #put(k3, null, v3) };\n }\n },\n #skip\n )\n },\n #skip\n )\n };\n\n /// Project the nth key-value pair from the trie build.\n ///\n /// This position is meaningful only when the build contains multiple uses of one or more keys, otherwise it is not.\n public func nth<K, V>(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) {\n func rec(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) {\n switch tb {\n case (#skip) { P.unreachable() };\n case (#put(k, h, v)) {\n assert(i == 0);\n ?(k, h, v)\n };\n case (#seq(s)) {\n let size_left = size(s.left);\n if (i < size_left) { rec(s.left, i) }\n else { rec(s.right, i - size_left) }\n };\n }\n };\n\n if (i >= size(tb)) {\n return null\n };\n rec(tb, i)\n };\n\n /// Like [`mergeDisjoint`](#mergedisjoint), except that it avoids the\n /// work of actually merging any tries; rather, just record the work for\n /// latter (if ever).\n public func projectInner<K1, K2, V>(t : Trie<K1, Build<K2, V>>)\n : Build<K2, V> {\n foldUp(\n t,\n func (t1 : Build<K2, V>, t2 : Build<K2, V>) : Build<K2, V> { seq(t1, t2) },\n func (_ : K1, t : Build<K2, V>) : Build<K2, V> { t },\n #skip\n )\n };\n\n /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n public func toArray<K, V, W>(tb : Build<K, V>, f: (K, V) -> W) : [W] {\n let c = size(tb);\n let a = A.init<?W>(c, null);\n var i = 0;\n func rec(tb : Build<K, V>) {\n switch tb {\n case (#skip) {};\n case (#put(k, _, v)) { a[i] := ?f(k, v); i := i + 1 };\n case (#seq(s)) { rec(s.left); rec(s.right) };\n }\n };\n rec(tb);\n A.tabulate(c, func(i : Nat) : W {\n switch (a[i]) {\n case null { P.unreachable() };\n case (?x) { x }\n }})\n };\n\n };\n\n /// Fold over the key-value pairs of the trie, using an accumulator.\n /// The key-value pairs have no reliable or meaningful ordering.\n public func fold<K, V, X>(t : Trie<K, V>, f : (K, V, X) -> X, x : X) : X {\n func rec(t : Trie<K, V>, x : X) : X {\n switch t {\n case (#empty) { x };\n case (#leaf(l)) {\n AssocList.fold(\n l.keyvals, x,\n func (k : Key<K>, v : V, x : X) : X = f(k.key, v, x)\n )\n };\n case (#branch(b)) { rec(b.left, rec(b.right, x)) };\n };\n };\n rec(t, x)\n };\n\n /// Test whether a given key-value pair is present, or not.\n public func some<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n func rec(t : Trie<K, V>) : Bool {\n switch t {\n case (#empty) { false };\n case (#leaf(l)) {\n List.some(\n l.keyvals, func ((k : Key<K>, v:V)) : Bool = f(k.key, v)\n )\n };\n case (#branch(b)) { rec(b.left) or rec(b.right) };\n };\n };\n rec(t)\n };\n\n /// Test whether all key-value pairs have a given property.\n public func all<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n func rec(t : Trie<K, V>) : Bool {\n switch t {\n case (#empty) { true };\n case (#leaf(l)) {\n List.all(\n l.keyvals, func ((k : Key<K>, v : V)) : Bool=f(k.key, v)\n )\n };\n case (#branch(b)) { rec(b.left) and rec(b.right) };\n };\n };\n rec(t)\n };\n\n /// Project the nth key-value pair from the trie.\n ///\n /// Note: This position is not meaningful; it's only here so that we\n /// can inject tries into arrays using functions like `Array.tabulate`.\n public func nth<K, V>(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) {\n func rec(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) {\n switch t {\n case (#empty) { P.unreachable() };\n case (#leaf(l)) { List.get(l.keyvals, i) };\n case (#branch(b)) {\n let size_left = size(b.left);\n if (i < size_left) { rec(b.left, i) }\n else { rec(b.right, i - size_left) }\n }\n }\n };\n if (i >= size(t)) {\n return null\n };\n rec(t, i)\n };\n\n\n /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n public func toArray<K, V, W>(t : Trie<K, V>, f : (K, V) -> W) : [W] {\n let a = A.tabulate<W> (\n size(t),\n func (i : Nat) : W {\n let (k, v) = switch (nth(t, i)) {\n case null { P.unreachable() };\n case (?x) { x };\n };\n f(k.key, v)\n }\n );\n a\n };\n\n /// Test for \"deep emptiness\": subtrees that have branching structure,\n /// but no leaves. These can result from naive filtering operations;\n /// filter uses this function to avoid creating such subtrees.\n public func isEmpty<K, V>(t : Trie<K, V>) : Bool {\n size(t) == 0\n };\n\n /// Filter the key-value pairs by a given predicate.\n public func filter<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Trie<K, V> {\n func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, V> {\n switch t {\n case (#empty) { #empty };\n case (#leaf(l)) {\n leaf(\n List.filter(\n l.keyvals,\n func ((k : Key<K>, v : V)) : Bool = f(k.key, v)\n ),\n bitpos\n )\n };\n case (#branch(b)) {\n let fl = rec(b.left, bitpos + 1);\n let fr = rec(b.right, bitpos + 1);\n if (isEmpty(fl) and isEmpty(fr)) {\n #empty\n } else {\n branch(fl, fr)\n }\n }\n }\n };\n rec(t, 0)\n };\n\n /// Map and filter the key-value pairs by a given predicate.\n public func mapFilter<K, V, W>(t : Trie<K, V>, f : (K, V) -> ?W) : Trie<K, W> {\n func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, W> {\n switch t {\n case (#empty) { #empty };\n case (#leaf(l)) {\n leaf(\n List.mapFilter(\n l.keyvals,\n // retain key and hash, but update key's value using f:\n func ((k : Key<K>, v : V)) : ?(Key<K>, W) {\n switch (f(k.key, v)) {\n case null { null };\n case (?w) { ?({key = k.key; hash = k.hash}, w) };\n }\n }\n ),\n bitpos\n )\n };\n case (#branch(b)) {\n let fl = rec(b.left, bitpos + 1);\n let fr = rec(b.right, bitpos + 1);\n if (isEmpty(fl) and isEmpty(fr)) {\n #empty\n } else {\n branch(fl, fr)\n }\n }\n }\n };\n\n rec(t, 0)\n };\n\n /// Test for equality, but naively, based on structure.\n /// Does not attempt to remove \"junk\" in the tree;\n /// For instance, a \"smarter\" approach would equate\n /// `#bin {left = #empty; right = #empty}`\n /// with\n /// `#empty`.\n /// We do not observe that equality here.\n public func equalStructure<K, V>(\n tl : Trie<K, V>,\n tr : Trie<K, V>,\n keq : (K, K) -> Bool,\n veq : (V, V) -> Bool\n ) : Bool {\n func rec(tl : Trie<K, V>, tr : Trie<K, V>) : Bool {\n switch (tl, tr) {\n case (#empty, #empty) { true };\n case (#leaf(l1), #leaf(l2)) {\n List.equal(l1.keyvals, l2.keyvals,\n func ((k1 : Key<K>, v1 : V), (k2 : Key<K>, v2 : V)) : Bool =\n keq(k1.key, k2.key) and veq(v1, v2)\n )\n };\n case (#branch(b1), #branch(b2)) {\n rec(b1.left, b2.left) and rec(b2.right, b2.right)\n };\n case _ { false };\n }\n };\n rec(tl, tr)\n };\n\n /// Replace the given key's value in the trie,\n /// and only if successful, do the success continuation,\n /// otherwise, return the failure value\n public func replaceThen<K, V, X>(\n t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v2 : V,\n success: (Trie<K, V>, V) -> X,\n fail: () -> X\n ) : X {\n let (t2, ov) = replace(t, k, k_eq, ?v2);\n switch ov {\n case null { /* no prior value; failure to remove */ fail() };\n case (?v1) { success(t2, v1) };\n }\n };\n\n /// Put the given key's value in the trie; return the new trie; assert that no prior value is associated with the key\n public func putFresh<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : Trie<K, V> {\n let (t2, none) = replace(t, k, k_eq, ?v);\n switch none {\n case null {};\n case (?_) assert false;\n };\n t2\n };\n\n /// Put the given key's value in the 2D trie; return the new 2D trie.\n public func put2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n v:V\n ) : Trie2D<K1, K2, V> {\n let inner = find(t, k1, k1_eq);\n let (updated_inner, _) = switch inner {\n case null { put(#empty, k2, k2_eq, v) };\n case (?inner) { put(inner, k2, k2_eq, v) };\n };\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n updated_outer;\n };\n\n /// Put the given key's value in the trie; return the new trie;\n public func put3D<K1, K2, K3, V> (\n t : Trie3D<K1, K2, K3, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n k3 : Key<K3>,\n k3_eq : (K3, K3) -> Bool,\n v : V\n ) : Trie3D<K1, K2, K3, V> {\n let inner1 = find(t, k1, k1_eq);\n let (updated_inner1, _) = switch inner1 {\n case null {\n put(\n #empty, k2, k2_eq,\n (put(#empty, k3, k3_eq, v)).0\n )\n };\n case (?inner1) {\n let inner2 = find(inner1, k2, k2_eq);\n let (updated_inner2, _) = switch inner2 {\n case null { put(#empty, k3, k3_eq, v) };\n case (?inner2) { put(inner2, k3, k3_eq, v) };\n };\n put(inner1, k2, k2_eq, updated_inner2 )\n };\n };\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner1);\n updated_outer;\n };\n\n /// Remove the given key's value in the trie; return the new trie\n public func remove<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : (Trie<K, V>, ?V) {\n replace(t, k, k_eq, null)\n };\n\n /// Remove the given key's value in the trie,\n /// and only if successful, do the success continuation,\n /// otherwise, return the failure value\n public func removeThen<K, V, X>(\n t : Trie<K, V>,\n k : Key<K>,\n k_eq : (K, K) -> Bool,\n success : (Trie<K, V>, V) -> X,\n fail : () -> X\n ) : X {\n let (t2, ov) = replace(t, k, k_eq, null);\n switch ov {\n case null { /* no prior value; failure to remove */ fail() };\n case (?v) { success(t2, v) };\n }\n };\n\n\n /// remove the given key-key pair's value in the 2D trie; return the\n /// new trie, and the prior value, if any.\n public func remove2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool\n ) : (Trie2D<K1, K2, V>, ?V) {\n switch (find(t, k1, k1_eq)) {\n case null {\n (t, null)\n };\n case (?inner) {\n let (updated_inner, ov) = remove(inner, k2, k2_eq);\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n (updated_outer, ov)\n };\n }\n };\n\n /// Remove the given key-key pair's value in the 3D trie; return the\n /// new trie, and the prior value, if any.\n public func remove3D<K1, K2, K3, V>(\n t : Trie3D<K1, K2, K3, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n k3 : Key<K3>,\n k3_eq : (K3, K3) -> Bool,\n ) : (Trie3D<K1, K2, K3, V>, ?V) {\n switch (find(t, k1, k1_eq)) {\n case null {\n (t, null)\n };\n case (?inner) {\n let (updated_inner, ov) = remove2D(inner, k2, k2_eq, k3, k3_eq);\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n (updated_outer, ov)\n };\n }\n };\n\n /// Like [`mergeDisjoint`](#mergedisjoint), except instead of merging a\n /// pair, it merges the collection of dimension-2 sub-trees of a 2D\n /// trie.\n public func mergeDisjoint2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1_eq : (K1, K1) -> Bool,\n k2_eq : (K2, K2) -> Bool\n ) : Trie<K2, V> {\n foldUp(\n t,\n func (t1 : Trie<K2, V>, t2 : Trie<K2, V>) : Trie<K2, V> {\n mergeDisjoint(t1, t2, k2_eq)\n },\n func (_ : K1, t : Trie<K2, V>) : Trie<K2, V> { t },\n #empty\n )\n };\n\n}\n"}}}
1
+ {"name":"base","version":"master","files":{"AssocList.mo":{"content":"/// Lists of key-value entries (\"associations\").\n///\n/// Implements the same operations as library `Trie`, but uses a\n/// linked-list of entries and no hashing.\n\nimport List \"List\";\n\nmodule {\n\n /// polymorphic association linked lists between keys and values\n public type AssocList<K, V> = List.List<(K, V)>;\n\n /// Find the value associated with a given key, or null if absent.\n public func find<K, V>(\n al : AssocList<K, V>,\n k : K,\n k_eq : (K, K) -> Bool\n ) : ?V {\n func rec(al : AssocList<K, V>) : ?V {\n label profile_assocList_find_rec : (?V)\n switch (al) {\n case (null) { label profile_assocList_find_end_fail : (?V) { null } };\n case (?((hd_k, hd_v), tl)) {\n if (k_eq(k, hd_k)) {\n label profile_assocList_find_end_success : (?V) {\n ?hd_v\n }\n } else {\n rec(tl)\n }\n };\n }\n };\n label profile_assocList_find_begin : (?V) {\n rec(al)\n }\n };\n\n /// replace the value associated with a given key, or add it, if missing.\n /// returns old value, or null, if no prior value existed.\n public func replace<K, V>(\n al : AssocList<K, V>,\n k : K,\n k_eq : (K, K) -> Bool,\n ov : ?V\n )\n : (AssocList<K, V>, ?V) {\n func rec(al : AssocList<K, V>) : (AssocList<K, V>, ?V) {\n switch (al) {\n case (null) {\n switch ov {\n case (null) { (null, null) };\n case (?v) { (?((k, v), null), null) };\n }\n };\n case (?((hd_k, hd_v), tl)) {\n if (k_eq(k, hd_k)) {\n // if value is null, remove the key; otherwise, replace key's old value\n // return old value\n switch ov {\n case (null) { (tl, ?hd_v) };\n case (?v) { (?((hd_k, v), tl), ?hd_v) };\n }\n } else {\n let (tl2, old_v) = rec(tl);\n (?((hd_k, hd_v), tl2), old_v)\n }\n };\n }\n };\n rec(al)\n };\n\n /// The entries of the final list consist of those pairs of\n /// the left list whose keys are not present in the right list; the\n /// \"extra\" values of the right list are irrelevant.\n public func diff<K, V, W>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n keq : (K, K) -> Bool\n ) : AssocList<K, V> {\n func rec(al1 : AssocList<K, V>) : AssocList<K, V> {\n switch al1 {\n case (null) { null };\n case (?((k, v1), tl)) {\n switch (find<K, W>(al2, k, keq)) {\n case (null) { ?((k, v1), rec(tl)) };\n case (?v2) { rec(tl)};\n }\n };\n }\n };\n rec(al1)\n };\n\n /// Transform and combine the entries of two association lists.\n public func mapAppend<K, V, W, X>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n vbin : (?V, ?W) -> X\n ) : AssocList<K, X> =\n label profile_assocList_mapAppend : AssocList<K, X> {\n func rec(al1 : AssocList<K, V>, al2 : AssocList<K, W>) : AssocList<K, X> =\n label profile_assocList_mapAppend_rec : AssocList<K,X> {\n switch (al1, al2) {\n case (null, null) { null };\n case (?((k, v), al1_), _ ) { ?((k, vbin(?v, null)), rec(al1_, al2 )) };\n case (null, ?((k, v), al2_)) { ?((k, vbin(null, ?v)), rec(null, al2_)) };\n }\n };\n rec(al1, al2)\n };\n\n /// Specialized version of `disj`, optimized for disjoint sub-spaces of keyspace (no matching keys).\n public func disjDisjoint<K, V, W, X>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n vbin : (?V, ?W) -> X)\n : AssocList<K, X> = label profile_assocList_disjDisjoint : AssocList<K,X> {\n mapAppend<K, V, W, X>(al1, al2, vbin)\n };\n\n /// This operation generalizes the notion of \"set union\" to finite maps.\n /// Produces a \"disjunctive image\" of the two lists, where the values of\n /// matching keys are combined with the given binary operator.\n ///\n /// For unmatched entries, the operator is still applied to\n /// create the value in the image. To accomodate these various\n /// situations, the operator accepts optional values, but is never\n /// applied to (null, null).\n public func disj<K, V, W, X>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n keq : (K, K) -> Bool,\n vbin :(?V, ?W) -> X\n ) : AssocList<K, X> {\n func rec1(al1Rec : AssocList<K, V>) : AssocList<K, X> {\n switch al1Rec {\n case (null) {\n func rec2(al2 : AssocList<K, W>) : AssocList<K, X> {\n switch al2 {\n case (null) { null };\n case (?((k, v2), tl)) {\n switch (find<K, V>(al1, k, keq)) {\n case (null) { ?((k, vbin(null, ?v2)), rec2(tl)) };\n case (?v1) { ?((k, vbin(?v1, ?v2)), rec2(tl)) };\n }\n };\n }\n };\n rec2(al2)\n };\n case (?((k, v1), tl)) {\n switch (find<K, W>(al2, k, keq)) {\n case (null) { ?((k, vbin(?v1, null)), rec1(tl)) };\n case (?v2) { /* handled above */ rec1(tl) };\n }\n };\n }\n };\n rec1(al1)\n };\n\n /// This operation generalizes the notion of \"set intersection\" to\n /// finite maps. Produces a \"conjuctive image\" of the two lists, where\n /// the values of matching keys are combined with the given binary\n /// operator, and unmatched entries are not present in the output.\n public func join<K, V, W, X>(\n al1 : AssocList<K, V>,\n al2 : AssocList<K, W>,\n keq : (K, K) -> Bool,\n vbin : (V, W) -> X\n ) : AssocList<K, X> {\n func rec(al1 : AssocList<K, V>) : AssocList<K, X> {\n switch al1 {\n case (null) { null };\n case (?((k, v1), tl)) {\n switch (find<K, W>(al2, k, keq)) {\n case (null) { rec(tl) };\n case (?v2) { ?((k, vbin(v1, v2)), rec(tl)) };\n }\n };\n }\n };\n rec(al1)\n };\n\n /// Fold the entries based on the recursive list structure.\n public func fold<K, V, X>(\n al : AssocList<K, V>,\n nil : X,\n cons : (K, V, X) -> X\n ) : X {\n func rec(al : AssocList<K, V>) : X {\n switch al {\n case null { nil };\n case (?((k, v), t)) { cons(k, v, rec(t)) };\n }\n };\n rec(al)\n };\n\n}\n"},"Array.mo":{"content":"/// Provides extended utility functions on Arrays. Note the difference between\n/// mutable and non-mutable arrays below.\n///\n/// WARNING: If you are looking for a list that can grow and shrink in size,\n/// it is recommended you use either the Buffer class or the List class for\n/// those purposes. Arrays must be created with a fixed size.\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Array \"mo:base/Array\";\n/// ```\n\nimport I \"IterType\";\nimport Option \"Option\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\nimport Result \"Result\";\n\nmodule {\n /// Create a mutable array with `size` copies of the initial value.\n ///\n /// ```motoko include=import\n /// let array = Array.init<Nat>(4, 2);\n /// ```\n ///\n /// Runtime: O(size)\n /// Space: O(size)\n public func init<X>(size : Nat, initValue : X) : [var X] =\n Prim.Array_init<X>(size, initValue);\n\n /// Create an immutable array of size `size`. Each element at index i\n /// is created by applying `generator` to i.\n ///\n /// ```motoko include=import\n /// let array : [Nat] = Array.tabulate<Nat>(4, func i = i * 2);\n /// ```\n ///\n /// Runtime: O(size)\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `generator` runs in O(1) time and space.\n public func tabulate<X>(size : Nat, generator : Nat -> X) : [X] =\n Prim.Array_tabulate<X>(size, generator);\n\n /// Create a mutable array of size `size`. Each element at index i\n /// is created by applying `generator` to i.\n ///\n /// ```motoko include=import\n /// let array : [var Nat] = Array.tabulateVar<Nat>(4, func i = i * 2);\n /// array[2] := 0;\n /// array\n /// ```\n ///\n /// Runtime: O(size)\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `generator` runs in O(1) time and space.\n public func tabulateVar<X>(size : Nat, generator : Nat -> X) : [var X] {\n // FIXME add this as a primitive in the RTS\n if (size == 0) { return [var] };\n let array = Prim.Array_init<X>(size, generator 0);\n var i = 0;\n while (i < size) {\n array[i] := generator i;\n i += 1;\n };\n array\n };\n\n /// Transforms a mutable array into an immutable array.\n ///\n /// ```motoko include=import\n ///\n /// let varArray = [var 0, 1, 2];\n /// varArray[2] := 3;\n /// let array = Array.freeze<Nat>(varArray);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func freeze<X>(varArray : [var X]) : [X] =\n Prim.Array_tabulate<X>(varArray.size(), func i = varArray[i]);\n\n /// Transforms an immutable array into a mutable array.\n ///\n /// ```motoko include=import\n ///\n /// let array = [0, 1, 2];\n /// let varArray = Array.thaw<Nat>(array);\n /// varArray[2] := 3;\n /// varArray\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func thaw<A>(array : [A]) : [var A] {\n let size = array.size();\n if (size == 0) {\n return [var];\n };\n let newArray = Prim.Array_init<A>(size, array[0]);\n var i = 0;\n while (i < size) {\n newArray[i] := array[i];\n i += 1;\n };\n newArray\n };\n\n /// Tests if two arrays contain equal values (i.e. they represent the same\n /// list of elements). Uses `equal` to compare elements in the arrays.\n ///\n /// ```motoko include=import\n /// // Use the equal function from the Nat module to compare Nats\n /// import {equal} \"mo:base/Nat\";\n ///\n /// let array1 = [0, 1, 2, 3];\n /// let array2 = [0, 1, 2, 3];\n /// Array.equal(array1, array2, equal)\n /// ```\n ///\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func equal<X>(array1 : [X], array2 : [X], equal : (X, X) -> Bool) : Bool {\n let size1 = array1.size();\n let size2 = array2.size();\n if (size1 != size2) {\n return false;\n };\n var i = 0;\n while (i < size1) {\n if (not equal(array1[i], array2[i])) {\n return false;\n };\n i += 1;\n };\n return true;\n };\n\n /// Returns the first value in `array` for which `predicate` returns true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// ```motoko include=import\n /// let array = [1, 9, 4, 8];\n /// Array.find<Nat>(array, func x = x > 8)\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func find<X>(array : [X], predicate : X -> Bool) : ?X {\n for (element in array.vals()) {\n if (predicate element) {\n return ?element;\n }\n };\n return null;\n };\n\n /// Create a new array by appending the values of `array1` and `array2`.\n /// @deprecated `Array.append` copies its arguments and has linear complexity;\n /// when used in a loop, consider using a `Buffer`, and `Buffer.append`, instead.\n ///\n /// ```motoko include=import\n /// let array1 = [1, 2, 3];\n /// let array2 = [4, 5, 6];\n /// Array.append<Nat>(array1, array2)\n /// ```\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(size1 + size2)\n public func append<X>(array1 : [X], array2 : [X]) : [X] {\n let size1 = array1.size();\n let size2 = array2.size();\n Prim.Array_tabulate<X>(size1 + size2, func i {\n if (i < size1) {\n array1[i];\n } else {\n array2[i - size1];\n };\n });\n };\n\n // FIXME this example stack overflows. Should test with new implementation of sortInPlace\n /// Sorts the elements in the array according to `compare`.\n /// Sort is deterministic and stable.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 6];\n /// Array.sort(array, Nat.compare)\n /// ```\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func sort<X>(array : [X], compare : (X, X) -> Order.Order) : [X] {\n let temp : [var X] = thaw(array);\n sortInPlace(temp, compare);\n freeze(temp)\n };\n\n /// Sorts the elements in the array, __in place__, according to `compare`.\n /// Sort is deterministic, stable, and in-place.\n ///\n /// ```motoko include=import\n ///\n /// import {compare} \"mo:base/Nat\";\n ///\n /// let array = [var 4, 2, 6];\n /// Array.sortInPlace(array, compare);\n /// array\n /// ```\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func sortInPlace<X>(array : [var X], compare : (X, X) -> Order.Order) {\n // Stable merge sort in a bottom-up iterative style. Same algorithm as the sort in Buffer.\n let size = array.size();\n if (size == 0) {\n return;\n };\n let scratchSpace = Prim.Array_init<X>(size, array[0]);\n\n let sizeDec = size - 1 : Nat;\n var currSize = 1; // current size of the subarrays being merged\n // when the current size == size, the array has been merged into a single sorted array\n while (currSize < size) {\n var leftStart = 0; // selects the current left subarray being merged\n while (leftStart < sizeDec) {\n let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {\n leftStart + currSize - 1;\n } else { sizeDec };\n let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {\n leftStart + (2 * currSize) - 1;\n } else { sizeDec };\n\n // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]\n var left = leftStart;\n var right = mid + 1;\n var nextSorted = leftStart;\n while (left < mid + 1 and right < rightEnd + 1) {\n let leftElement = array[left];\n let rightElement = array[right];\n switch (compare(leftElement, rightElement)) {\n case (#less or #equal) {\n scratchSpace[nextSorted] := leftElement;\n left += 1;\n };\n case (#greater) {\n scratchSpace[nextSorted] := rightElement;\n right += 1;\n };\n };\n nextSorted += 1;\n };\n while (left < mid + 1) {\n scratchSpace[nextSorted] := array[left];\n nextSorted += 1;\n left += 1;\n };\n while (right < rightEnd + 1) {\n scratchSpace[nextSorted] := array[right];\n nextSorted += 1;\n right += 1;\n };\n\n // Copy over merged elements\n var i = leftStart;\n while (i < rightEnd + 1) {\n array[i] := scratchSpace[i];\n i += 1;\n };\n\n leftStart += 2 * currSize;\n };\n currSize *= 2;\n };\n };\n\n /// Creates a new array by reversing the order of elements in `array`.\n ///\n /// ```motoko include=import\n ///\n /// let array = [10, 11, 12];\n ///\n /// Array.reverse(array)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func reverse<X>(array : [X]) : [X] {\n let size = array.size();\n Prim.Array_tabulate<X>(size, func i = array[size - i - 1]);\n };\n\n /// Creates a new array by applying `f` to each element in `array`. `f` \"maps\"\n /// each element it is applied to of type `X` to an element of type `Y`.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n ///\n /// let array = [0, 1, 2, 3];\n /// Array.map<Nat, Nat>(array, func x = x * 3)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func map<X, Y>(array : [X], f : X -> Y) : [Y] =\n Prim.Array_tabulate<Y>(array.size(), func i = f(array[i]));\n\n /// Creates a new array by applying `predicate` to every element\n /// in `array`, retaining the elements for which `predicate` returns true.\n ///\n /// ```motoko include=import\n /// let array = [4, 2, 6, 1, 5];\n /// let evenElements = Array.filter<Nat>(array, func x = x % 2 == 0);\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func filter<X>(array : [X], predicate : X -> Bool) : [X] {\n var count = 0;\n let keep =\n Prim.Array_tabulate<Bool>(\n array.size(),\n func i {\n if (predicate(array[i])) {\n count += 1;\n true\n } else {\n false\n }\n }\n );\n var nextKeep = 0;\n Prim.Array_tabulate<X>(\n count,\n func _ {\n while (not keep[nextKeep]) {\n nextKeep += 1;\n };\n nextKeep += 1;\n array[nextKeep - 1];\n }\n )\n };\n\n // FIXME the arguments ordering to the higher order function are flipped\n // between this and the buffer class\n // probably can't avoid breaking changes at some point\n /// Creates a new array by applying `f` to each element in `array` and its index.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n ///\n /// let array = [10, 10, 10, 10];\n /// Array.mapEntries<Nat, Nat>(array, func (i, x) = i * x)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapEntries<X, Y>(array : [X], f : (X, Nat) -> Y) : [Y] =\n Prim.Array_tabulate<Y>(array.size(), func i = f(array[i], i));\n\n /// Creates a new array by applying `f` to each element in `array`,\n /// and keeping all non-null elements. The ordering is retained.\n ///\n /// ```motoko include=import\n /// import {toText} \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 0, 1];\n /// let newArray =\n /// Array.mapFilter<Nat, Text>( // mapping from Nat to Text values\n /// array,\n /// func x = if (x == 0) { null } else { ?toText(100 / x) } // can't divide by 0, so return null\n /// );\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapFilter<X, Y>(array : [X], f : X -> ?Y) : [Y] {\n var count = 0;\n let options =\n Prim.Array_tabulate<?Y>(\n array.size(),\n func i {\n let result = f(array[i]);\n switch (result) {\n case (?element) {\n count += 1;\n result\n };\n case null {\n null\n }\n }\n }\n );\n\n var nextSome = 0;\n Prim.Array_tabulate<Y>(\n count,\n func _ {\n while (Option.isNull(options[nextSome])) {\n nextSome += 1;\n };\n nextSome += 1;\n switch(options[nextSome - 1]) {\n case(?element) element;\n case null {\n Prim.trap \"Malformed array in mapFilter\"\n }\n }\n }\n )\n };\n\n /// Creates a new array by applying `f` to each element in `array`.\n /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n /// returns an `#ok` containing the new array.\n ///\n /// ```motoko include=import\n /// let array = [4, 3, 2, 1, 0];\n /// // divide 100 by every element in the array\n /// Array.mapResult<Nat, Nat, Text>(array, func x {\n /// if (x > 0) {\n /// #ok(100 / x)\n /// } else {\n /// #err \"Cannot divide by zero\"\n /// }\n /// })\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapResult<X, Y, E>(array : [X], f : X -> Result.Result<Y, E>) : Result.Result<[Y], E> {\n let size = array.size();\n var target : [var Y] = [var];\n var isInit = false;\n\n var error : ?Result.Result<[Y], E> = null;\n let results = Prim.Array_tabulate<?Y>(size, func i {\n switch (f(array[i])) {\n case (#ok element) {\n ?element\n };\n case (#err e) {\n switch (error) {\n case null { // only take the first error\n error := ?(#err e);\n };\n case _ { };\n };\n null\n }\n }\n });\n\n switch error {\n case null {\n // unpack the option\n #ok(map<?Y, Y>(results, func element {\n switch element {\n case (?element) {\n element\n };\n case null {\n Prim.trap \"Malformed array in mapResults\"\n };\n }\n }));\n };\n case (?error) {\n error\n };\n }\n };\n\n /// Creates a new array by applying `k` to each element in `array`,\n /// and concatenating the resulting arrays in order. This operation\n /// is similar to what in other functional languages is known as monadic bind.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:base/Nat\";\n ///\n /// let array = [1, 2, 3, 4];\n /// Array.chain<Nat, Int>(array, func x = [x, -x])\n ///\n /// ```\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `k` runs in O(1) time and space.\n public func chain<X, Y>(array : [X], k : X -> [Y]) : [Y] {\n var flatSize = 0;\n let subArrays = Prim.Array_tabulate<[Y]>(array.size(), func i {\n let subArray = k(array[i]);\n flatSize += subArray.size();\n subArray\n });\n // could replace with a call to flatten,\n // but it would require an extra pass (to compute `flatSize`)\n var outer = 0;\n var inner = 0;\n Prim.Array_tabulate<Y>(flatSize, func _ {\n let subArray = subArrays[outer];\n let element = subArray[inner];\n inner += 1;\n if (inner == subArray.size()) {\n inner := 0;\n outer += 1;\n };\n element\n })\n };\n\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// ```motoko include=import\n /// import {add} \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 0, 1];\n /// let sum =\n /// Array.foldLeft<Nat, Nat>(\n /// array,\n /// 0, // start the sum at 0\n /// func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!\n /// );\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldLeft<X, A>(array : [X], base : A, combine : (A, X) -> A) : A {\n var accumulation = base;\n\n for (element in array.vals()) {\n accumulation := combine(accumulation, element);\n };\n\n accumulation\n };\n\n // FIXME the type arguments are reverse order from Buffer\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// ```motoko include=import\n /// import {toText} \"mo:base/Nat\";\n ///\n /// let array = [1, 9, 4, 8];\n /// let bookTitle = Array.foldRight<Nat, Text>(array, \"\", func(x, acc) = toText(x) # acc);\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldRight<X, A>(array : [X], base : A, combine : (X, A) -> A) : A {\n var accumulation = base;\n let size = array.size();\n\n var i = size;\n while (i > 0) {\n i -= 1;\n accumulation := combine(array[i], accumulation);\n };\n\n accumulation;\n };\n\n /// Flattens the array of arrays into a single array. Retains the original\n /// ordering of the elements.\n ///\n /// ```motoko include=import\n ///\n /// let arrays = [[0, 1, 2], [2, 3], [], [4]];\n /// Array.flatten<Nat>(arrays)\n /// ```\n ///\n /// Runtime: O(number of elements in array)\n ///\n /// Space: O(number of elements in array)\n public func flatten<X>(arrays : [[X]]) : [X] {\n var flatSize = 0;\n for (subArray in arrays.vals()) {\n flatSize += subArray.size()\n };\n\n var outer = 0;\n var inner = 0;\n Prim.Array_tabulate<X>(flatSize, func _ {\n while (inner == arrays[outer].size()) {\n inner := 0;\n outer += 1;\n };\n let element = arrays[outer][inner];\n inner += 1;\n element\n })\n };\n\n /// Create an array containing a single value.\n ///\n /// ```motoko include=import\n /// Array.make(2)\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func make<X>(element : X) : [X] = [element];\n\n /// Returns an Iterator (`Iter`) over the elements of `array`.\n /// Iterator provides a single method `next()`, which returns\n /// elements in order, or `null` when out of elements to iterate over.\n ///\n /// NOTE: You can also use `array.vals()` instead of this function. See example\n /// below.\n ///\n /// ```motoko include=import\n ///\n /// let array = [10, 11, 12];\n ///\n /// var sum = 0;\n /// for (element in array.vals()) {\n /// sum += element;\n /// };\n /// sum\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func vals<X>(array : [X]) : I.Iter<X> = array.vals();\n\n /// Returns an Iterator (`Iter`) over the indices of `array`.\n /// Iterator provides a single method `next()`, which returns\n /// indices in order, or `null` when out of index to iterate over.\n ///\n /// NOTE: You can also use `array.keys()` instead of this function. See example\n /// below.\n ///\n /// ```motoko include=import\n ///\n /// let array = [10, 11, 12];\n ///\n /// var sum = 0;\n /// for (element in array.keys()) {\n /// sum += element;\n /// };\n /// sum\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func keys<X>(array : [X]) : I.Iter<Nat> = array.keys();\n}\n"},"Char.mo":{"content":"/// Characters\nimport Prim \"mo:⛔\";\nmodule {\n\n /// Characters represented as Unicode code points.\n public type Char = Prim.Types.Char;\n\n /// Convert character `c` to a word containing its Unicode scalar value.\n public let toNat32 : (c : Char) -> Nat32 = Prim.charToNat32;\n\n /// Convert `w` to a character.\n /// Traps if `w` is not a valid Unicode scalar value.\n /// Value `w` is valid if, and only if, `w < 0xD800 or (0xE000 <= w and w <= 0x10FFFF)`.\n public let fromNat32 : (w : Nat32) -> Char = Prim.nat32ToChar;\n\n /// Convert character `c` to single character text.\n public let toText : (c : Char) -> Text = Prim.charToText;\n\n // Not exposed pending multi-char implementation.\n private let toUpper : (c : Char) -> Char = Prim.charToUpper;\n\n // Not exposed pending multi-char implementation.\n private let toLower : (c : Char) -> Char = Prim.charToLower;\n\n /// Returns `true` when `c` is a decimal digit between `0` and `9`, otherwise `false`.\n public func isDigit(c : Char) : Bool {\n Prim.charToNat32(c) -% Prim.charToNat32('0') <= (9 : Nat32)\n };\n\n /// Returns the Unicode _White_Space_ property of `c`.\n public let isWhitespace : (c : Char) -> Bool = Prim.charIsWhitespace;\n\n /// Returns the Unicode _Lowercase_ property of `c`.\n public let isLowercase : (c : Char) -> Bool = Prim.charIsLowercase;\n\n /// Returns the Unicode _Uppercase_ property of `c`.\n public let isUppercase : (c : Char) -> Bool = Prim.charIsUppercase;\n\n /// Returns the Unicode _Alphabetic_ property of `c`.\n public let isAlphabetic : (c : Char) -> Bool = Prim.charIsAlphabetic;\n\n /// Returns `x == y`.\n public func equal(x : Char, y : Char) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Char, y : Char) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Char, y : Char) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Char, y : Char) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Char, y : Char) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Char, y : Char) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Char, y : Char) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n}\n"},"Bool.mo":{"content":"/// Boolean type and operations.\n///\n/// While boolean operators `_ and _` and `_ or _` are short-circuiting,\n/// avoiding computation of the right argument when possible, the functions\n/// `logand(_, _)` and `logor(_, _)` are *strict* and will always evaluate *both*\n/// of their arguments.\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// Booleans with constants `true` and `false`.\n public type Bool = Prim.Types.Bool;\n\n /// Conversion.\n public func toText(x : Bool) : Text {\n if x { \"true\" } else { \"false\" }\n };\n\n /// Returns `x and y`.\n public func logand(x : Bool, y : Bool) : Bool { x and y };\n\n /// Returns `x or y`.\n public func logor(x : Bool, y : Bool) : Bool { x or y };\n\n /// Returns exclusive or of `x` and `y`, `x != y`.\n public func logxor(x : Bool, y : Bool) : Bool {\n x != y\n };\n\n /// Returns `not x`.\n public func lognot(x : Bool) : Bool { not x };\n\n /// Returns `x == y`.\n public func equal(x : Bool, y : Bool) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Bool, y : Bool) : Bool { x != y };\n\n /// Returns the order of `x` and `y`, where `false < true`.\n public func compare(x : Bool, y : Bool) : {#less; #equal; #greater } {\n if (x == y) { #equal } else if (x) { #greater } else { #less }\n };\n\n}\n"},"Blob.mo":{"content":"/// Binary blobs\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// An immutable, possibly empty sequence of bytes.\n /// Given `b : Blob`:\n ///\n /// * `b.size() : Nat` returns the number of bytes in the blob;\n /// * `b.vals() : Iter.Iter<Nat8>` returns an iterator to enumerate the bytes of the blob.\n ///\n /// (Direct indexing of Blobs is not yet supported.)\n public type Blob = Prim.Types.Blob;\n\n /// Returns a (non-cryptographic) hash of 'b'\n public let hash : (b : Blob) -> Nat32 = Prim.hashBlob;\n\n /// Returns `x == y`.\n public func equal(x : Blob, y : Blob) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Blob, y : Blob) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Blob, y : Blob) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Blob, y : Blob) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Blob, y : Blob) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Blob, y : Blob) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Blob, y : Blob) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Creates a blob from an array of bytes, by copying each element.\n public let fromArray : [Nat8] -> Blob = Prim.arrayToBlob;\n\n /// Creates a blob from a mutable array of bytes, by copying each element.\n public let fromArrayMut : [var Nat8] -> Blob = Prim.arrayMutToBlob;\n\n /// Creates an array of bytes from a blob, by copying each element.\n public let toArray : Blob -> [Nat8] = Prim.blobToArray;\n\n /// Creates a mutable array of bytes from a blob, by copying each element.\n public let toArrayMut : Blob -> [var Nat8] = Prim.blobToArrayMut;\n\n}\n"},"CertifiedData.mo":{"content":"/// Certified data.\n///\n/// The Internet Computer allows canister smart contracts to store a small amount of data during\n/// update method processing so that during query call processing, the canister can obtain\n/// a certificate about that data.\n///\n/// This module provides a _low-level_ interface to this API, aimed at advanced\n/// users and library implementors. See the Internet Computer Functional\n/// Specification and corresponding documentation for how to use this to make query\n/// calls to your canister tamperproof.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Set the certified data.\n ///\n /// Must be called from an update method, else traps.\n /// Must be passed a blob of at most 32 bytes, else traps.\n public let set : (data : Blob) -> () = Prim.setCertifiedData;\n\n /// Gets a certificate\n ///\n /// Returns `null` if no certificate is available, e.g. when processing an\n /// update call or inter-canister call. This returns a non-`null` value only\n /// when processing a query call.\n public let getCertificate : () -> ?Blob = Prim.getCertificate;\n\n}\n"},"Debug.mo":{"content":"/// Debugging aids\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// `print(t)` emits text `t` to the debug output stream.\n /// How this stream is stored or displayed depends on the\n /// execution environment.\n public let print : Text -> () = Prim.debugPrint;\n\n /// `trap(t)` traps execution with a user-provided message.\n public let trap : Text -> None = Prim.trap;\n\n\n}\n"},"Deque.mo":{"content":"/// Functions for persistent, double-ended queues.\n\nimport List \"List\";\nimport P \"Prelude\";\n\nmodule {\n type List<T> = List.List<T>;\n\n /// Double-ended queue\n public type Deque<T> = (List<T>, List<T>);\n\n /// Empty queue\n public func empty<T> () : Deque<T> { (List.nil(), List.nil()); };\n\n /// True when the queue is empty\n public func isEmpty<T>(q : Deque<T>) : Bool {\n switch q {\n case (f, r) { List.isNil(f) and List.isNil(r) };\n }\n };\n\n func check<T>(q : Deque<T>) : Deque<T> {\n switch q {\n case (null, r) { let (a,b) = List.split(List.size(r) / 2, r); (List.reverse(b), a) };\n case (f, null) { let (a,b) = List.split(List.size(f) / 2, f); (a, List.reverse(b)) };\n case q { q };\n }\n };\n\n /// Insert a new element on the front end of the queue\n public func pushFront<T>(q : Deque<T>, x : T) : Deque<T> {\n check (List.push(x, q.0), q.1);\n };\n\n /// Inspect the (optional) first element on the front end of the queue\n public func peekFront<T>(q : Deque<T>) : ?T {\n switch q {\n case (?(x, f), r) { ?x };\n case (null, ?(x, r)) { ?x };\n case _ { null };\n };\n };\n\n /// Remove the first element on the front end of the queue; Returns null when empty.\n public func popFront<T>(q : Deque<T>) : ?(T, Deque<T>) {\n switch q {\n case (?(x, f), r) { ?(x, check(f, r)) };\n case (null, ?(x, r)) { ?(x, check(null, r)) };\n case _ { null };\n };\n };\n\n /// Insert a new element on the back end of the queue\n public func pushBack<T>(q : Deque<T>, x : T) : Deque<T> {\n check (q.0, List.push(x, q.1));\n };\n\n /// Inspect the (optional) first element on the back end of the queue\n public func peekBack<T>(q : Deque<T>) : ?T {\n switch q {\n case (f, ?(x, r)) { ?x };\n case (?(x, r), null) { ?x };\n case _ { null };\n };\n };\n\n /// Remove the first element on the back end of the queue; Returns null when empty.\n public func popBack<T>(q : Deque<T>) : ?(Deque<T>, T) {\n switch q {\n case (f, ?(x, r)) { ?(check(f, r), x) };\n case (?(x, f), null) { ?(check(f, null), x) };\n case _ { null };\n };\n };\n};\n"},"ExperimentalCycles.mo":{"content":"/// Managing cycles\n///\n/// Usage of the Internet Computer is measured, and paid for, in _cycles_.\n/// This library provides imperative operations for observing cycles, transferring cycles and\n/// observing refunds of cycles.\n///\n/// **WARNING:** This low-level API is **experimental** and likely to change or even disappear.\n/// Dedicated syntactic support for manipulating cycles may be added to the language in future, obsoleting this library.\n///\n/// **NOTE:** Since cycles measure computational resources, the value of\n/// `balance()` can change from one call to the next.\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// Returns the actor's current balance of cycles as `amount`.\n public let balance : () -> (amount : Nat) = Prim.cyclesBalance;\n\n /// Returns the currently available `amount` of cycles.\n /// The amount available is the amount received in the current call,\n /// minus the cumulative amount `accept`ed by this call.\n /// On exit from the current shared function or async expression via `return` or `throw`\n /// any remaining available amount is automatically\n /// refunded to the caller/context.\n public let available : () -> (amount : Nat) = Prim.cyclesAvailable;\n\n /// Transfers up to `amount` from `available()` to `balance()`.\n /// Returns the amount actually transferred, which may be less than\n /// requested, for example, if less is available, or if canister balance limits are reached.\n public let accept : (amount : Nat) -> (accepted : Nat) = Prim.cyclesAccept;\n\n /// Indicates additional `amount` of cycles to be transferred in\n /// the next call, that is, evaluation of a shared function call or\n /// async expression.\n /// Traps if the current total would exceed 2^128 cycles.\n /// Upon the call, but not before, the total amount of cycles ``add``ed since\n /// the last call is deducted from `balance()`.\n /// If this total exceeds `balance()`, the caller traps, aborting the call.\n ///\n /// **Note**: the implicit register of added amounts is reset to zero on entry to\n /// a shared function and after each shared function call or resume from an await.\n public let add : (amount : Nat) -> () = Prim.cyclesAdd;\n\n /// Reports `amount` of cycles refunded in the last `await` of the current\n /// context, or zero if no await has occurred yet.\n /// Calling `refunded()` is solely informational and does not affect `balance()`.\n /// Instead, refunds are automatically added to the current balance,\n /// whether or not `refunded` is used to observe them.\n public let refunded : () -> (amount : Nat) = Prim.cyclesRefunded;\n\n}\n"},"Error.mo":{"content":"/// Error values and inspection.\n///\n/// The `Error` type is the argument to `throw`, parameter of `catch`.\n/// The `Error` type is opaque.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Error values resulting from `async` computations\n public type Error = Prim.Types.Error;\n\n /// Error codes (user and system), where module `Prim` defines:\n /// ```motoko\n /// type ErrorCode = {\n /// // Fatal error.\n /// #system_fatal;\n /// // Transient error.\n /// #system_transient;\n /// // Destination invalid.\n /// #destination_invalid;\n /// // Explicit reject by canister code.\n /// #canister_reject;\n /// // Canister trapped.\n /// #canister_error;\n /// // Future error code (with unrecognized numeric code)\n /// #future : Nat32;\n /// };\n /// ```\n public type ErrorCode = Prim.ErrorCode;\n\n /// Create an error from message `m` with code #canister_reject.\n public let reject : (m : Text) -> Error = Prim.error;\n\n /// Returns the code of an error `e`.\n public let code : (e : Error) -> ErrorCode = Prim.errorCode;\n\n /// Returns the message of an error `e`.\n public let message : (e : Error) -> Text = Prim.errorMessage;\n\n}\n"},"ExperimentalInternetComputer.mo":{"content":"/// Low-level interface to the Internet Computer.\n///\n/// **WARNING:** This low-level API is **experimental** and likely to change or even disappear.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Calls ``canister``'s update or query function, `name`, with the binary contents of `data` as IC argument.\n /// Returns the response to the call, an IC _reply_ or _reject_, as a Motoko future:\n ///\n /// * The message data of an IC reply determines the binary contents of `reply`.\n /// * The error code and textual message data of an IC reject determines the future's `Error` value.\n ///\n /// Note: `call` is an asynchronous function and can only be applied in an asynchronous context.\n public let call : (canister : Principal, name : Text, data : Blob) ->\n async (reply : Blob) = Prim.call_raw;\n\n /// Given computation, `comp`, counts the number of actual and (for IC system calls) notional WebAssembly\n /// instructions performed during the execution of `comp()`.\n ///\n /// More precisely, returns the difference between the state of the IC instruction counter (_performance counter_ `0`) before and after executing `comp()`\n /// (see [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter)).\n ///\n /// NB: `countInstructions(comp)` will _not_ account for any deferred garbage collection costs incurred by `comp()`.\n public func countInstructions(comp : () -> ()) : Nat64 {\n let init = Prim.performanceCounter(0);\n let pre = Prim.performanceCounter(0);\n comp();\n let post = Prim.performanceCounter(0);\n // performance_counter costs around 200 extra instructions, we perform an empty measurement to decide the overhead\n let overhead = pre - init;\n post - pre - overhead\n }\n\n}\n"},"HashMap.mo":{"content":"/// Mutable hash map (aka Hashtable)\n///\n/// This module defines an imperative hash map (hash table), with a general key and value type.\n///\n/// It has a minimal object-oriented interface: `get`, `set`, `delete`, `count` and `entries`.\n///\n/// The class is parameterized by the key's equality and hash functions,\n/// and an initial capacity. However, as with the `Buffer` class, no array allocation\n/// happens until the first `set`.\n///\n/// Internally, table growth policy is very simple, for now:\n/// Double the current capacity when the expected bucket list size grows beyond a certain constant.\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport A \"Array\";\nimport Hash \"Hash\";\nimport Iter \"Iter\";\nimport AssocList \"AssocList\";\nimport Nat32 \"Nat32\";\n\nmodule {\n\n\n // hash field avoids re-hashing the key when the array grows.\n type Key<K> = (Hash.Hash, K);\n\n // key-val list type\n type KVs<K, V> = AssocList.AssocList<Key<K>, V>;\n\n /// An imperative HashMap with a minimal object-oriented interface.\n /// Maps keys of type `K` to values of type `V`.\n public class HashMap<K, V>(\n initCapacity : Nat,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash) {\n\n var table : [var KVs<K, V>] = [var];\n var _count : Nat = 0;\n\n /// Returns the number of entries in this HashMap.\n public func size() : Nat = _count;\n\n /// Deletes the entry with the key `k`. Doesn't do anything if the key doesn't\n /// exist.\n public func delete(k : K) = ignore remove(k);\n\n func keyHash_(k : K) : Key<K> = (keyHash(k), k);\n\n func keyHashEq(k1 : Key<K>, k2 : Key<K>) : Bool { k1.0 == k2.0 and keyEq(k1.1, k2.1) };\n\n /// Removes the entry with the key `k` and returns the associated value if it\n /// existed or `null` otherwise.\n public func remove(k : K) : ?V {\n let m = table.size();\n if (m > 0) {\n let h = Prim.nat32ToNat(keyHash(k));\n let pos = h % m;\n let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(k), keyHashEq, null);\n table[pos] := kvs2;\n switch(ov){\n case null { };\n case _ { _count -= 1; }\n };\n ov\n } else {\n null\n };\n };\n\n /// Gets the entry with the key `k` and returns its associated value if it\n /// existed or `null` otherwise.\n public func get(k : K) : ?V {\n let h = Prim.nat32ToNat(keyHash(k));\n let m = table.size();\n let v = if (m > 0) {\n AssocList.find<Key<K>, V>(table[h % m], keyHash_(k), keyHashEq)\n } else {\n null\n };\n };\n\n /// Insert the value `v` at key `k`. Overwrites an existing entry with key `k`\n public func put(k : K, v : V) = ignore replace(k, v);\n\n /// Insert the value `v` at key `k` and returns the previous value stored at\n /// `k` or `null` if it didn't exist.\n public func replace(k : K, v : V) : ?V {\n if (_count >= table.size()) {\n let size =\n if (_count == 0) {\n if (initCapacity > 0) {\n initCapacity\n } else {\n 1\n }\n } else {\n table.size() * 2;\n };\n let table2 = A.init<KVs<K, V>>(size, null);\n for (i in table.keys()) {\n var kvs = table[i];\n label moveKeyVals : ()\n loop {\n switch kvs {\n case null { break moveKeyVals };\n case (?((k, v), kvsTail)) {\n let pos2 = Nat32.toNat(k.0) % table2.size(); // critical: uses saved hash. no re-hash.\n table2[pos2] := ?((k,v), table2[pos2]);\n kvs := kvsTail;\n };\n }\n };\n };\n table := table2;\n };\n let h = Prim.nat32ToNat(keyHash(k));\n let pos = h % table.size();\n let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(k), keyHashEq, ?v);\n table[pos] := kvs2;\n switch(ov){\n case null { _count += 1 };\n case _ {}\n };\n ov\n };\n\n /// An `Iter` over the keys.\n public func keys() : Iter.Iter<K>\n { Iter.map(entries(), func (kv : (K, V)) : K { kv.0 }) };\n\n /// An `Iter` over the values.\n public func vals() : Iter.Iter<V>\n { Iter.map(entries(), func (kv : (K, V)) : V { kv.1 }) };\n\n /// Returns an iterator over the key value pairs in this\n /// `HashMap`. Does _not_ modify the `HashMap`.\n public func entries() : Iter.Iter<(K, V)> {\n if (table.size() == 0) {\n object { public func next() : ?(K, V) { null } }\n }\n else {\n object {\n var kvs = table[0];\n var nextTablePos = 1;\n public func next () : ?(K, V) {\n switch kvs {\n case (?(kv, kvs2)) {\n kvs := kvs2;\n ?(kv.0.1, kv.1)\n };\n case null {\n if (nextTablePos < table.size()) {\n kvs := table[nextTablePos];\n nextTablePos += 1;\n next()\n } else {\n null\n }\n }\n }\n }\n }\n }\n };\n\n };\n\n /// clone cannot be an efficient object method,\n /// ...but is still useful in tests, and beyond.\n public func clone<K, V> (\n h : HashMap<K, V>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : HashMap<K, V> {\n let h2 = HashMap<K, V>(h.size(), keyEq, keyHash);\n for ((k,v) in h.entries()) {\n h2.put(k,v);\n };\n h2\n };\n\n /// Clone from any iterator of key-value pairs\n public func fromIter<K, V>(\n iter : Iter.Iter<(K, V)>,\n initCapacity : Nat,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : HashMap<K, V> {\n let h = HashMap<K, V>(initCapacity, keyEq, keyHash);\n for ((k, v) in iter) {\n h.put(k, v);\n };\n h\n };\n\n public func map<K, V1, V2>(\n h : HashMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n mapFn : (K, V1) -> V2,\n ) : HashMap<K, V2> {\n let h2 = HashMap<K, V2>(h.size(), keyEq, keyHash);\n for ((k, v1) in h.entries()) {\n let v2 = mapFn(k, v1);\n h2.put(k, v2);\n };\n h2\n };\n\n public func mapFilter<K, V1, V2>(\n h : HashMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n mapFn : (K, V1) -> ?V2,\n ) : HashMap<K, V2> {\n let h2 = HashMap<K, V2>(h.size(), keyEq, keyHash);\n for ((k, v1) in h.entries()) {\n switch (mapFn(k, v1)) {\n case null { };\n case (?v2) {\n h2.put(k, v2);\n };\n }\n };\n h2\n };\n\n}\n"},"Float.mo":{"content":"/// 64-bit Floating-point numbers\n\nimport Prim \"mo:⛔\";\nimport Int \"Int\";\n\nmodule {\n\n /// 64-bit floating point numbers.\n public type Float = Prim.Types.Float;\n\n /// Ratio of the circumference of a circle to its diameter.\n public let pi : Float = 3.14159265358979323846; // taken from musl math.h\n\n /// Base of the natural logarithm.\n public let e : Float = 2.7182818284590452354; // taken from musl math.h\n\n /// Returns the absolute value of `x`.\n public let abs : (x : Float) -> Float = Prim.floatAbs;\n\n /// Returns the square root of `x`.\n public let sqrt : (x : Float) -> Float = Prim.floatSqrt;\n\n /// Returns the smallest integral float greater than or equal to `x`.\n public let ceil : (x : Float) -> Float = Prim.floatCeil;\n\n /// Returns the largest integral float less than or equal to `x`.\n public let floor : (x : Float) -> Float = Prim.floatFloor;\n\n /// Returns the nearest integral float not greater in magnitude than `x`.\n public let trunc : (x : Float) -> Float = Prim.floatTrunc;\n\n /// Returns the nearest integral float to `x`.\n public let nearest : (x : Float) -> Float = Prim.floatNearest;\n\n /// Returns `x` if `x` and `y` have same sign, otherwise `x` with negated sign.\n public let copySign : (x : Float, y : Float) -> Float = Prim.floatCopySign;\n\n /// Returns the smaller value of `x` and `y`.\n public let min : (x : Float, y : Float) -> Float = Prim.floatMin;\n\n /// Returns the larger value of `x` and `y`.\n public let max : (x : Float, y : Float) -> Float = Prim.floatMax;\n\n /// Returns the sine of the radian angle `x`.\n public let sin : (x : Float) -> Float = Prim.sin;\n\n /// Returns the cosine of the radian angle `x`.\n public let cos : (x : Float) -> Float = Prim.cos;\n\n /// Returns the tangent of the radian angle `x`.\n public let tan : (x : Float) -> Float = Prim.tan;\n\n /// Returns the arc sine of `x` in radians.\n public let arcsin: (x : Float) -> Float = Prim.arcsin;\n\n /// Returns the arc cosine of `x` in radians.\n public let arccos : (x : Float) -> Float = Prim.arccos;\n\n /// Returns the arc tangent of `x` in radians.\n public let arctan : (x : Float) -> Float = Prim.arctan;\n\n /// Given `(y,x)`, returns the arc tangent in radians of `y/x` based on the signs of both values to determine the correct quadrant.\n public let arctan2 : (y : Float, x : Float) -> Float = Prim.arctan2;\n\n /// Returns the value of `e` raised to the `x`-th power.\n public let exp : (x : Float) -> Float = Prim.exp;\n\n /// Returns the natural logarithm (base-`e`) of `x`.\n public let log : (x : Float) -> Float = Prim.log;\n\n /// Formatting. `format(fmt, x)` formats `x` to `Text` according to the\n /// formatting directive `fmt`, which can take one of the following forms:\n ///\n /// * `#fix prec` as fixed-point format with `prec` digits\n /// * `#exp prec` as exponential format with `prec` digits\n /// * `#gen prec` as generic format with `prec` digits\n /// * `#hex prec` as hexadecimal format with `prec` digits\n /// * `#exact` as exact format that can be decoded without loss.\n public func format\n (fmt : { #fix : Nat8; #exp : Nat8; #gen : Nat8; #hex : Nat8; #exact }, x : Float) : Text =\n switch fmt {\n case (#fix(prec)) { Prim.floatToFormattedText(x, prec, 0) };\n case (#exp(prec)) { Prim.floatToFormattedText(x, prec, 1) };\n case (#gen(prec)) { Prim.floatToFormattedText(x, prec, 2) };\n case (#hex(prec)) { Prim.floatToFormattedText(x, prec, 3) };\n case (#exact) { Prim.floatToFormattedText(x, 17, 2) };\n };\n\n /// Conversion to Text. Use `format(fmt, x)` for more detailed control.\n public let toText : Float -> Text = Prim.floatToText;\n\n /// Conversion to Int64 by truncating Float, equivalent to `toInt64(trunc(f))`\n public let toInt64 : Float -> Int64 = Prim.floatToInt64;\n\n /// Conversion from Int64.\n public let fromInt64 : Int64 -> Float = Prim.int64ToFloat;\n\n /// Conversion to Int.\n public let toInt : Float -> Int = Prim.floatToInt;\n\n /// Conversion from Int. May result in `Inf`.\n public let fromInt : Int -> Float = Prim.intToFloat;\n\n /// Returns `x == y`.\n public func equal(x : Float, y : Float) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Float, y : Float) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Float, y : Float) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Float, y : Float) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Float, y : Float) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Float, y : Float) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Float, y : Float) : { #less; #equal; #greater} {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x` .\n public func neq(x : Float) : Float { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n public func add(x : Float, y : Float) : Float { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n public func sub(x : Float, y : Float) : Float { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n public func mul(x : Float, y : Float) : Float { x * y };\n\n /// Returns the division of `x` by `y`, `x / y`.\n public func div(x : Float, y : Float) : Float { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n public func rem(x : Float, y : Float) : Float { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n public func pow(x : Float, y : Float) : Float { x ** y };\n\n};\n"},"Func.mo":{"content":"/// Functions on functions\n///\n/// (Most commonly used when programming in functional style using higher-order\n/// functions.)\n\nmodule {\n\n /// The composition of two functions `f` and `g` is a function that applies `g` and then `f`.\n ///\n /// ```\n /// compose(f, g)(x) = f(g(x))\n /// ```\n public func compose<A, B, C>(f : B -> C, g : A -> B) : A -> C {\n func (x : A) : C {\n f(g(x));\n };\n };\n\n /// The `identity` function returns its argument.\n /// ```motoko\n /// import Func \"mo:base/Func\";\n /// assert(Func.identity(10) == 10);\n /// assert(Func.identity(true) == true);\n /// ```\n public func identity<A>(x : A) : A = x;\n\n /// The const function is a _curried_ function that accepts an argument `x`,\n /// and then returns a function that discards its argument and always returns\n /// the `x`.\n ///\n /// ```motoko\n /// import Func \"mo:base/Func\";\n /// assert(Func.const<Nat, Text>(10)(\"hello\") == 10);\n /// assert(Func.const<Bool, Nat>(true)(20) == true);\n /// ```\n public func const<A, B>(x : A) : B -> A =\n func (_) = x;\n}\n"},"Int32.mo":{"content":"/// 32-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 32-bit signed integers.\n public type Int32 = Prim.Types.Int32;\n\n /// Conversion.\n public let toInt : Int32 -> Int = Prim.int32ToInt;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromInt : Int -> Int32 = Prim.intToInt32;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Int32 = Prim.intToInt32Wrap;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromNat32 : Nat32 -> Int32 = Prim.nat32ToInt32;\n\n /// Conversion. Wraps on overflow/underflow.\n public let toNat32 : Int32 -> Nat32 = Prim.int32ToNat32;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Int32) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`. Traps when `x = -2^31`.\n public func abs(x : Int32) : Int32 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int32, y : Int32) : Int32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Int32, y : Int32) : Int32 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Int32, y : Int32) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int32, y : Int32) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int32, y : Int32) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int32, y : Int32) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int32, y : Int32) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int32, y : Int32) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int32, y : Int32) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`. Traps on overflow.\n public func neg(x : Int32) : Int32 { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Int32, y : Int32) : Int32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Int32, y : Int32) : Int32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Int32, y : Int32) : Int32 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int32, y : Int32) : Int32 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int32, y : Int32) : Int32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Int32, y : Int32) : Int32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Int32, y : Int32) : Int32 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Int32, y : Int32) : Int32 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Int32, y : Int32) : Int32 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Int32, y : Int32) : Int32 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Int32, y : Int32) : Int32 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Int32, y : Int32) : Int32 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Int32, y : Int32) : Int32 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Int32, y : Int32) : Int32 { x <>> y };\n\n /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n public func bittest(x : Int32, p : Nat) : Bool {\n Prim.btstInt32(x, Prim.intToInt32(p));\n };\n\n /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n public func bitset(x : Int32, p : Nat) : Int32 {\n x | (1 << Prim.intToInt32(p));\n };\n\n /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n public func bitclear(x : Int32, p : Nat) : Int32 {\n x & ^(1 << Prim.intToInt32(p));\n };\n\n /// Returns the value of flipping bit `p mod 16` in `x`.\n public func bitflip(x : Int32, p : Nat) : Int32 {\n x ^ (1 << Prim.intToInt32(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Int32) -> Int32 = Prim.popcntInt32;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Int32) -> Int32 = Prim.clzInt32;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Int32) -> Int32 = Prim.ctzInt32;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Int32, y : Int32) : Int32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Int32, y : Int32) : Int32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Int32, y : Int32) : Int32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n public func powWrap(x : Int32, y : Int32) : Int32 { x **% y };\n\n}\n"},"Iter.mo":{"content":"/// Iterators\n\nimport Array \"Array\";\nimport Buffer \"Buffer\";\nimport List \"List\";\nimport Order \"Order\";\n\nmodule {\n\n /// An iterator that produces values of type `T`. Calling `next` returns\n /// `null` when iteration is finished.\n ///\n /// Iterators are inherently stateful. Calling `next` \"consumes\" a value from\n /// the Iterator that cannot be put back, so keep that in mind when sharing\n /// iterators between consumers.\n ///\n /// An iterater `i` can be iterated over using\n /// ```\n /// for (x in i) {\n /// …do something with x…\n /// }\n /// ```\n public type Iter<T> = { next : () -> ?T };\n\n /// Creates an iterator that produces all `Nat`s from `x` to `y` including\n /// both of the bounds.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// assert(?1 == iter.next());\n /// assert(?2 == iter.next());\n /// assert(?3 == iter.next());\n /// assert(null == iter.next());\n /// ```\n public class range(x : Nat, y : Int) {\n var i = x;\n public func next() : ?Nat { if (i > y) { null } else {let j = i; i += 1; ?j} };\n };\n\n /// Like `range` but produces the values in the opposite\n /// order.\n public class revRange(x : Int, y : Int) {\n var i = x;\n public func next() : ?Int { if (i < y) { null } else {let j = i; i -= 1; ?j} };\n };\n\n /// Calls a function `f` on every value produced by an iterator and discards\n /// the results. If you're looking to keep these results use `map` instead.\n ///\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// var sum = 0;\n /// Iter.iterate<Nat>(Iter.range(1, 3), func(x, _index) {\n /// sum += x;\n /// });\n /// assert(6 == sum)\n /// ```\n public func iterate<A>(\n xs : Iter<A>,\n f : (A, Nat) -> ()\n ) {\n var i = 0;\n label l loop {\n switch (xs.next()) {\n case (?next) {\n f(next, i);\n };\n case (null) {\n break l;\n };\n };\n i += 1;\n continue l;\n };\n };\n\n /// Consumes an iterator and counts how many elements were produced\n /// (discarding them in the process).\n public func size<A>(xs : Iter<A>) : Nat {\n var len = 0;\n iterate<A>(xs, func (x, i) { len += 1; });\n len;\n };\n\n /// Takes a function and an iterator and returns a new iterator that lazily applies\n /// the function to every element produced by the argument iterator.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// let mappedIter = Iter.map(iter, func (x : Nat) : Nat { x * 2 });\n /// assert(?2 == mappedIter.next());\n /// assert(?4 == mappedIter.next());\n /// assert(?6 == mappedIter.next());\n /// assert(null == mappedIter.next());\n /// ```\n public func map<A, B>(xs : Iter<A>, f : A -> B) : Iter<B> = object {\n public func next() : ?B {\n switch (xs.next()) {\n case (?next) {\n ?f(next);\n };\n case (null) {\n null;\n };\n };\n };\n };\n\n /// Takes a function and an iterator and returns a new iterator that produces\n /// elements from the original iterator if and only if the predicate is true.\n /// ```motoko\n /// import Iter \"o:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// let mappedIter = Iter.filter(iter, func (x : Nat) : Bool { x % 2 == 1 });\n /// assert(?1 == mappedIter.next());\n /// assert(?3 == mappedIter.next());\n /// assert(null == mappedIter.next());\n /// ```\n public func filter<A>(xs : Iter<A>, f : A -> Bool) : Iter<A> = object {\n public func next() : ?A {\n loop {\n switch (xs.next()) {\n case (null) {\n return null;\n };\n case (?x) {\n if (f(x)) {\n return ?x;\n };\n };\n };\n };\n null;\n };\n };\n\n /// Creates an iterator that produces an infinite sequence of `x`.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.make(10);\n /// assert(?10 == iter.next());\n /// assert(?10 == iter.next());\n /// assert(?10 == iter.next());\n /// // ...\n /// ```\n public func make<A>(x : A) : Iter<A> = object {\n public func next() : ?A {\n ?x;\n };\n };\n\n /// Creates an iterator that produces the elements of an Array in ascending index order.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.fromArray([1, 2, 3]);\n /// assert(?1 == iter.next());\n /// assert(?2 == iter.next());\n /// assert(?3 == iter.next());\n /// assert(null == iter.next());\n /// ```\n public func fromArray<A>(xs : [A]) : Iter<A> {\n var ix : Nat = 0;\n let size = xs.size();\n object {\n public func next() : ?A {\n if (ix >= size) {\n return null\n } else {\n let res = ?(xs[ix]);\n ix += 1;\n return res\n }\n }\n }\n };\n\n /// Like `fromArray` but for Arrays with mutable elements. Captures\n /// the elements of the Array at the time the iterator is created, so\n /// further modifications won't be reflected in the iterator.\n public func fromArrayMut<A>(xs : [var A]) : Iter<A> {\n fromArray<A>(Array.freeze<A>(xs));\n };\n\n /// Like `fromArray` but for Lists.\n public let fromList = List.toIter;\n\n /// Consumes an iterator and collects its produced elements in an Array.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// assert([1, 2, 3] == Iter.toArray(iter));\n /// ```\n public func toArray<A>(xs : Iter<A>) : [A] {\n let buffer = Buffer.Buffer<A>(8);\n iterate(xs, func(x : A, ix : Nat) { buffer.add(x) });\n return Buffer.toArray(buffer)\n };\n\n /// Like `toArray` but for Arrays with mutable elements.\n public func toArrayMut<A>(xs : Iter<A>) : [var A] {\n Array.thaw<A>(toArray<A>(xs));\n };\n\n /// Like `toArray` but for Lists.\n public func toList<A>(xs : Iter<A>) : List.List<A> {\n var result = List.nil<A>();\n iterate<A>(xs, func (x, _i) {\n result := List.push<A>(x, result);\n });\n List.reverse<A>(result);\n };\n\n /// Sorted iterator. Will iterate over *all* elements to sort them, necessarily.\n public func sort<A>(xs : Iter<A>, compare : (A, A) -> Order.Order) : Iter<A> {\n let a = toArrayMut<A>(xs);\n Array.sortInPlace<A>(a, compare);\n fromArrayMut<A>(a)\n };\n\n};\n"},"Int16.mo":{"content":"/// 16-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 16-bit signed integers\n public type Int16 = Prim.Types.Int16;\n\n /// Conversion.\n public let toInt : Int16 -> Int = Prim.int16ToInt;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromInt : Int -> Int16 = Prim.intToInt16;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Int16 = Prim.intToInt16Wrap;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromNat16 : Nat16 -> Int16 = Prim.nat16ToInt16;\n\n /// Conversion. Wraps on overflow/underflow.\n public let toNat16 : Int16 -> Nat16 = Prim.int16ToNat16;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Int16) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`. Traps when `x = -2^15`.\n public func abs(x : Int16) : Int16 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int16, y : Int16) : Int16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Int16, y : Int16) : Int16 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Int16, y : Int16) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int16, y : Int16) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int16, y : Int16) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int16, y : Int16) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int16, y : Int16) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int16, y : Int16) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int16, y : Int16) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`. Traps on overflow.\n public func neg(x : Int16) : Int16 { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Int16, y : Int16) : Int16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Int16, y : Int16) : Int16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Int16, y : Int16) : Int16 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int16, y : Int16) : Int16 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int16, y : Int16) : Int16 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Int16, y : Int16) : Int16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Int16, y : Int16) : Int16 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Int16, y : Int16) : Int16 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Int16, y : Int16) : Int16 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Int16, y : Int16) : Int16 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Int16, y : Int16) : Int16 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Int16, y : Int16) : Int16 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Int16, y : Int16) : Int16 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Int16, y : Int16) : Int16 { x <>> y };\n\n /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n public func bittest(x : Int16, p : Nat) : Bool {\n Prim.btstInt16(x, Prim.intToInt16(p));\n };\n\n /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n public func bitset(x : Int16, p : Nat) : Int16 {\n x | (1 << Prim.intToInt16(p));\n };\n\n /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n public func bitclear(x : Int16, p : Nat) : Int16 {\n x & ^(1 << Prim.intToInt16(p));\n };\n\n /// Returns the value of flipping bit `p mod 16` in `x`.\n public func bitflip(x : Int16, p : Nat) : Int16 {\n x ^ (1 << Prim.intToInt16(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Int16) -> Int16 = Prim.popcntInt16;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Int16) -> Int16 = Prim.clzInt16;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Int16) -> Int16 = Prim.ctzInt16;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Int16, y : Int16) : Int16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Int16, y : Int16) : Int16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Int16, y : Int16) : Int16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n public func powWrap(x : Int16, y : Int16) : Int16 { x **% y };\n}\n"},"Int.mo":{"content":"/// Integer numbers\n///\n/// Most operations on integers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n\nimport Prim \"mo:⛔\";\nimport Prelude \"Prelude\";\nimport Hash \"Hash\";\n\nmodule {\n\n /// Infinite precision signed integers.\n public type Int = Prim.Types.Int;\n\n /// Returns the absolute value of the number\n public let abs : Int -> Nat = Prim.abs;\n\n /// Conversion.\n public let toText : Int -> Text = func(x) {\n if (x == 0) {\n return \"0\";\n };\n\n let isNegative = x < 0;\n var int = if isNegative { -x } else { x };\n\n var text = \"\";\n let base = 10;\n\n while (int > 0) {\n let rem = int % base;\n text := (switch (rem) {\n case 0 { \"0\" };\n case 1 { \"1\" };\n case 2 { \"2\" };\n case 3 { \"3\" };\n case 4 { \"4\" };\n case 5 { \"5\" };\n case 6 { \"6\" };\n case 7 { \"7\" };\n case 8 { \"8\" };\n case 9 { \"9\" };\n case _ { Prelude.unreachable() };\n }) # text;\n int := int / base;\n };\n\n return if isNegative { \"-\" # text } else { text };\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int, y : Int) : Int {\n if (x < y) { x } else { y };\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max(x : Int, y : Int) : Int {\n if (x < y) { y } else { x };\n };\n\n // this is a local copy of deprecated Hash.hashNat8 (redefined to suppress the warning)\n private func hashNat8(key : [Nat32]) : Hash.Hash {\n var hash : Nat32 = 0;\n for (natOfKey in key.vals()) {\n hash := hash +% natOfKey;\n hash := hash +% hash << 10;\n hash := hash ^ (hash >> 6);\n };\n hash := hash +% hash << 3;\n hash := hash ^ (hash >> 11);\n hash := hash +% hash << 15;\n return hash;\n };\n\n /// Computes a hash from the least significant 32-bits of `i`, ignoring other bits.\n /// @deprecated For large `Int` values consider using a bespoke hash function that considers all of the argument's bits.\n public func hash(i : Int) : Hash.Hash {\n // CAUTION: This removes the high bits!\n let j = Prim.int32ToNat32(Prim.intToInt32Wrap(i));\n hashNat8(\n [j & (255 << 0),\n j & (255 << 8),\n j & (255 << 16),\n j & (255 << 24)\n ]);\n };\n\n /// @deprecated This function will be removed in future.\n public func hashAcc(h1 : Hash.Hash, i : Int) : Hash.Hash {\n // CAUTION: This removes the high bits!\n let j = Prim.int32ToNat32(Prim.intToInt32Wrap(i));\n hashNat8(\n [h1,\n j & (255 << 0),\n j & (255 << 8),\n j & (255 << 16),\n j & (255 << 24)\n ]);\n };\n\n /// Returns `x == y`.\n public func equal(x : Int, y : Int) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int, y : Int) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int, y : Int) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int, y : Int) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int, y : Int) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int, y : Int) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int, y : Int) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x` .\n public func neq(x : Int) : Int { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n public func add(x : Int, y : Int) : Int { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n public func sub(x : Int, y : Int) : Int { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n public func mul(x : Int, y : Int) : Int { x * y };\n\n /// Returns the division of `x` by `y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int, y : Int) : Int { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int, y : Int) : Int { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n public func pow(x : Int, y : Int) : Int { x ** y };\n\n}\n\n"},"Buffer.mo":{"content":"/// Class `Buffer<X>` provides a mutable list of elements of type `X`.\n/// The class wraps and resizes an underyling array that holds the elements,\n/// and thus is comparable to ArrayLists or Vectors in other languages.\n///\n/// When required, the current state of a buffer object can be converted to a fixed-size array of its elements.\n/// This is recommended for example when storing a buffer to a stable variable.\n///\n/// Throughout this documentation, two terms come up that can be confused: `size`\n/// and `capacity`. `size` is the length of the list that the buffer represents.\n/// `capacity` is the length of the underyling array that backs this list.\n/// `capacity` >= `size` is an invariant for this class.\n///\n/// Like arrays, elements in the buffer are ordered by indices from 0 to `size`-1.\n///\n/// WARNING: Certain operations are amortized O(1) time, such as `add`, but run\n/// in worst case O(n) time. These worst case runtimes may exceed the cycles limit\n/// per message if the size of the buffer is large enough. Grow these structures\n/// with discretion. All amortized operations below also list the worst case runtime.\n///\n/// Constructor:\n/// The argument `initCapacity` determines the initial capacity of the array.\n/// The underlying array grows by a factor of 1.5 when its current capacity is\n/// exceeded. Further, when the size of the buffer shrinks to be less than 1/4th\n/// of the capacity, the underyling array is shrunk by a factor of 2.\n///\n/// Example:\n/// ```motoko name=initialize\n/// import Buffer \"mo:base/Buffer\";\n///\n/// let buffer = Buffer.Buffer<Nat>(3); // Creates a new Buffer\n/// ```\n///\n/// Runtime: O(initCapacity)\n///\n/// Space: O(initCapacity)\n\nimport Prim \"mo:⛔\";\nimport Result \"Result\";\nimport Order \"Order\";\nimport Array \"Array\";\n\nmodule {\n type Order = Order.Order;\n\n // The following constants are used to manage the capacity.\n // The length of `elements` is increased by `INCREASE_FACTOR` when capacity is reached.\n // The length of `elements` is decreased by `DECREASE_FACTOR` when capacity is strictly less than\n // `DECREASE_THRESHOLD`.\n\n // INCREASE_FACTOR = INCREASE_FACTOR_NUME / INCREASE_FACTOR_DENOM (with floating point division)\n // Keep INCREASE_FACTOR low to minimize cycle limit problem\n private let INCREASE_FACTOR_NUME = 3;\n private let INCREASE_FACTOR_DENOM = 2;\n private let DECREASE_THRESHOLD = 4; // Don't decrease capacity too early to avoid thrashing\n private let DECREASE_FACTOR = 2;\n private let DEFAULT_CAPACITY = 8;\n\n private func newCapacity(oldCapacity : Nat) : Nat {\n if (oldCapacity == 0) {\n 1;\n } else {\n // calculates ceil(oldCapacity * INCREASE_FACTOR) without floats\n ((oldCapacity * INCREASE_FACTOR_NUME) + INCREASE_FACTOR_DENOM - 1) / INCREASE_FACTOR_DENOM;\n };\n };\n\n public class Buffer<X>(initCapacity : Nat) = this {\n var _size : Nat = 0; // avoid name clash with `size()` method\n var elements : [var ?X] = Prim.Array_init(initCapacity, null);\n\n /// Returns the current number of elements in the buffer.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// buffer.size()\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func size() : Nat = _size;\n\n /// Adds a single element to the end of the buffer, doubling\n /// the size of the array if capacity is exceeded.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(0); // add 0 to buffer\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3); // causes underlying array to increase in capacity\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Amortized Runtime: O(1), Worst Case Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func add(element : X) {\n if (_size == elements.size()) {\n reserve(newCapacity(elements.size()));\n };\n elements[_size] := ?element;\n _size += 1;\n };\n\n /// Returns the element at index `index`. Traps if `index >= size`. Indexing is zero-based.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// let x = buffer.get(0); // evaluates to 10\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func get(index : Nat) : X {\n switch (elements[index]) {\n case (?element) element;\n case null Prim.trap(\"Buffer index out of bounds in get\");\n };\n };\n\n /// Returns the element at index `index` as an option.\n /// Returns `null` when `index >= size`. Indexing is zero-based.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// let x = buffer.getOpt(0); // evaluates to ?10\n /// let y = buffer.getOpt(2); // evaluates to null\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func getOpt(index : Nat) : ?X {\n if (index < _size) {\n elements[index];\n } else {\n null;\n };\n };\n\n /// Overwrites the current element at `index` with `element`. Traps if\n /// `index` >= size. Indexing is zero-based.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.put(0, 20); // overwrites 10 at index 0 with 20\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func put(index : Nat, element : X) {\n if (index >= _size) {\n Prim.trap \"Buffer index out of bounds in put\";\n };\n elements[index] := ?element;\n };\n\n /// Removes and returns the last item in the buffer or `null` if\n /// the buffer is empty.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// let x = buffer.removeLast(); // evaluates to ?11\n /// ```\n ///\n /// Amortized Runtime: O(1), Worst Case Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func removeLast() : ?X {\n if (_size == 0) {\n return null;\n };\n\n _size -= 1;\n let lastElement = elements[_size];\n elements[_size] := null;\n\n if (_size < elements.size() / DECREASE_THRESHOLD) {\n // FIXME should this new capacity be a function of _size\n // instead of the current capacity? E.g. _size * INCREASE_FACTOR\n reserve(elements.size() / DECREASE_FACTOR);\n };\n\n lastElement;\n };\n\n /// Removes and returns the element at `index` from the buffer.\n /// All elements with index > `index` are shifted one position to the left.\n /// This may cause a downsizing of the array.\n ///\n /// Traps if index >= size.\n ///\n /// WARNING: Repeated removal of elements using this method is ineffecient\n /// and might be a sign that you should consider a different data-structure\n /// for your use case.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// let x = buffer.remove(1); // evaluates to 11. 11 no longer in list.\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func remove(index : Nat) : X {\n if (index >= _size) {\n Prim.trap \"Buffer index out of bounds in remove\";\n };\n\n let element = elements[index];\n\n // copy elements to new array and shift over in one pass\n if ((_size - 1) : Nat < elements.size() / DECREASE_THRESHOLD) {\n let elements2 = Prim.Array_init<?X>(elements.size() / DECREASE_FACTOR, null);\n\n var i = 0;\n var j = 0;\n label l while (i < _size) {\n if (i == index) {\n i += 1;\n continue l;\n };\n\n elements2[j] := elements[i];\n i += 1;\n j += 1;\n };\n elements := elements2;\n } else {\n // just shift over elements\n var i = index;\n while (i < (_size - 1 : Nat)) {\n elements[i] := elements[i + 1];\n i += 1;\n };\n elements[_size - 1] := null;\n };\n\n _size -= 1;\n\n switch (element) {\n case (?element) {\n element;\n };\n case null {\n Prim.trap \"Malformed buffer in remove\";\n };\n };\n };\n\n /// Resets the buffer. Capacity is set to 8.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// buffer.clear(); // buffer is now empty\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func clear() {\n _size := 0;\n reserve(DEFAULT_CAPACITY);\n };\n\n /// Removes all elements from the buffer for which the predicate returns false.\n /// The predicate is given both the index of the element and the element itself.\n /// This may cause a downsizing of the array.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// buffer.filterEntries(func(_, x) = x % 2 == 0); // only keep even elements\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func filterEntries(predicate : (Nat, X) -> Bool) {\n var numRemoved = 0;\n let keep = Prim.Array_tabulate<Bool>(\n _size,\n func i {\n switch (elements[i]) {\n case (?element) {\n if (predicate(i, element)) {\n true;\n } else {\n numRemoved += 1;\n false;\n };\n };\n case null {\n Prim.trap \"Malformed buffer in filter()\";\n };\n };\n },\n );\n\n let capacity = elements.size();\n\n if ((_size - numRemoved : Nat) < capacity / DECREASE_THRESHOLD) {\n let elements2 = Prim.Array_init<?X>(capacity / DECREASE_FACTOR, null);\n\n var i = 0;\n var j = 0;\n while (i < _size) {\n if (keep[i]) {\n elements2[j] := elements[i];\n i += 1;\n j += 1;\n } else {\n i += 1;\n };\n };\n\n elements := elements2;\n } else {\n var i = 0;\n var j = 0;\n while (i < _size) {\n if (keep[i]) {\n elements[j] := elements[i];\n i += 1;\n j += 1;\n } else {\n i += 1;\n };\n };\n\n while (j < _size) {\n elements[j] := null;\n j += 1;\n };\n };\n\n _size -= numRemoved;\n };\n\n /// Returns the capacity of the buffer (the length of the underlying array).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// \n /// let buffer = Buffer.Buffer<Nat>(2); // underlying array has capacity 2\n /// buffer.add(10);\n /// let c1 = buffer.capacity(); // evaluates to 2\n /// buffer.add(11);\n /// buffer.add(12); // causes capacity to increase by factor of 1.5\n /// let c2 = buffer.capacity(); // evaluates to 3\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func capacity() : Nat = elements.size();\n\n /// Changes the capacity to `capacity`. Traps if `capacity` < `size`.\n ///\n /// ```motoko include=initialize\n /// \n /// buffer.reserve(4);\n /// buffer.add(10);\n /// buffer.add(11);\n /// let c = buffer.capacity(); // evaluates to 4\n /// ```\n ///\n /// Runtime: O(capacity)\n ///\n /// Space: O(capacity)\n public func reserve(capacity : Nat) {\n if (capacity < _size) {\n Prim.trap \"capacity must be >= size in reserve\";\n };\n\n let elements2 = Prim.Array_init<?X>(capacity, null);\n\n var i = 0;\n while (i < _size) {\n elements2[i] := elements[i];\n i += 1;\n };\n elements := elements2;\n };\n\n /// Adds all elements in buffer `b` to this buffer.\n ///\n /// ```motoko include=initialize\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(10);\n /// buffer1.add(11);\n /// buffer2.add(12);\n /// buffer2.add(13);\n /// buffer1.append(buffer2); // adds elements from buffer2 to buffer1\n /// Buffer.toArray(buffer1)\n /// ```\n ///\n /// Amortized Runtime: O(size2), Worst Case Runtime: O(size1 + size2)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size1 + size2)\n public func append(buffer2 : Buffer<X>) {\n let size2 = buffer2.size();\n // Make sure you only allocate a new array at most once\n if (_size + size2 > elements.size()) {\n // FIXME would be nice to have a tabulate for var arrays here\n reserve(newCapacity(_size + size2));\n };\n var i = 0;\n while (i < size2) {\n elements[_size + i] := buffer2.getOpt i;\n i += 1;\n };\n\n _size += size2;\n };\n\n /// Inserts `element` at `index`, shifts all elements to the right of\n /// `index` over by one index. Traps if `index` is greater than size.\n ///\n /// ```motoko include=initialize\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.insert(1, 9);\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size)\n public func insert(index : Nat, element : X) {\n if (index > _size) {\n Prim.trap \"Buffer index out of bounds in insert\";\n };\n let capacity = elements.size();\n\n if (_size + 1 > capacity) {\n let capacity = elements.size();\n let elements2 = Prim.Array_init<?X>(newCapacity capacity, null);\n var i = 0;\n while (i < _size + 1) {\n if (i < index) {\n elements2[i] := elements[i];\n } else if (i == index) {\n elements2[i] := ?element;\n } else {\n elements2[i] := elements[i - 1];\n };\n\n i += 1;\n };\n elements := elements2;\n } else {\n var i : Nat = _size;\n while (i > index) {\n elements[i] := elements[i - 1];\n i -= 1;\n };\n elements[index] := ?element;\n };\n\n _size += 1;\n };\n\n /// Inserts `buffer2` at `index`, and shifts all elements to the right of\n /// `index` over by size2. Traps if `index` is greater than size.\n ///\n /// ```motoko include=initialize\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(10);\n /// buffer1.add(11);\n /// buffer2.add(12);\n /// buffer2.add(13);\n /// buffer1.insertBuffer(1, buffer2);\n /// Buffer.toArray(buffer1)\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Amortized Space: O(1), Worst Case Space: O(size1 + size2)\n public func insertBuffer(index : Nat, buffer2 : Buffer<X>) {\n if (index > _size) {\n Prim.trap \"Buffer index out of bounds in insertBuffer\";\n };\n\n let size2 = buffer2.size();\n let capacity = elements.size();\n\n // copy elements to new array and shift over in one pass\n if (_size + size2 > capacity) {\n let elements2 = Prim.Array_init<?X>(newCapacity(_size + size2), null);\n var i = 0;\n for (element in elements.vals()) {\n if (i == index) {\n i += size2;\n };\n elements2[i] := element;\n i += 1;\n };\n\n i := 0;\n while (i < size2) {\n elements2[i + index] := buffer2.getOpt(i);\n i += 1;\n };\n elements := elements2;\n } // just insert\n else {\n var i = index;\n while (i < index + size2) {\n if (i < _size) {\n elements[i + size2] := elements[i];\n };\n elements[i] := buffer2.getOpt(i - index);\n\n i += 1;\n };\n };\n\n _size += size2;\n };\n\n /// Sorts the elements in the buffer according to `compare`.\n /// Sort is deterministic, stable, and in-place.\n ///\n /// ```motoko include=initialize\n /// \n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(11);\n /// buffer.add(12);\n /// buffer.add(10);\n /// buffer.sort(Nat.compare);\n /// Buffer.toArray(buffer)\n /// ```\n ///\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n public func sort(compare : (X, X) -> Order.Order) {\n // Stable merge sort in a bottom-up iterative style\n if (_size == 0) {\n return;\n };\n let scratchSpace = Prim.Array_init<?X>(_size, null);\n\n let sizeDec = _size - 1 : Nat;\n var currSize = 1; // current size of the subarrays being merged\n // when the current size == size, the array has been merged into a single sorted array\n while (currSize < _size) {\n var leftStart = 0; // selects the current left subarray being merged\n while (leftStart < sizeDec) {\n let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {\n leftStart + currSize - 1;\n } else { sizeDec };\n let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {\n leftStart + (2 * currSize) - 1;\n } else { sizeDec };\n\n // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]\n var left = leftStart;\n var right = mid + 1;\n var nextSorted = leftStart;\n while (left < mid + 1 and right < rightEnd + 1) {\n let leftOpt = elements[left];\n let rightOpt = elements[right];\n switch (leftOpt, rightOpt) {\n case (?leftElement, ?rightElement) {\n switch (compare(leftElement, rightElement)) {\n case (#less or #equal) {\n scratchSpace[nextSorted] := leftOpt;\n left += 1;\n };\n case (#greater) {\n scratchSpace[nextSorted] := rightOpt;\n right += 1;\n };\n };\n };\n case (_, _) {\n // only sorting non-null items\n Prim.trap \"Malformed buffer in sort\";\n };\n };\n nextSorted += 1;\n };\n while (left < mid + 1) {\n scratchSpace[nextSorted] := elements[left];\n nextSorted += 1;\n left += 1;\n };\n while (right < rightEnd + 1) {\n scratchSpace[nextSorted] := elements[right];\n nextSorted += 1;\n right += 1;\n };\n\n // Copy over merged elements\n var i = leftStart;\n while (i < rightEnd + 1) {\n elements[i] := scratchSpace[i];\n i += 1;\n };\n\n leftStart += 2 * currSize;\n };\n currSize *= 2;\n };\n };\n\n /// Returns an Iterator (`Iter`) over the elements of this buffer.\n /// Iterator provides a single method `next()`, which returns\n /// elements in order, or `null` when out of elements to iterate over.\n ///\n /// ```motoko include=initialize\n ///\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n ///\n /// var sum = 0;\n /// for (element in buffer.vals()) {\n /// sum += element;\n /// };\n /// sum\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func vals() : { next : () -> ?X } = object {\n // FIXME either handle modification to underlying list\n // or explicitly warn users in documentation\n var nextIndex = 0;\n public func next() : ?X {\n if (nextIndex >= _size) {\n return null;\n };\n let nextElement = elements[nextIndex];\n nextIndex += 1;\n nextElement;\n };\n };\n\n // FOLLOWING METHODS ARE DEPRECATED\n\n /// @deprecated Use static library function instead.\n public func clone() : Buffer<X> {\n let newBuffer = Buffer<X>(elements.size());\n for (element in vals()) {\n newBuffer.add(element);\n };\n newBuffer;\n };\n\n /// @deprecated Use static library function instead.\n public func toArray() : [X] =\n // immutable clone of array\n Prim.Array_tabulate<X>(\n _size,\n func(i : Nat) : X { get i },\n );\n\n /// @deprecated Use static library function instead.\n public func toVarArray() : [var X] {\n if (_size == 0) { [var] } else {\n let newArray = Prim.Array_init<X>(_size, get 0);\n var i = 0;\n for (element in vals()) {\n newArray[i] := element;\n i += 1;\n };\n newArray;\n };\n };\n };\n\n /// Returns true iff the buffer is empty.\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func isEmpty<X>(buffer : Buffer<X>) : Bool = buffer.size() == 0;\n\n /// Returns true iff `buffer` contains `element` with respect to equality\n /// defined by `equal`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func contains<X>(buffer : Buffer<X>, element : X, equal : (X, X) -> Bool) : Bool {\n for (current in buffer.vals()) {\n if (equal(current, element)) {\n return true;\n };\n };\n\n false;\n };\n\n /// Returns a copy of `buffer`, with the same capacity.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func clone<X>(buffer : Buffer<X>) : Buffer<X> {\n let newBuffer = Buffer<X>(buffer.capacity());\n for (element in buffer.vals()) {\n newBuffer.add(element);\n };\n newBuffer;\n };\n\n /// Finds the greatest element in `buffer` defined by `compare`.\n /// Returns `null` if `buffer` is empty.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func max<X>(buffer : Buffer<X>, compare : (X, X) -> Order) : ?X {\n if (buffer.size() == 0) {\n return null;\n };\n\n var maxSoFar = buffer.get(0);\n for (current in buffer.vals()) {\n switch (compare(current, maxSoFar)) {\n case (#greater) {\n maxSoFar := current;\n };\n case _ {};\n };\n };\n\n ?maxSoFar;\n };\n\n /// Finds the least element in `buffer` defined by `compare`.\n /// Returns `null` if `buffer` is empty.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func min<X>(buffer : Buffer<X>, compare : (X, X) -> Order) : ?X {\n if (buffer.size() == 0) {\n return null;\n };\n\n var minSoFar = buffer.get(0);\n for (current in buffer.vals()) {\n switch (compare(current, minSoFar)) {\n case (#less) {\n minSoFar := current;\n };\n case _ {};\n };\n };\n\n ?minSoFar;\n };\n\n /// Defines equality for two buffers, using `equal` to recursively compare elements in the\n /// buffers. Returns true iff the two buffers are of the same size, and `equal`\n /// evaluates to true for every pair of elements in the two buffers of the same\n /// index.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func equal<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let size1 = buffer1.size();\n\n if (size1 != buffer2.size()) {\n return false;\n };\n\n var i = 0;\n while (i < size1) {\n if (not equal(buffer1.get(i), buffer2.get(i))) {\n return false;\n };\n i += 1;\n };\n\n true;\n };\n\n /// Defines comparison for two buffers, using `compare` to recursively compare elements in the\n /// buffers. Comparison is defined lexicographically.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func compare<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, compare : (X, X) -> Order.Order) : Order.Order {\n let size1 = buffer1.size();\n let size2 = buffer2.size();\n let minSize = if (size1 < size2) { size1 } else { size2 };\n\n var i = 0;\n while (i < minSize) {\n switch (compare(buffer1.get(i), buffer2.get(i))) {\n case (#less) {\n return #less;\n };\n case (#greater) {\n return #greater;\n };\n case _ {};\n };\n i += 1;\n };\n\n if (size1 < size2) {\n #less;\n } else if (size1 == size2) {\n #equal;\n } else {\n #greater;\n };\n };\n\n /// Creates a textual representation of `buffer`, using `toText` to recursively\n /// convert the elements into Text.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `toText` runs in O(1) time and space.\n public func toText<X>(buffer : Buffer<X>, toText : X -> Text) : Text {\n let size : Int = buffer.size();\n var i = 0;\n var text = \"\";\n while (i < size - 1) {\n text := text # toText(buffer.get(i)) # \", \"; // Text implemented as rope\n i += 1;\n };\n if (size > 0) {\n // avoid the trailing comma\n text := text # toText(buffer.get(i));\n };\n\n \"[\" # text # \"]\";\n };\n\n /// Hashes `buffer` using `hash` to hash the underlying elements.\n /// The deterministic hash function is a function of the elements in the Buffer, as well\n /// as their ordering.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `hash` runs in O(1) time and space.\n public func hash<X>(buffer : Buffer<X>, hash : X -> Nat32) : Nat32 {\n let size = buffer.size();\n var i = 0;\n var accHash : Nat32 = 0;\n\n while (i < size) {\n accHash := Prim.intToNat32Wrap(i) ^ accHash ^ hash(buffer.get(i));\n i += 1;\n };\n\n accHash;\n };\n\n /// Finds the first index of `element` in `buffer` using equality of elements defined\n /// by `equal`. Returns `null` if `element` is not found.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func indexOf<X>(element : X, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n let size = buffer.size();\n var i = 0;\n while (i < size) {\n if (equal(buffer.get(i), element)) {\n return ?i;\n };\n i += 1;\n };\n\n null;\n };\n\n /// Finds the last index of `element` in `buffer` using equality of elements defined\n /// by `equal`. Returns `null` if `element` is not found.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func lastIndexOf<X>(element : X, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n let size = buffer.size();\n if (size == 0) {\n return null;\n };\n var i = size;\n while (i >= 1) {\n i -= 1;\n if (equal(buffer.get(i), element)) {\n return ?i;\n };\n };\n\n null;\n };\n\n /// Searches for `subBuffer` in `buffer`, and returns the starting index if it is found.\n ///\n /// Runtime: O(size of buffer + size of subBuffer)\n ///\n /// Space: O(size of subBuffer)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func indexOfBuffer<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n // Uses the KMP substring search algorithm\n // Implementation from: https://www.educative.io/answers/what-is-the-knuth-morris-pratt-algorithm\n let size = buffer.size();\n let subSize = subBuffer.size();\n if (subSize > size or subSize == 0) {\n return null;\n };\n\n // precompute lps\n let lps = Prim.Array_init<Nat>(subSize, 0);\n var i = 0;\n var j = 1;\n\n while (j < subSize) {\n if (equal(subBuffer.get(i), subBuffer.get(j))) {\n i += 1;\n lps[j] := i;\n j += 1;\n } else if (i == 0) {\n lps[j] := 0;\n j += 1;\n } else {\n i := lps[i - 1];\n };\n };\n\n // start search\n i := 0;\n j := 0;\n let subSizeDec = subSize - 1 : Nat; // hoisting loop invariant\n while (i < subSize and j < size) {\n if (equal(subBuffer.get(i), buffer.get(j)) and i == subSizeDec) {\n return ?(j - i);\n } else if (equal(subBuffer.get(i), buffer.get(j))) {\n i += 1;\n j += 1;\n } else {\n if (i != 0) {\n i := lps[i - 1];\n } else {\n j += 1;\n };\n };\n };\n\n null;\n };\n\n /// Similar to indexOf, but runs in logarithmic time. Assumes that `buffer` is sorted.\n /// Behavior is undefined if `buffer` is not sorted. Uses `compare` to\n /// perform the search. Returns an index of `element` if it is found.\n ///\n /// Runtime: O(log(size))\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func binarySearch<X>(element : X, buffer : Buffer<X>, compare : (X, X) -> Order.Order) : ?Nat {\n var low = 0;\n var high = buffer.size();\n\n while (low < high) {\n let mid = (low + high) / 2;\n let current = buffer.get(mid);\n switch (compare(element, current)) {\n case (#equal) {\n return ?mid;\n };\n case (#less) {\n high := mid;\n };\n case (#greater) {\n low := mid + 1;\n };\n };\n };\n\n null;\n };\n\n /// Returns the sub-buffer of `buffer` starting at index `start`\n /// of length `length`. Traps if `start` is out of bounds, or `start + length`\n /// is greater than the size of `buffer`.\n ///\n /// Runtime: O(length)\n ///\n /// Space: O(length)\n public func subBuffer<X>(buffer : Buffer<X>, start : Nat, length : Nat) : Buffer<X> {\n let size = buffer.size();\n let end = start + length; // exclusive\n if (start >= size or end > size) {\n Prim.trap \"Buffer index out of bounds in subBuffer\";\n };\n\n let newBuffer = Buffer<X>(newCapacity length);\n\n var i = start;\n while (i < end) {\n newBuffer.add(buffer.get(i));\n\n i += 1;\n };\n\n newBuffer;\n };\n\n /// Checks if `subBuffer` is a sub-Buffer of `buffer`. Uses `equal` to\n /// compare elements.\n ///\n /// Runtime: O(size of subBuffer + size of buffer)\n ///\n /// Space: O(size of subBuffer)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isSubBufferOf<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n switch (indexOfBuffer(subBuffer, buffer, equal)) {\n case null subBuffer.size() == 0;\n case _ true;\n };\n };\n\n /// Checks if `subBuffer` is a strict subBuffer of `buffer`, i.e. `subBuffer` must be\n /// strictly contained inside both the first and last indices of `buffer`.\n /// Uses `equal` to compare elements.\n ///\n /// Runtime: O(size of subBuffer + size of buffer)\n ///\n /// Space: O(size of subBuffer)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isStrictSubBufferOf<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let subBufferSize = subBuffer.size();\n\n switch (indexOfBuffer(subBuffer, buffer, equal)) {\n case (?index) {\n index != 0 and index != (buffer.size() - subBufferSize : Nat) // enforce strictness\n };\n case null {\n subBufferSize == 0 and subBufferSize != buffer.size();\n };\n };\n };\n\n /// Returns the prefix of `buffer` of length `length`. Traps if `length`\n /// is greater than the size of `buffer`.\n ///\n /// Runtime: O(length)\n ///\n /// Space: O(length)\n public func prefix<X>(buffer : Buffer<X>, length : Nat) : Buffer<X> {\n let size = buffer.size();\n if (length > size) {\n Prim.trap \"Buffer index out of bounds in prefix\";\n };\n\n let newBuffer = Buffer<X>(newCapacity length);\n\n var i = 0;\n while (i < length) {\n newBuffer.add(buffer.get(i));\n i += 1;\n };\n\n newBuffer;\n };\n\n /// Checks if `prefix` is a prefix of `buffer`. Uses `equal` to\n /// compare elements.\n ///\n /// Runtime: O(size of prefix)\n ///\n /// Space: O(size of prefix)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isPrefixOf<X>(prefix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let sizePrefix = prefix.size();\n if (buffer.size() < sizePrefix) {\n return false;\n };\n\n var i = 0;\n while (i < sizePrefix) {\n if (not equal(buffer.get(i), prefix.get(i))) {\n return false;\n };\n\n i += 1;\n };\n\n return true;\n };\n\n /// Checks if `prefix` is a strict prefix of `buffer`. Uses `equal` to\n /// compare elements.\n ///\n /// Runtime: O(size of prefix)\n ///\n /// Space: O(size of prefix)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isStrictPrefixOf<X>(prefix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n if (buffer.size() <= prefix.size()) {\n return false;\n };\n isPrefixOf(prefix, buffer, equal);\n };\n\n /// Returns the suffix of `buffer` of length `length`.\n /// Traps if `length`is greater than the size of `buffer`.\n ///\n /// Runtime: O(length)\n ///\n /// Space: O(length)\n public func suffix<X>(buffer : Buffer<X>, length : Nat) : Buffer<X> {\n let size = buffer.size();\n\n if (length > size) {\n Prim.trap \"Buffer index out of bounds in suffix\";\n };\n\n let newBuffer = Buffer<X>(newCapacity length);\n\n var i = size - length : Nat;\n while (i < size) {\n newBuffer.add(buffer.get(i));\n\n i += 1;\n };\n\n newBuffer;\n };\n\n /// Checks if `suffix` is a suffix of `buffer`. Uses `equal` to compare\n /// elements.\n ///\n /// Runtime: O(length of suffix)\n ///\n /// Space: O(length of suffix)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isSuffixOf<X>(suffix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let suffixSize = suffix.size();\n let bufferSize = buffer.size();\n if (bufferSize < suffixSize) {\n return false;\n };\n\n var i = bufferSize;\n var j = suffixSize;\n while (i >= 1 and j >= 1) {\n i -= 1;\n j -= 1;\n if (not equal(buffer.get(i), suffix.get(j))) {\n return false;\n };\n };\n\n return true;\n };\n\n /// Checks if `suffix` is a strict suffix of `buffer`. Uses `equal` to compare\n /// elements.\n ///\n /// Runtime: O(length of suffix)\n ///\n /// Space: O(length of suffix)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func isStrictSuffixOf<X>(suffix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n if (buffer.size() <= suffix.size()) {\n return false;\n };\n isSuffixOf(suffix, buffer, equal);\n };\n\n /// Returns true iff every element in `buffer` satisfies `predicate`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func forAll<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n for (element in buffer.vals()) {\n if (not predicate element) {\n return false;\n };\n };\n\n true;\n };\n\n /// Returns true iff some element in `buffer` satisfies `predicate`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func forSome<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n for (element in buffer.vals()) {\n if (predicate element) {\n return true;\n };\n };\n\n false;\n };\n\n /// Returns true iff no element in `buffer` satisfies `predicate`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func forNone<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n for (element in buffer.vals()) {\n if (predicate element) {\n return false;\n };\n };\n\n true;\n };\n\n /// Creates an array containing elements from `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toArray<X>(buffer : Buffer<X>) : [X] =\n // immutable clone of array\n Prim.Array_tabulate<X>(\n buffer.size(),\n func(i : Nat) : X { buffer.get(i) },\n );\n\n /// Creates a mutable array containing elements from `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toVarArray<X>(buffer : Buffer<X>) : [var X] {\n let size = buffer.size();\n if (size == 0) { [var] } else {\n let newArray = Prim.Array_init<X>(size, buffer.get(0));\n var i = 1;\n while (i < size) {\n newArray[i] := buffer.get(i);\n i += 1;\n };\n newArray;\n };\n };\n\n /// Creates a buffer containing elements from `array`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromArray<X>(array : [X]) : Buffer<X> {\n // When returning new buffer, if possible, set the capacity\n // to the capacity of the old buffer. Otherwise, return them\n // at 2/3 capacity (like in this case). Alternative is to\n // calculate what the size would be if the elements were\n // sequentially added using `add`. This current strategy (2/3)\n // is the upper bound of that calculation (if the last element\n // added caused a capacity increase).\n let newBuffer = Buffer<X>(newCapacity(array.size()));\n\n for (element in array.vals()) {\n newBuffer.add(element);\n };\n\n newBuffer;\n };\n\n /// Creates a buffer containing elements from `array`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromVarArray<X>(array : [var X]) : Buffer<X> {\n let newBuffer = Buffer<X>(newCapacity(array.size()));\n\n for (element in array.vals()) {\n newBuffer.add(element);\n };\n\n newBuffer;\n };\n\n /// Creates a buffer containing elements from `iter`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromIter<X>(iter : { next : () -> ?X }) : Buffer<X> {\n let newBuffer = Buffer<X>(DEFAULT_CAPACITY); // can't get size from `iter`\n\n for (element in iter) {\n newBuffer.add(element);\n };\n\n newBuffer;\n };\n\n /// Reallocates the array underlying `buffer` such that capacity == size.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func trimToSize<X>(buffer : Buffer<X>) {\n let size = buffer.size();\n if (size < buffer.capacity()) {\n buffer.reserve(size);\n };\n };\n\n /// Creates a new buffer by applying `f` to each element in `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func map<X, Y>(buffer : Buffer<X>, f : X -> Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n newBuffer.add(f element);\n };\n\n newBuffer;\n };\n\n /// Applies `f` to each element in `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func iterate<X>(buffer : Buffer<X>, f : X -> ()) {\n for (element in buffer.vals()) {\n f element;\n };\n };\n\n /// Applies `f` to each element in `buffer` and its index.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapEntries<X, Y>(buffer : Buffer<X>, f : (Nat, X) -> Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n var i = 0;\n let size = buffer.size();\n while (i < size) {\n newBuffer.add(f(i, buffer.get(i)));\n i += 1;\n };\n\n newBuffer;\n };\n\n /// Creates a new buffer by applying `f` to each element in `buffer`,\n /// and keeping all non-null elements.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapFilter<X, Y>(buffer : Buffer<X>, f : X -> ?Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n switch (f element) {\n case (?element) {\n newBuffer.add(element);\n };\n case _ {};\n };\n };\n\n newBuffer;\n };\n\n /// Creates a new buffer by applying `f` to each element in `buffer`.\n /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n /// Returns an `#ok` containing the new buffer.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapResult<X, Y, E>(buffer : Buffer<X>, f : X -> Result.Result<Y, E>) : Result.Result<Buffer<Y>, E> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n switch (f element) {\n case (#ok result) {\n newBuffer.add(result);\n };\n case (#err e) {\n return #err e;\n };\n };\n };\n\n #ok newBuffer;\n };\n\n /// Creates a new buffer by applying `k` to each element in `buffer`,\n /// and concatenating the resulting buffers in order. This operation\n /// is similar to what in other functional languages is known as monadic bind.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `k` runs in O(1) time and space.\n public func chain<X, Y>(buffer : Buffer<X>, k : X -> Buffer<Y>) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.size() * 4);\n\n for (element in buffer.vals()) {\n newBuffer.append(k element);\n };\n\n newBuffer;\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldLeft<A, X>(buffer : Buffer<X>, base : A, combine : (A, X) -> A) : A {\n var accumulation = base;\n\n for (element in buffer.vals()) {\n accumulation := combine(accumulation, element);\n };\n\n accumulation;\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldRight<X, A>(buffer : Buffer<X>, base : A, combine : (X, A) -> A) : A {\n let size = buffer.size();\n if (size == 0) {\n return base;\n };\n var accumulation = base;\n\n var i = size;\n while (i >= 1) {\n i -= 1; // to avoid Nat underflow, subtract first and stop iteration at 1\n accumulation := combine(buffer.get(i), accumulation);\n };\n\n accumulation;\n };\n\n /// Returns the first element of `buffer`. Traps if `buffer` is empty.\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func first<X>(buffer : Buffer<X>) : X = buffer.get(0);\n\n /// Returns the last element of `buffer`. Traps if `buffer` is empty.\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func last<X>(buffer : Buffer<X>) : X = buffer.get(buffer.size() - 1);\n\n /// Returns a new buffer with capacity and size 1, containing `element`.\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func make<X>(element : X) : Buffer<X> {\n let newBuffer = Buffer<X>(1);\n newBuffer.add(element);\n newBuffer;\n };\n\n /// Reverses the order of elements in `buffer`.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func reverse<X>(buffer : Buffer<X>) {\n let size = buffer.size();\n if (size == 0) {\n return;\n };\n\n var i = 0;\n var j = size - 1 : Nat;\n var temp = buffer.get(0);\n while (i < size / 2) {\n temp := buffer.get(j);\n buffer.put(j, buffer.get(i));\n buffer.put(i, temp);\n i += 1;\n j -= 1;\n };\n };\n\n /// Merges two sorted buffers into a single sorted buffer, using `compare` to define\n /// the ordering. The final ordering is stable. Behavior is undefined if either\n /// `buffer1` or `buffer2` is not sorted.\n ///\n /// Runtime: O(size1 + size2)\n ///\n /// Space: O(size1 + size2)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func merge<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, compare : (X, X) -> Order) : Buffer<X> {\n let size1 = buffer1.size();\n let size2 = buffer2.size();\n\n let newBuffer = Buffer<X>(newCapacity(size1 + size2));\n\n var pointer1 = 0;\n var pointer2 = 0;\n\n while (pointer1 < size1 and pointer2 < size2) {\n let current1 = buffer1.get(pointer1);\n let current2 = buffer2.get(pointer2);\n\n switch (compare(current1, current2)) {\n case (#less) {\n newBuffer.add(current1);\n pointer1 += 1;\n };\n case _ {\n newBuffer.add(current2);\n pointer2 += 1;\n };\n };\n };\n\n while (pointer1 < size1) {\n newBuffer.add(buffer1.get(pointer1));\n pointer1 += 1;\n };\n\n while (pointer2 < size2) {\n newBuffer.add(buffer2.get(pointer2));\n pointer2 += 1;\n };\n\n newBuffer;\n };\n\n /// Eliminates all duplicate elements in `buffer` as defined by `compare`.\n /// Elimination is stable with respect to the original ordering of the elements.\n ///\n /// Runtime: O(size * log(size))\n ///\n /// Space: O(size)\n public func removeDuplicates<X>(buffer : Buffer<X>, compare : (X, X) -> Order) {\n let size = buffer.size();\n let indices = Prim.Array_tabulate<(Nat, X)>(size, func i = (i, buffer.get(i)));\n // Sort based on element, while carrying original index information\n // This groups together the duplicate elements\n let sorted = Array.sort<(Nat, X)>(indices, func(pair1, pair2) = compare(pair1.1, pair2.1));\n let uniques = Buffer<(Nat, X)>(size);\n\n // Iterate over elements\n var i = 0;\n while (i < size) {\n var j = i;\n // Iterate over duplicate elements, and find the smallest index among them (for stability)\n var minIndex = sorted[j];\n label duplicates while (j < (size - 1 : Nat)) {\n let pair1 = sorted[j];\n let pair2 = sorted[j + 1];\n switch (compare(pair1.1, pair2.1)) {\n case (#equal) {\n if (pair2.0 < pair1.0) {\n minIndex := pair2;\n };\n j += 1;\n };\n case _ {\n break duplicates;\n };\n };\n };\n\n uniques.add(minIndex);\n i := j + 1;\n };\n\n // resort based on original ordering and place back in buffer\n uniques.sort(\n func(pair1, pair2) {\n if (pair1.0 < pair2.0) {\n #less;\n } else if (pair1.0 == pair2.0) {\n #equal;\n } else {\n #greater;\n };\n },\n );\n\n buffer.clear();\n buffer.reserve(uniques.size());\n for (element in uniques.vals()) {\n buffer.add(element.1);\n };\n };\n\n /// Splits `buffer` into a pair of buffers where all elements in the left\n /// buffer satisfy `predicate` and all elements in the right buffer do not.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func partition<X>(buffer : Buffer<X>, predicate : X -> Bool) : (Buffer<X>, Buffer<X>) {\n let size = buffer.size();\n let trueBuffer = Buffer<X>(size);\n let falseBuffer = Buffer<X>(size);\n\n for (element in buffer.vals()) {\n if (predicate element) {\n trueBuffer.add(element);\n } else {\n falseBuffer.add(element);\n };\n };\n\n (trueBuffer, falseBuffer);\n };\n\n /// Splits the buffer into two buffers at `index`, where the left buffer contains\n /// all elements with indices less than `index`, and the right buffer contains all\n /// elements with indices greater than or equal to `index`. Traps if `index` is out\n /// of bounds.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `compare` runs in O(1) time and space.\n public func split<X>(buffer : Buffer<X>, index : Nat) : (Buffer<X>, Buffer<X>) {\n let size = buffer.size();\n\n if (index < 0 or index > size) {\n Prim.trap \"Index out of bounds in split\";\n };\n\n let buffer1 = Buffer<X>(newCapacity index);\n let buffer2 = Buffer<X>(newCapacity(size - index));\n\n var i = 0;\n while (i < index) {\n buffer1.add(buffer.get(i));\n i += 1;\n };\n while (i < size) {\n buffer2.add(buffer.get(i));\n i += 1;\n };\n\n (buffer1, buffer2);\n };\n\n /// Breaks up `buffer` into buffers of size `size`. The last chunk may\n /// have less than `size` elements if the number of elements is not divisible\n /// by the chunk size.\n ///\n /// Runtime: O(number of elements in buffer)\n ///\n /// Space: O(number of elements in buffer)\n public func chunk<X>(buffer : Buffer<X>, size : Nat) : Buffer<Buffer<X>> {\n if (size == 0) {\n Prim.trap \"Chunk size must be non-zero in chunk\";\n };\n\n // ceil(buffer.size() / size)\n let newBuffer = Buffer<Buffer<X>>((buffer.size() + size - 1) / size);\n\n var newInnerBuffer = Buffer<X>(newCapacity size);\n var innerSize = 0;\n for (element in buffer.vals()) {\n if (innerSize == size) {\n newBuffer.add(newInnerBuffer);\n newInnerBuffer := Buffer<X>(newCapacity size);\n innerSize := 0;\n };\n newInnerBuffer.add(element);\n innerSize += 1;\n };\n if (innerSize > 0) {\n newBuffer.add(newInnerBuffer);\n };\n\n newBuffer;\n };\n\n /// Groups equal and adjacent elements in the list into sub lists.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n public func groupBy<X>(buffer : Buffer<X>, equal : (X, X) -> Bool) : Buffer<Buffer<X>> {\n let size = buffer.size();\n let newBuffer = Buffer<Buffer<X>>(size);\n if (size == 0) {\n return newBuffer;\n };\n\n var i = 0;\n var baseElement = buffer.get(0);\n var newInnerBuffer = Buffer<X>(size);\n while (i < size) {\n let element = buffer.get(i);\n\n if (equal(baseElement, element)) {\n newInnerBuffer.add(element);\n } else {\n newBuffer.add(newInnerBuffer);\n baseElement := element;\n newInnerBuffer := Buffer<X>(size - i);\n newInnerBuffer.add(element);\n };\n i += 1;\n };\n if (newInnerBuffer.size() > 0) {\n newBuffer.add(newInnerBuffer);\n };\n\n newBuffer;\n };\n\n /// Flattens the buffer of buffers into a single buffer.\n ///\n /// Runtime: O(number of elements in buffer)\n ///\n /// Space: O(number of elements in buffer)\n public func flatten<X>(buffer : Buffer<Buffer<X>>) : Buffer<X> {\n let size = buffer.size();\n if (size == 0) {\n return Buffer<X>(0);\n };\n\n let newBuffer = Buffer<X>(\n if (buffer.get(0).size() != 0) {\n newCapacity(buffer.get(0).size() * size);\n } else {\n newCapacity(size);\n },\n );\n\n for (innerBuffer in buffer.vals()) {\n for (innerElement in innerBuffer.vals()) {\n newBuffer.add(innerElement);\n };\n };\n\n newBuffer;\n };\n\n /// Combines the two buffers into a single buffer of pairs, pairing together\n /// elements with the same index. If one buffer is longer than the other, the\n /// remaining elements from the longer buffer are not included.\n ///\n /// Runtime: O(min(size1, size2))\n ///\n /// Space: O(min(size1, size2))\n public func zip<X, Y>(buffer1 : Buffer<X>, buffer2 : Buffer<Y>) : Buffer<(X, Y)> {\n // compiler should pull lamda out as a static function since it is fully closed\n zipWith<X, Y, (X, Y)>(buffer1, buffer2, func(x, y) = (x, y));\n };\n\n /// Combines the two buffers into a single buffer, pairing together\n /// elements with the same index and combining them using `zip`. If\n /// one buffer is longer than the other, the remaining elements from\n /// the longer buffer are not included.\n ///\n /// Runtime: O(min(size1, size2))\n ///\n /// Space: O(min(size1, size2))\n ///\n /// *Runtime and space assumes that `zip` runs in O(1) time and space.\n public func zipWith<X, Y, Z>(buffer1 : Buffer<X>, buffer2 : Buffer<Y>, zip : (X, Y) -> Z) : Buffer<Z> {\n let size1 = buffer1.size();\n let size2 = buffer2.size();\n let minSize = if (size1 < size2) { size1 } else { size2 };\n\n var i = 0;\n let newBuffer = Buffer<Z>(newCapacity minSize);\n while (i < minSize) {\n newBuffer.add(zip(buffer1.get(i), buffer2.get(i)));\n i += 1;\n };\n newBuffer;\n };\n\n /// Creates a new buffer taking elements in order from `buffer` until predicate\n /// returns false.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func takeWhile<X>(buffer : Buffer<X>, predicate : X -> Bool) : Buffer<X> {\n let newBuffer = Buffer<X>(buffer.size());\n\n for (element in buffer.vals()) {\n if (not predicate element) {\n return newBuffer;\n };\n newBuffer.add(element);\n };\n\n newBuffer;\n };\n\n /// Creates a new buffer excluding elements in order from `buffer` until predicate\n /// returns false.\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n ///\n /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\n public func dropWhile<X>(buffer : Buffer<X>, predicate : X -> Bool) : Buffer<X> {\n let size = buffer.size();\n let newBuffer = Buffer<X>(size);\n\n var i = 0;\n var take = false;\n label iter for (element in buffer.vals()) {\n if (not (take or predicate element)) {\n take := true;\n };\n if (take) {\n newBuffer.add(element);\n };\n };\n newBuffer;\n };\n};\n"},"Heap.mo":{"content":"/// Priority Queue\n///\n/// This module provides purely-functional priority queue based on leftist heap\n\nimport O \"Order\";\nimport P \"Prelude\";\nimport L \"List\";\nimport I \"Iter\";\n\nmodule {\n\n public type Tree<T> = ?(Int, T, Tree<T>, Tree<T>);\n\n public class Heap<T>(ord : (T, T) -> O.Order) {\n var heap : Tree<T> = null;\n\n /// Get purely-functional representation\n public func share() : Tree<T> {\n heap\n };\n\n /// Put purely-functional representation into class. Need to make sure the tree is constructed with the same compare function\n public func unsafeUnshare(t : Tree<T>) {\n heap := t;\n };\n\n /// Insert an element to the heap\n public func put(x : T) {\n heap := merge(heap, ?(1, x, null, null), ord);\n };\n\n /// Return the minimal element\n public func peekMin() : ?T {\n switch heap {\n case (null) { null };\n case (?(_, x, _, _)) { ?x };\n }\n };\n\n /// Delete the minimal element\n public func deleteMin() {\n switch heap {\n case null {};\n case (?(_, _, a, b)) { heap := merge(a, b, ord) };\n }\n };\n\n /// Remove the minimal element and return its value\n public func removeMin() : ?T {\n switch heap {\n case null { null };\n case (?(_, x, a, b)) {\n heap := merge(a, b, ord);\n ?x\n };\n }\n };\n };\n\n func rank<T>(heap : Tree<T>) : Int {\n switch heap {\n case null { 0 };\n case (?(r, _, _, _)) { r };\n }\n };\n\n func makeT<T>(x : T, a : Tree<T>, b : Tree<T>) : Tree<T> {\n if (rank(a) >= rank(b)) {\n ?(rank(b) + 1, x, a, b)\n } else {\n ?(rank(a) + 1, x, b, a)\n };\n };\n\n func merge<T>(h1 : Tree<T>, h2 : Tree<T>, ord : (T, T) -> O.Order) : Tree<T> {\n switch (h1, h2) {\n case (null, h) { h };\n case (h, null) { h };\n case (?(_, x, a, b), ?(_, y, c, d)) {\n switch (ord(x,y)) {\n case (#less) { makeT(x, a, merge(b, h2, ord)) };\n case _ { makeT(y, c, merge(d, h1, ord)) };\n };\n };\n };\n };\n\n /// Convert iterator into a heap in O(N) time.\n public func fromIter<T>(iter : I.Iter<T>, ord : (T, T) -> O.Order) : Heap<T> {\n let heap = Heap<T>(ord);\n func build(xs : L.List<Tree<T>>) : Tree<T> {\n func join(xs : L.List<Tree<T>>) : L.List<Tree<T>> {\n switch(xs) {\n case (null) { null };\n case (?(hd, null)) { ?(hd, null) };\n case (?(h1, ?(h2, tl))) { ?(merge(h1, h2, ord), join(tl)) };\n }\n };\n switch(xs) {\n case null { P.unreachable() };\n case (?(hd, null)) { hd };\n case _ { build(join(xs)) };\n };\n };\n let list = I.toList(I.map(iter, func (x : T) : Tree<T> { ?(1, x, null, null) } ));\n if (not L.isNil(list)) {\n let t = build(list);\n heap.unsafeUnshare(t);\n };\n heap\n };\n\n};\n"},"Int8.mo":{"content":"/// 8-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 8-bit signed integers.\n public type Int8 = Prim.Types.Int8;\n\n /// Conversion.\n public let toInt : Int8 -> Int = Prim.int8ToInt;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromInt : Int -> Int8 = Prim.intToInt8;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Int8 = Prim.intToInt8Wrap;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromNat8 : Nat8 -> Int8 = Prim.nat8ToInt8;\n\n /// Conversion. Wraps on overflow/underflow.\n public let toNat8 : Int8 -> Nat8 = Prim.int8ToNat8;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Int8) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`. Traps when `x = -2^7`.\n public func abs(x : Int8) : Int8 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int8, y : Int8) : Int8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Int8, y : Int8) : Int8 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Int8, y : Int8) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int8, y : Int8) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int8, y : Int8) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int8, y : Int8) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int8, y : Int8) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int8, y : Int8) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int8, y : Int8) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`. Traps on overflow.\n public func neg(x : Int8) : Int8 { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Int8, y : Int8) : Int8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Int8, y : Int8) : Int8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Int8, y : Int8) : Int8 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int8, y : Int8) : Int8 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int8, y : Int8) : Int8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Int8, y : Int8) : Int8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Int8, y : Int8) : Int8 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Int8, y : Int8) : Int8 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Int8, y : Int8) : Int8 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Int8, y : Int8) : Int8 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Int8, y : Int8) : Int8 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Int8, y : Int8) : Int8 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Int8, y : Int8) : Int8 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Int8, y : Int8) : Int8 { x <>> y };\n\n /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`.\n public func bittest(x : Int8, p : Nat) : Bool {\n Prim.btstInt8(x, Prim.intToInt8(p));\n };\n\n /// Returns the value of setting bit `p mod 8` in `x` to `1`.\n public func bitset(x : Int8, p : Nat) : Int8 {\n x | (1 << Prim.intToInt8(p));\n };\n\n /// Returns the value of clearing bit `p mod 8` in `x` to `0`.\n public func bitclear(x : Int8, p : Nat) : Int8 {\n x & ^(1 << Prim.intToInt8(p));\n };\n\n /// Returns the value of flipping bit `p mod 8` in `x`.\n public func bitflip(x : Int8, p : Nat) : Int8 {\n x ^ (1 << Prim.intToInt8(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Int8) -> Int8 = Prim.popcntInt8;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Int8) -> Int8 = Prim.clzInt8;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Int8) -> Int8 = Prim.ctzInt8;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Int8, y : Int8) : Int8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Int8, y : Int8) : Int8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Int8, y : Int8) : Int8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n public func powWrap(x : Int8, y : Int8) : Int8 { x **% y };\n\n}\n"},"Hash.mo":{"content":"/// Hash values\n\nimport Prim \"mo:⛔\";\nimport Iter \"Iter\";\n\nmodule {\n\n /// Hash values represent a string of _hash bits_, packed into a `Nat32`.\n public type Hash = Nat32;\n\n /// The hash length, always 31.\n public let length : Nat = 31; // Why not 32?\n\n /// Project a given bit from the bit vector.\n public func bit(h : Hash, pos : Nat) : Bool {\n assert (pos <= length);\n (h & (Prim.natToNat32(1) << Prim.natToNat32(pos))) != Prim.natToNat32(0)\n };\n\n /// Test if two hashes are equal\n public func equal(ha : Hash, hb : Hash) : Bool {\n ha == hb\n };\n\n /// Computes a hash from the least significant 32-bits of `n`, ignoring other bits.\n /// @deprecated For large `Nat` values consider using a bespoke hash function that considers all of the argument's bits.\n public func hash(n : Nat) : Hash {\n let j = Prim.intToNat32Wrap(n);\n hashNat8(\n [j & (255 << 0),\n j & (255 << 8),\n j & (255 << 16),\n j & (255 << 24)\n ]);\n };\n\n /// @deprecated This function will be removed in future.\n public func debugPrintBits(bits : Hash) {\n for (j in Iter.range(0, length - 1)) {\n if (bit(bits, j)) {\n Prim.debugPrint(\"1\")\n } else {\n Prim.debugPrint(\"0\")\n }\n }\n };\n\n /// @deprecated This function will be removed in future.\n public func debugPrintBitsRev(bits : Hash) {\n for (j in Iter.revRange(length - 1, 0)) {\n if (bit(bits, Prim.abs(j))) {\n Prim.debugPrint(\"1\")\n } else {\n Prim.debugPrint(\"0\")\n }\n }\n };\n\n\n /// Jenkin's one at a time:\n ///\n /// https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time\n ///\n /// The input type should actually be `[Nat8]`.\n /// Note: Be sure to explode each `Nat8` of a `Nat32` into its own `Nat32`, and to shift into lower 8 bits.\n\n // should this really be public?\n // NB: Int.mo contains a local copy of hashNat8 (redefined to suppress the deprecation warning).\n /// @deprecated This function may be removed or changed in future.\n public func hashNat8(key : [Hash]) : Hash {\n var hash : Nat32 = 0;\n for (natOfKey in key.vals()) {\n hash := hash +% natOfKey;\n hash := hash +% hash << 10;\n hash := hash ^ (hash >> 6);\n };\n hash := hash +% hash << 3;\n hash := hash ^ (hash >> 11);\n hash := hash +% hash << 15;\n return hash;\n };\n\n}\n"},"Int64.mo":{"content":"/// 64-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 64-bit signed integers.\n public type Int64 = Prim.Types.Int64;\n\n /// Conversion.\n public let toInt : Int64 -> Int = Prim.int64ToInt;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromInt : Int -> Int64 = Prim.intToInt64;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Int64 = Prim.intToInt64Wrap;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromNat64 : Nat64 -> Int64 = Prim.nat64ToInt64;\n\n /// Conversion. Wraps on overflow/underflow.\n public let toNat64 : Int64 -> Nat64 = Prim.int64ToNat64;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Int64) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`. Traps when `x = -2^63`.\n public func abs(x : Int64) : Int64 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Int64, y : Int64) : Int64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Int64, y : Int64) : Int64 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Int64, y : Int64) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Int64, y : Int64) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Int64, y : Int64) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Int64, y : Int64) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Int64, y : Int64) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Int64, y : Int64) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Int64, y : Int64) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`. Traps on overflow.\n public func neg(x : Int64) : Int64 { -x; };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Int64, y : Int64) : Int64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Int64, y : Int64) : Int64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Int64, y : Int64) : Int64 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Int64, y : Int64) : Int64 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Int64, y : Int64) : Int64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Int64, y : Int64) : Int64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Int64, y : Int64) : Int64 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Int64, y : Int64) : Int64 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Int64, y : Int64) : Int64 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Int64, y : Int64) : Int64 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Int64, y : Int64) : Int64 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Int64, y : Int64) : Int64 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Int64, y : Int64) : Int64 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Int64, y : Int64) : Int64 { x <>> y };\n\n /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`.\n public func bittest(x : Int64, p : Nat) : Bool {\n Prim.btstInt64(x, Prim.intToInt64(p));\n };\n\n /// Returns the value of setting bit `p mod 64` in `x` to `1`.\n public func bitset(x : Int64, p : Nat) : Int64 {\n x | (1 << Prim.intToInt64(p));\n };\n\n /// Returns the value of clearing bit `p mod 64` in `x` to `0`.\n public func bitclear(x : Int64, p : Nat) : Int64 {\n x & ^(1 << Prim.intToInt64(p));\n };\n\n /// Returns the value of flipping bit `p mod 64` in `x`.\n public func bitflip(x : Int64, p : Nat) : Int64 {\n x ^ (1 << Prim.intToInt64(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Int64) -> Int64 = Prim.popcntInt64;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Int64) -> Int64 = Prim.clzInt64;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Int64) -> Int64 = Prim.ctzInt64;\n\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Int64, y : Int64) : Int64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Int64, y : Int64) : Int64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Int64, y : Int64) : Int64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n public func powWrap(x : Int64, y : Int64) : Int64 { x **% y };\n\n}\n"},"Nat.mo":{"content":"/// Natural numbers\n///\n/// Most operations on natural numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n\nimport Int \"Int\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n\n /// Infinite precision natural numbers.\n public type Nat = Prim.Types.Nat;\n\n /// Conversion.\n public let toText : Nat -> Text = Int.toText;\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat, y : Nat) : Nat {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat, y : Nat) : Nat {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat, y : Nat) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat, y : Nat) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat, y : Nat) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat, y : Nat) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat, y : Nat) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat, y : Nat) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat, y : Nat) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n public func add(x : Nat, y : Nat) : Nat { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n public func sub(x : Nat, y : Nat) : Nat { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n public func mul(x : Nat, y : Nat) : Nat { x * y };\n\n /// Returns the division of `x` by `y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat, y : Nat) : Nat { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat, y : Nat) : Nat { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n public func pow(x : Nat, y : Nat) : Nat { x ** y };\n\n}\n"},"IterType.mo":{"content":"/// The Iterator type\n\n// Just here to break cyclic module definitions\n\nmodule {\n public type Iter<T> = { next : () -> ?T };\n}\n"},"Nat16.mo":{"content":"/// 16-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 16-bit natural numbers.\n public type Nat16 = Prim.Types.Nat16;\n\n /// Conversion.\n public let toNat : Nat16 -> Nat = Prim.nat16ToNat;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromNat : Nat -> Nat16 = Prim.natToNat16;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Nat16 = Prim.intToNat16Wrap;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Nat16) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat16, y : Nat16) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat16, y : Nat16) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat16, y : Nat16) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat16, y : Nat16) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat16, y : Nat16) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat16, y : Nat16) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat16, y : Nat16) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Nat16, y : Nat16) : Nat16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Nat16, y : Nat16) : Nat16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Nat16, y : Nat16) : Nat16 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat16, y : Nat16) : Nat16 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat16, y : Nat16) : Nat16 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Nat16, y : Nat16) : Nat16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Nat16, y : Nat16) : Nat16 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Nat16, y : Nat16) : Nat16 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Nat16, y : Nat16) : Nat16 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Nat16, y : Nat16) : Nat16 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Nat16, y : Nat16) : Nat16 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Nat16, y : Nat16) : Nat16 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Nat16, y : Nat16) : Nat16 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Nat16, y : Nat16) : Nat16 { x <>> y };\n\n /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n public func bittest(x : Nat16, p : Nat) : Bool {\n Prim.btstNat16(x, Prim.natToNat16(p));\n };\n\n /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n public func bitset(x : Nat16, p : Nat) : Nat16 {\n x | (1 << Prim.natToNat16(p));\n };\n\n /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n public func bitclear(x : Nat16, p : Nat) : Nat16 {\n x & ^(1 << Prim.natToNat16(p));\n };\n\n /// Returns the value of flipping bit `p mod 16` in `x`.\n public func bitflip(x : Nat16, p : Nat) : Nat16 {\n x ^ (1 << Prim.natToNat16(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Nat16) -> Nat16 = Prim.popcntNat16;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Nat16) -> Nat16 = Prim.clzNat16;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Nat16) -> Nat16 = Prim.ctzNat16;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Nat16, y : Nat16) : Nat16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Nat16, y : Nat16) : Nat16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Nat16, y : Nat16) : Nat16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n public func powWrap(x : Nat16, y : Nat16) : Nat16 { x **% y };\n\n}\n"},"ExperimentalStableMemory.mo":{"content":"/// Byte-level access to (virtual) _stable memory_.\n///\n/// **WARNING**: As its name suggests, this library is **experimental**, subject to change\n/// and may be replaced by safer alternatives in later versions of Motoko.\n/// Use at your own risk and discretion.\n///\n/// This is a lightweight abstraction over IC _stable memory_ and supports persisting\n/// raw binary data across Motoko upgrades.\n/// Use of this module is fully compatible with Motoko's use of\n/// _stable variables_, whose persistence mechanism also uses (real) IC stable memory internally, but does not interfere with this API.\n///\n/// Memory is allocated, using `grow(pages)`, sequentially and on demand, in units of 64KiB pages, starting with 0 allocated pages.\n/// New pages are zero initialized.\n/// Growth is capped by a soft limit on page count controlled by compile-time flag\n/// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n///\n/// Each `load` operation loads from byte address `offset` in little-endian\n/// format using the natural bit-width of the type in question.\n/// The operation traps if attempting to read beyond the current stable memory size.\n///\n/// Each `store` operation stores to byte address `offset` in little-endian format using the natural bit-width of the type in question.\n/// The operation traps if attempting to write beyond the current stable memory size.\n///\n/// Text values can be handled by using `Text.decodeUtf8` and `Text.encodeUtf8`, in conjunction with `loadBlob` and `storeBlob`.\n///\n/// The current page allocation and page contents is preserved across upgrades.\n///\n/// NB: The IC's actual stable memory size (`ic0.stable_size`) may exceed the\n/// page size reported by Motoko function `size()`.\n/// This (and the cap on growth) are to accommodate Motoko's stable variables.\n/// Applications that plan to use Motoko stable variables sparingly or not at all can\n/// increase `--max-stable-pages` as desired, approaching the IC maximum (currently 8GiB).\n/// All applications should reserve at least one page for stable variable data, even when no stable variables are used.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Current size of the stable memory, in pages.\n /// Each page is 64KiB (65536 bytes).\n /// Initially `0`.\n /// Preserved across upgrades, together with contents of allocated\n /// stable memory.\n public let size : () -> (pages : Nat64) =\n Prim.stableMemorySize;\n\n /// Grow current `size` of stable memory by `pagecount` pages.\n /// Each page is 64KiB (65536 bytes).\n /// Returns previous `size` when able to grow.\n /// Returns `0xFFFF_FFFF_FFFF_FFFF` if remaining pages insufficient.\n /// Every new page is zero-initialized, containing byte 0 at every offset.\n /// Function `grow` is capped by a soft limit on `size` controlled by compile-time flag\n /// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n public let grow : (new_pages : Nat64) -> (oldpages : Nat64) =\n Prim.stableMemoryGrow;\n\n /// Returns a query that, when called, returns the number of bytes of (real) IC stable memory that would be\n /// occupied by persisting its current stable variables before an upgrade.\n /// This function may be used to monitor or limit real stable memory usage.\n /// The query computes the estimate by running the first half of an upgrade, including any `preupgrade` system method.\n /// Like any other query, its state changes are discarded so no actual upgrade (or other state change) takes place.\n /// The query can only be called by the enclosing actor and will trap for other callers.\n public let stableVarQuery : () -> (shared query () -> async {size : Nat64}) =\n Prim.stableVarQuery;\n\n public let loadNat32 : (offset : Nat64) -> Nat32 =\n Prim.stableMemoryLoadNat32;\n public let storeNat32 : (offset : Nat64, value: Nat32) -> () =\n Prim.stableMemoryStoreNat32;\n\n public let loadNat8 : (offset : Nat64) -> Nat8 =\n Prim.stableMemoryLoadNat8;\n public let storeNat8 : (offset : Nat64, value : Nat8) -> () =\n Prim.stableMemoryStoreNat8;\n\n public let loadNat16 : (offset : Nat64) -> Nat16 =\n Prim.stableMemoryLoadNat16;\n public let storeNat16 : (offset : Nat64, value : Nat16) -> () =\n Prim.stableMemoryStoreNat16;\n\n public let loadNat64 : (offset : Nat64) -> Nat64 =\n Prim.stableMemoryLoadNat64;\n public let storeNat64 : (offset : Nat64, value : Nat64) -> () =\n Prim.stableMemoryStoreNat64;\n\n public let loadInt32 : (offset : Nat64) -> Int32 =\n Prim.stableMemoryLoadInt32;\n public let storeInt32 : (offset : Nat64, value : Int32) -> () =\n Prim.stableMemoryStoreInt32;\n\n public let loadInt8 : (offset : Nat64) -> Int8 =\n Prim.stableMemoryLoadInt8;\n public let storeInt8 : (offset : Nat64, value : Int8) -> () =\n Prim.stableMemoryStoreInt8;\n\n public let loadInt16 : (offset : Nat64) -> Int16 =\n Prim.stableMemoryLoadInt16;\n public let storeInt16 : (offset : Nat64, value : Int16) -> () =\n Prim.stableMemoryStoreInt16;\n\n public let loadInt64 : (offset : Nat64) -> Int64 =\n Prim.stableMemoryLoadInt64;\n public let storeInt64 : (offset : Nat64, value : Int64) -> () =\n Prim.stableMemoryStoreInt64;\n\n public let loadFloat : (offset : Nat64) -> Float =\n Prim.stableMemoryLoadFloat;\n public let storeFloat : (offset : Nat64, value : Float) -> () =\n Prim.stableMemoryStoreFloat;\n\n /// Load `size` bytes starting from `offset` as a `Blob`.\n /// Traps on out-of-bounds access.\n public let loadBlob : (offset : Nat64, size : Nat) -> Blob =\n Prim.stableMemoryLoadBlob;\n\n /// Write bytes of `blob` beginning at `offset`.\n /// Traps on out-of-bounds access.\n public let storeBlob : (offset : Nat64, value : Blob) -> () =\n Prim.stableMemoryStoreBlob;\n\n}\n"},"Order.mo":{"content":"/// Order\n\nmodule {\n\n /// A type to represent an order.\n public type Order = {\n #less;\n #equal;\n #greater;\n };\n\n /// Check if an order is #less.\n public func isLess(order : Order) : Bool {\n switch order {\n case (#less) { true };\n case _ { false };\n };\n };\n\n /// Check if an order is #equal.\n public func isEqual(order : Order) : Bool {\n switch order {\n case (#equal) { true };\n case _ { false };\n };\n };\n\n /// Check if an order is #greater.\n public func isGreater(order : Order) : Bool {\n switch order {\n case (#greater) { true };\n case _ { false };\n };\n };\n\n /// Returns true if only if `o1` and `o2` are the same ordering.\n public func equal(o1 : Order, o2: Order) : Bool {\n switch (o1, o2) {\n case (#less, #less) { true };\n case (#equal, #equal) { true };\n case (#greater, #greater) { true };\n case _ { false };\n };\n };\n\n};\n"},"Option.mo":{"content":"/// Typesafe nulls\n///\n/// Optional values can be seen as a typesafe `null`. A value of type `?Int` can\n/// be constructed with either `null` or `?42`. The simplest way to get at the\n/// contents of an optional is to use pattern matching:\n///\n/// ```motoko\n/// let optionalInt1 : ?Int = ?42;\n/// let optionalInt2 : ?Int = null;\n///\n/// let int1orZero : Int = switch optionalInt1 {\n/// case null 0;\n/// case (?int) int;\n/// };\n/// assert int1orZero == 42;\n///\n/// let int2orZero : Int = switch optionalInt2 {\n/// case null 0;\n/// case (?int) int;\n/// };\n/// assert int2orZero == 0;\n/// ```\n///\n/// The functions in this module capture some common operations when working\n/// with optionals that can be more succinct than using pattern matching.\n\nimport P \"Prelude\";\n\nmodule {\n\n /// Unwraps an optional value, with a default value, i.e. `get(?x, d) = x` and\n /// `get(null, d) = d`.\n public func get<T>(x : ?T, default : T) : T =\n switch x {\n case null { default };\n case (?x_) { x_ };\n };\n\n /// Unwraps an optional value using a function, or returns the default, i.e.\n /// `option(?x, f, d) = f x` and `option(null, f, d) = d`.\n public func getMapped<A, B>(x : ?A, f : A -> B, default : B) : B =\n switch x {\n case null { default };\n case (?x_) { f(x_) };\n };\n\n /// Applies a function to the wrapped value. `null`'s are left untouched.\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// assert Option.map<Nat, Nat>(?42, func x = x + 1) == ?43;\n /// assert Option.map<Nat, Nat>(null, func x = x + 1) == null;\n /// ```\n public func map<A, B>(x : ?A, f : A -> B) : ?B =\n switch x {\n case null { null };\n case (?x_) { ?f(x_) };\n };\n\n /// Applies a function to the wrapped value, but discards the result. Use\n /// `iterate` if you're only interested in the side effect `f` produces.\n ///\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// var counter : Nat = 0;\n /// Option.iterate(?5, func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// Option.iterate(null, func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// ```\n public func iterate<A>(x : ?A, f : A -> ()) =\n switch x {\n case null {};\n case (?x_) { f(x_) };\n };\n\n /// Applies an optional function to an optional value. Returns `null` if at\n /// least one of the arguments is `null`.\n public func apply<A, B>(x : ?A, f : ?(A -> B)) : ?B {\n switch (f, x) {\n case (?f_, ?x_) {\n ?f_(x_);\n };\n case (_, _) {\n null;\n };\n };\n };\n\n /// Applies a function to an optional value. Returns `null` if the argument is\n /// `null`, or the function returns `null`.\n public func chain<A, B>(x : ?A, f : A -> ?B) : ?B {\n switch(x) {\n case (?x_) {\n f(x_);\n };\n case (null) {\n null;\n };\n };\n };\n\n /// Given an optional optional value, removes one layer of optionality.\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// assert Option.flatten(?(?(42))) == ?42;\n /// assert Option.flatten(?(null)) == null;\n /// assert Option.flatten(null) == null;\n /// ```\n public func flatten<A>(x : ??A) : ?A {\n chain<?A, A>(x, func (x_ : ?A) : ?A {\n x_;\n });\n };\n\n /// Creates an optional value from a definite value.\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// assert Option.make(42) == ?42;\n /// ```\n public func make<A>(x: A) : ?A = ?x;\n\n /// Returns true if the argument is not `null`, otherwise returns false.\n public func isSome(x : ?Any) : Bool =\n switch x {\n case null { false };\n case _ { true };\n };\n\n /// Returns true if the argument is `null`, otherwise returns false.\n public func isNull(x : ?Any) : Bool =\n switch x {\n case null { true };\n case _ { false };\n };\n\n /// Asserts that the value is not `null`; fails otherwise.\n /// @deprecated Option.assertSome will be removed soon; use an assert expression instead\n public func assertSome(x : ?Any) =\n switch x {\n case null { P.unreachable() };\n case _ {};\n };\n\n /// Asserts that the value _is_ `null`; fails otherwise.\n /// @deprecated Option.assertNull will be removed soon; use an assert expression instead\n public func assertNull(x : ?Any) =\n switch x {\n case null { };\n case _ { P.unreachable() };\n };\n\n /// Unwraps an optional value, i.e. `unwrap(?x) = x`.\n ///\n /// @deprecated Option.unwrap is unsafe and fails if the argument is null; it will be removed soon; use a `switch` or `do?` expression instead\n public func unwrap<T>(x : ?T) : T =\n switch x {\n case null { P.unreachable() };\n case (?x_) { x_ };\n };\n}\n"},"Stack.mo":{"content":"/// Stack collection (LIFO discipline).\n///\n/// Minimal LIFO (last in first out) implementation, as a class.\n/// See library `Deque` for mixed LIFO/FIFO behavior.\n///\nimport List \"List\";\n\nmodule {\n\n public class Stack<T>() {\n\n var stack : List.List<T> = List.nil<T>();\n\n /// Push an element on the top of the stack.\n public func push(x:T) {\n stack := ?(x, stack)\n };\n\n /// True when the stack is empty.\n public func isEmpty() : Bool {\n List.isNil<T>(stack)\n };\n\n /// Return and retain the top element, or return null.\n public func peek() : ?T {\n switch stack {\n case null { null };\n case (?(h, t)) { ?h };\n }\n };\n\n /// Remove and return the top element, or return null.\n public func pop() : ?T {\n switch stack {\n case null { null };\n case (?(h, t)) { stack := t; ?h };\n }\n };\n };\n}\n"},"Prelude.mo":{"content":"/// General utilities\n///\n/// This prelude file proposes standard library features that _may_\n/// belong in the _language_ (compiler-internal) prelude sometime, after\n/// some further experience and discussion. Until then, they live here.\n\nimport Debug \"Debug\";\n\nmodule {\n\n /// Not yet implemented\n ///\n /// Mark incomplete code with the `nyi` and `xxx` functions.\n ///\n /// Each have calls are well-typed in all typing contexts, which\n /// trap in all execution contexts.\n public func nyi() : None {\n Debug.trap(\"Prelude.nyi()\");\n };\n\n public func xxx() : None {\n Debug.trap(\"Prelude.xxx()\");\n };\n\n /// Mark unreachable code with the `unreachable` function.\n ///\n /// Calls are well-typed in all typing contexts, and they\n /// trap in all execution contexts.\n public func unreachable() : None {\n Debug.trap(\"Prelude.unreachable()\")\n };\n\n}\n"},"RBTree.mo":{"content":"/// Red-Black Trees\n\nimport Debug \"Debug\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\nmodule {\n\n /// Node color: red or black.\n public type Color = { #R; #B };\n\n /// Ordered, (red-black) tree of entries.\n public type Tree<X, Y> = {\n #node : (Color, Tree<X, Y>, (X, ?Y), Tree<X, Y>);\n #leaf;\n };\n\n /// Create an order map from an order function for its keys.\n public class RBTree<X, Y>(compareTo : (X, X) -> O.Order) {\n\n var tree : Tree<X, Y> = (#leaf : Tree<X, Y>);\n\n /// Tree as sharable data.\n ///\n /// Get non-OO, purely-functional representation:\n /// for drawing, pretty-printing and non-OO contexts\n /// (e.g., async args and results):\n public func share() : Tree<X, Y> {\n tree\n };\n\n /// Get the value associated with a given key.\n public func get(x : X) : ?Y {\n getRec(x, compareTo, tree);\n };\n\n /// Replace the value associated with a given key.\n public func replace(x : X, y : Y) : ?Y {\n let (res, t) = insertRoot(x, compareTo, y, tree);\n tree := t;\n res\n };\n\n /// Put an entry: A value associated with a given key.\n public func put(x : X, y : Y) {\n let (res, t) = insertRoot(x, compareTo, y, tree);\n tree := t;\n };\n\n /// Delete the entry associated with a given key.\n public func delete(x : X) {\n let (res, t) = removeRec(x, compareTo, tree);\n tree := t\n };\n\n /// Remove the entry associated with a given key.\n public func remove(x : X) : ?Y {\n let (res, t) = removeRec(x, compareTo, tree);\n tree := t;\n res\n };\n\n /// An iterator for the key-value entries of the map, in ascending key order.\n ///\n /// iterator is persistent, like the tree itself\n public func entries() : I.Iter<(X, Y)> { iter(tree, #fwd) };\n\n /// An iterator for the key-value entries of the map, in descending key order.\n ///\n /// iterator is persistent, like the tree itself\n public func entriesRev() : I.Iter<(X, Y)> { iter(tree, #bwd) };\n\n };\n\n\n type IterRep<X, Y> = List.List<{ #tr:Tree<X, Y>; #xy:(X, ?Y) }>;\n\n /// An iterator for the entries of the map, in ascending (`#fwd`) or descending (`#bwd`) order.\n public func iter<X, Y>(t : Tree<X, Y>, dir : { #fwd; #bwd }) : I.Iter<(X, Y)> {\n object {\n var trees : IterRep<X, Y> = ?(#tr(t), null);\n public func next() : ?(X, Y) {\n switch (dir, trees) {\n case (_, null) { null };\n case (_, ?(#tr(#leaf), ts)){\n trees := ts;\n next()\n };\n case (_, ?(#xy(xy), ts)) {\n trees := ts;\n switch (xy.1) {\n case null { next() };\n case (?y) { ?(xy.0, y) }\n }\n };\n case (#fwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n trees := ?(#tr(l), ?(#xy(xy), ?(#tr(r), ts)));\n next()\n };\n case (#bwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n trees := ?(#tr(r), ?(#xy(xy), ?(#tr(l), ts)));\n next()\n };\n }\n };\n }\n };\n\n /// Remove the value associated with a given key.\n func removeRec<X, Y>(x : X, compareTo : (X, X) -> O.Order, t : Tree<X, Y>)\n : (?Y, Tree<X, Y>) {\n switch t {\n case (#leaf) { (null, #leaf) };\n case (#node(c, l, xy, r)) {\n switch (compareTo(x, xy.0)) {\n case (#less) {\n let (yo, l2) = removeRec(x, compareTo, l);\n (yo, #node(c, l2, xy, r))\n };\n case (#equal) {\n (xy.1, #node(c, l, (x, null), r))\n };\n case (#greater) {\n let (yo, r2) = removeRec(x, compareTo, r);\n (yo, #node(c, l, xy, r2))\n };\n }\n }\n }\n };\n\n\n\n func bal<X, Y>(color : Color, lt : Tree<X, Y>, kv : (X, ?Y), rt : Tree<X, Y>) : Tree<X, Y> {\n // thank you, algebraic pattern matching!\n // following notes from [Ravi Chugh](https://www.classes.cs.uchicago.edu/archive/2019/spring/22300-1/lectures/RedBlackTrees/index.html)\n switch (color, lt, kv, rt) {\n case (#B, #node(#R, #node(#R, a, x, b), y, c), z, d) {\n #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n };\n case (#B, #node(#R, a, x, #node(#R, b, y, c)), z, d) {\n #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n };\n case (#B, a, x, #node(#R, #node(#R, b, y, c), z, d)) {\n #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n };\n case (#B, a, x, #node(#R, b, y, #node(#R, c, z, d))) {\n #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n };\n case _ { #node(color, lt, kv, rt) };\n }\n };\n\n func insertRoot<X, Y>(x : X, compareTo : (X, X) -> O.Order, y : Y, t : Tree<X, Y>)\n : (?Y, Tree<X, Y>) {\n switch (insertRec(x, compareTo, y, t)) {\n case (_, #leaf) { assert false; loop { } };\n case (yo, #node(_, l, xy, r)) { (yo, #node(#B, l, xy, r)) };\n }\n };\n\n func insertRec<X, Y>(x : X, compareTo : (X, X) -> O.Order, y : Y, t : Tree<X, Y>)\n : (?Y, Tree<X, Y>) {\n switch t {\n case (#leaf) { (null, #node(#R, #leaf, (x, ?y), #leaf)) };\n case (#node(c, l, xy, r)) {\n switch (compareTo(x, xy.0)) {\n case (#less) {\n let (yo, l2) = insertRec(x, compareTo, y, l);\n (yo, bal(c, l2, xy, r))\n };\n case (#equal) {\n (xy.1, #node(c, l, (x, ?y), r))\n };\n case (#greater) {\n let (yo, r2) = insertRec(x, compareTo, y, r);\n (yo, bal(c, l, xy, r2))\n };\n }\n }\n }\n };\n\n func getRec<X, Y>(x : X, compareTo : (X, X) -> O.Order, t : Tree<X, Y>) : ?Y {\n switch t {\n case (#leaf) { null };\n case (#node(c, l, xy, r)) {\n switch (compareTo(x, xy.0)) {\n case (#less) { getRec(x, compareTo, l) };\n case (#equal) { xy.1 };\n case (#greater) { getRec(x, compareTo, r) };\n }\n };\n }\n };\n\n func height<X, Y>(t : Tree<X, Y>) : Nat {\n switch t {\n case (#leaf) { 0 };\n case (#node(_, l, _, r)) {\n Nat.max(height(l), height(r)) + 1\n }\n }\n };\n\n /// The size of the tree as the number of key-value entries.\n public func size<X, Y>(t : Tree<X, Y>) : Nat {\n switch t {\n case (#leaf) { 0 };\n case (#node(_, l, xy, r)) {\n size(l) + size(r) + (switch (xy.1) { case null 0; case _ 1 });\n };\n }\n };\n\n}\n"},"Principal.mo":{"content":"/// IC principals (user and canister smart contract IDs)\n\nimport Prim \"mo:⛔\";\nimport Blob \"Blob\";\nimport Hash \"Hash\";\nmodule {\n\n /// Internet Computer principal identifiers.\n /// Convert to `Blob` for access to bytes.\n public type Principal = Prim.Types.Principal;\n\n /// Conversion.\n public let fromActor : (a : actor {}) -> Principal = Prim.principalOfActor;\n\n /// Conversion.\n public let toBlob : (p : Principal) -> Blob = Prim.blobOfPrincipal;\n\n /// Conversion.\n public let fromBlob : (b : Blob) -> Principal = Prim.principalOfBlob;\n \n /// Conversion.\n public func toText(p : Principal) : Text = debug_show(p);\n\n private let anonymousPrincipal : Blob = \"\\04\";\n\n public func isAnonymous(p : Principal) : Bool =\n Prim.blobOfPrincipal p == anonymousPrincipal;\n\n public func hash(principal : Principal) : Hash.Hash =\n Blob.hash (Prim.blobOfPrincipal(principal));\n\n public func fromText(t : Text) : Principal = fromActor(actor(t));\n\n /// Returns `x == y`.\n public func equal(x : Principal, y : Principal) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Principal, y : Principal) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Principal, y : Principal) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Principal, y : Principal) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Principal, y : Principal) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Principal, y : Principal) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Principal, y : Principal) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n}\n"},"TrieMap.mo":{"content":"/// Key-value hash maps.\n///\n/// An imperative hash map, with a general key and value type.\n///\n/// - The `class` `TrieMap` exposes the same interface as `HashMap`.\n///\n/// - Unlike HashMap, the internal representation uses a functional representation (via `Trie` module).\n///\n/// - This class does not permit a direct `clone` operation (neither does `HashMap`), but it does permit creating iterators via `iter()`. Each iterator costs `O(1)` to create, but represents a fixed view of the mapping that does not interfere with mutations (it will _not_ reflect subsequent insertions or mutations, if any).\n\nimport T \"Trie\";\nimport P \"Prelude\";\nimport I \"Iter\";\nimport Hash \"Hash\";\nimport List \"List\";\n\n/// An imperative hash-based map with a minimal object-oriented interface.\n/// Maps keys of type `K` to values of type `V`.\n///\n/// See also the `HashMap` module, with a matching interface.\n/// Unlike HashMap, the iterators are persistent (pure), clones are cheap and the maps have an efficient persistent representation.\n\nmodule {\n\n public class TrieMap<K, V> (isEq : (K, K) -> Bool, hashOf : K -> Hash.Hash) {\n\n var map = T.empty<K, V>();\n var _size : Nat = 0;\n\n /// Returns the number of entries in the map.\n public func size() : Nat { _size };\n\n /// Associate a key and value, overwriting any prior association for the key.\n public func put(k : K, v : V) =\n ignore replace(k, v);\n\n /// Put the key and value, _and_ return the (optional) prior value for the key.\n public func replace(k : K, v : V) : ?V {\n let keyObj = { key = k; hash = hashOf(k) };\n let (map2, ov) =\n T.put<K,V>(map, keyObj, isEq, v);\n map := map2;\n switch (ov) {\n case null { _size += 1 };\n case _ {}\n };\n ov\n };\n\n /// Get the (optional) value associated with the given key.\n public func get(k : K) : ?V {\n let keyObj = {key = k; hash = hashOf(k);};\n T.find<K, V>(map, keyObj, isEq)\n };\n\n /// Delete the (optional) value associated with the given key.\n public func delete(k : K) =\n ignore remove(k);\n\n /// Delete and return the (optional) value associated with the given key.\n public func remove(k : K) : ?V {\n let keyObj = { key = k; hash = hashOf(k) };\n let (t, ov) = T.remove<K, V>(map, keyObj, isEq);\n map := t;\n switch (ov) {\n case null {};\n case (?_) { _size -= 1 }\n };\n ov\n };\n\n /// An `Iter` over the keys.\n ///\n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n public func keys() : I.Iter<K>\n { I.map(entries(), func (kv : (K, V)) : K { kv.0 }) };\n\n /// An `Iter` over the values.\n ///\n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n public func vals() : I.Iter<V>\n { I.map(entries(), func (kv : (K, V)) : V { kv.1 }) };\n\n /// Returns an `Iter` over the entries.\n ///\n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n public func entries() : I.Iter<(K, V)> {\n object {\n var stack = ?(map, null) : List.List<T.Trie<K, V>>;\n public func next() : ?(K, V) {\n switch stack {\n case null { null };\n case (?(trie, stack2)) {\n switch trie {\n case (#empty) {\n stack := stack2;\n next()\n };\n case (#leaf({keyvals = null})) {\n stack := stack2;\n next()\n };\n case (#leaf({size = c; keyvals = ?((k, v), kvs)})) {\n stack := ?(#leaf({size=c-1; keyvals=kvs}), stack2);\n ?(k.key, v)\n };\n case (#branch(br)) {\n stack := ?(br.left, ?(br.right, stack2));\n next()\n };\n }\n }\n }\n }\n }\n }\n };\n\n\n /// Clone the map, given its key operations.\n public func clone<K, V>(\n h : TrieMap<K, V>,\n keyEq : (K,K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : TrieMap<K, V> {\n let h2 = TrieMap<K, V>(keyEq, keyHash);\n for ((k, v) in h.entries()) {\n h2.put(k, v);\n };\n h2\n };\n\n /// Clone an iterator of key-value pairs.\n public func fromEntries<K, V>(\n entries : I.Iter<(K, V)>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : TrieMap<K, V> {\n let h = TrieMap<K, V>(keyEq, keyHash);\n for ((k, v) in entries) {\n h.put(k, v);\n };\n h\n };\n\n /// Transform (map) the values of a map, retaining its keys.\n public func map<K, V1, V2> (\n h : TrieMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n mapFn : (K, V1) -> V2,\n ) : TrieMap<K, V2> {\n let h2 = TrieMap<K, V2>(keyEq, keyHash);\n for ((k, v1) in h.entries()) {\n let v2 = mapFn(k, v1);\n h2.put(k, v2);\n };\n h2\n };\n\n /// Transform and filter the values of a map, retaining its keys.\n public func mapFilter<K, V1, V2>(\n h : TrieMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n mapFn : (K, V1) -> ?V2,\n ) : TrieMap<K, V2> {\n let h2 = TrieMap<K, V2>(keyEq, keyHash);\n for ((k, v1) in h.entries()) {\n switch (mapFn(k, v1)) {\n case null { };\n case (?v2) {\n h2.put(k, v2);\n };\n }\n };\n h2\n };\n\n}\n"},"TrieSet.mo":{"content":"/// Functional set\n///\n/// Sets are partial maps from element type to unit type,\n/// i.e., the partial map represents the set with its domain.\n\n// TODO-Matthew:\n// ---------------\n//\n// - for now, we pass a hash value each time we pass an element value;\n// in the future, we might avoid passing element hashes with each element in the API;\n// related to: https://dfinity.atlassian.net/browse/AST-32\n//\n// - similarly, we pass an equality function when we do some operations.\n// in the future, we might avoid this via https://dfinity.atlassian.net/browse/AST-32\nimport Trie \"Trie\";\nimport Hash \"Hash\";\nimport List \"List\";\n\nmodule {\n\n public type Hash = Hash.Hash;\n public type Set<T> = Trie.Trie<T,()>;\n\n /// Empty set.\n public func empty<T>() : Set<T> { Trie.empty<T,()>(); };\n\n /// Put an element into the set.\n public func put<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n let (s2, _) = Trie.put<T,()>(s, { key = x; hash = xh }, eq, ());\n s2\n };\n\n /// Delete an element from the set.\n public func delete<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n let (s2, _) = Trie.remove<T, ()>(s, { key = x; hash = xh }, eq);\n s2\n };\n\n /// Test if two sets are equal.\n public func equal<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Bool {\n // XXX: Todo: use a smarter check\n func unitEqual (_ : (),_ : ()) : Bool { true };\n Trie.equalStructure<T, ()>(s1, s2, eq, unitEqual)\n };\n\n /// The number of set elements, set's cardinality.\n public func size<T>(s : Set<T>) : Nat {\n Trie.foldUp<T, (), Nat>(\n s,\n func(n : Nat, m : Nat) : Nat { n + m },\n func(_ : T, _ : ()) : Nat { 1 },\n 0\n )\n };\n\n /// Test if a set contains a given element.\n public func mem<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Bool {\n switch (Trie.find<T, ()>(s, { key = x; hash = xh }, eq)) {\n case null { false };\n case (?_) { true };\n }\n };\n\n /// [Set union](https://en.wikipedia.org/wiki/Union_(set_theory)).\n public func union<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let s3 = Trie.merge<T, ()>(s1, s2, eq);\n s3\n };\n\n /// [Set difference](https://en.wikipedia.org/wiki/Difference_(set_theory)).\n public func diff<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let s3 = Trie.diff<T, (), ()>(s1, s2, eq);\n s3\n };\n\n /// [Set intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)).\n public func intersect<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let noop : ((), ()) -> (()) = func (_ : (), _ : ()) : (()) = ();\n let s3 = Trie.join<T, (), (), ()>(s1, s2, eq, noop);\n s3\n };\n\n //// Construct a set from an array.\n public func fromArray<T>(arr : [T], elemHash : T -> Hash, eq : (T, T) -> Bool) : Set<T> {\n var s = empty<T>();\n for (elem in arr.vals()) {\n s := put<T>(s, elem, elemHash(elem), eq);\n };\n s\n };\n\n //// Returns the set as an array.\n public func toArray<T>(s : Set<T>): [T] {\n Trie.toArray(s, func (t : T, _ : ()) : T { t })\n }\n\n}\n"},"Time.mo":{"content":"/// System time\n\nimport Prim \"mo:⛔\";\nmodule {\n\n /// System time is represent as nanoseconds since 1970-01-01.\n public type Time = Int;\n\n /// Current system time given as nanoseconds since 1970-01-01. The system guarantees that:\n ///\n /// * the time, as observed by the canister smart contract, is monotonically increasing, even across canister upgrades.\n /// * within an invocation of one entry point, the time is constant.\n ///\n /// The system times of different canisters are unrelated, and calls from one canister to another may appear to travel \"backwards in time\"\n ///\n /// Note: While an implementation will likely try to keep the system time close to the real time, this is not formally guaranteed.\n public let now : () -> Time =\n func () : Int = Prim.nat64ToNat(Prim.time());\n ///\n /// The following example illustrates using the system time:\n ///\n /// ```motoko\n /// import Int = \"mo:base/Int\";\n /// import Time = \"mo:base/Time\";\n ///\n /// actor {\n /// var lastTime = Time.now();\n /// public func greet(name : Text) : async Text {\n /// let now = Time.now();\n /// let elapsedSeconds = (now - lastTime) / 1000_000_000;\n /// lastTime := now;\n /// return \"Hello, \" # name # \"!\" #\n /// \" I was last called \" # Int.toText(elapsedSeconds) # \" seconds ago\";\n /// };\n /// };\n /// ```\n}\n"},"Random.mo":{"content":"/// A module for obtaining randomness on the Internet Computer (IC).\n///\n/// This module provides the fundamentals for user abstractions to build on.\n///\n/// Dealing with randomness on a deterministic computing platform, such\n/// as the IC, is intricate. Some basic rules need to be followed by the\n/// user of this module to obtain (and maintain) the benefits of crypto-\n/// graphic randomness:\n///\n/// - cryptographic entropy (randomness source) is only obtainable\n/// asyncronously in discrete chunks of 256 bits (32-byte sized `Blob`s)\n/// - all bets must be closed *before* entropy is being asked for in\n/// order to decide them\n/// - this implies that the same entropy (i.e. `Blob`) - or surplus entropy\n/// not utilised yet - cannot be used for a new round of bets without\n/// losing the cryptographic guarantees.\n///\n/// Concretely, the below class `Finite`, as well as the\n/// `*From` methods risk the carrying-over of state from previous rounds.\n/// These are provided for performance (and convenience) reasons, and need\n/// special care when used. Similar caveats apply for user-defined (pseudo)\n/// random number generators.\n\nimport I \"Iter\";\nimport Option \"Option\";\nimport P \"Prelude\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Drawing from a finite supply of entropy, `Finite` provides\n /// methods to obtain random values. When the entropy is used up,\n /// `null` is returned. Otherwise the outcomes' distributions are\n /// stated for each method. The uniformity of outcomes is\n /// guaranteed only when the supplied entropy is originally obtained\n /// by the `blob()` call, and is never reused.\n public class Finite(entropy : Blob) {\n let it : I.Iter<Nat8> = entropy.vals();\n\n /// Uniformly distributes outcomes in the numeric range [0 .. 255].\n /// Consumes 1 byte of entropy.\n public func byte() : ?Nat8 {\n it.next()\n };\n\n /// Bool iterator splitting up a byte of entropy into 8 bits\n let bit : I.Iter<Bool> = object {\n var mask = 0x80 : Nat8;\n var byte = 0x00 : Nat8;\n public func next() : ?Bool {\n if (0 : Nat8 == mask) {\n switch (it.next()) {\n case null { null };\n case (?w) {\n byte := w;\n mask := 0x40;\n ?(0 : Nat8 != byte & (0x80 : Nat8))\n }\n }\n } else {\n let m = mask;\n mask >>= (1 : Nat8);\n ?(0 : Nat8 != byte & m)\n }\n }\n };\n\n /// Simulates a coin toss. Both outcomes have equal probability.\n /// Consumes 1 bit of entropy (amortised).\n public func coin() : ?Bool {\n bit.next()\n };\n\n /// Uniformly distributes outcomes in the numeric range [0 .. 2^p - 1].\n /// Consumes ⌈p/8⌉ bytes of entropy.\n public func range(p : Nat8) : ?Nat {\n var pp = p;\n var acc : Nat = 0;\n for (i in it) {\n if (8 : Nat8 <= pp)\n { acc := acc * 256 + Prim.nat8ToNat(i) }\n else if (0 : Nat8 == pp)\n { return ?acc }\n else {\n acc *= Prim.nat8ToNat(1 << pp);\n let mask : Nat8 = 0xff >> (8 - pp);\n return ?(acc + Prim.nat8ToNat(i & mask))\n };\n pp -= 8\n };\n null\n };\n\n /// Counts the number of heads in `n` fair coin tosses.\n /// Consumes ⌈p/8⌉ bytes of entropy.\n public func binomial(n : Nat8) : ?Nat8 {\n var nn = n;\n var acc : Nat8 = 0;\n for (i in it) {\n if (8 : Nat8 <= nn)\n { acc +%= Prim.popcntNat8(i) }\n else if (0 : Nat8 == nn)\n { return ?acc }\n else {\n let mask : Nat8 = 0xff << (8 - nn);\n let residue = Prim.popcntNat8(i & mask);\n return ?(acc +% residue)\n };\n nn -= 8\n };\n null\n }\n };\n\n let raw_rand = (actor \"aaaaa-aa\" : actor { raw_rand : () -> async Blob }).raw_rand;\n\n /// Distributes outcomes in the numeric range [0 .. 255].\n /// Seed blob must contain at least a byte.\n public func byteFrom(seed : Blob) : Nat8 {\n switch (seed.vals().next()) {\n case (?w) { w };\n case _ { P.unreachable() };\n }\n };\n\n /// Simulates a coin toss.\n /// Seed blob must contain at least a byte.\n public func coinFrom(seed : Blob) : Bool {\n switch (seed.vals().next()) {\n case (?w) { w > (127 : Nat8) };\n case _ { P.unreachable() };\n }\n };\n\n /// Obtains a full blob (32 bytes) worth of fresh entropy.\n public let blob : shared () -> async Blob = raw_rand;\n\n /// Distributes outcomes in the numeric range [0 .. 2^p - 1].\n /// Seed blob must contain at least ((p+7) / 8) bytes.\n public func rangeFrom(p : Nat8, seed : Blob) : Nat {\n rangeIter(p, seed.vals())\n };\n\n // internal worker method, expects iterator with sufficient supply\n func rangeIter(p : Nat8, it : I.Iter<Nat8>) : Nat {\n var pp = p;\n var acc : Nat = 0;\n for (i in it) {\n if (8 : Nat8 <= pp)\n { acc := acc * 256 + Prim.nat8ToNat(i) }\n else if (0 : Nat8 == pp)\n { return acc }\n else {\n acc *= Prim.nat8ToNat(1 << pp);\n let mask : Nat8 = 0xff >> (8 - pp);\n return acc + Prim.nat8ToNat(i & mask)\n };\n pp -= 8\n };\n P.unreachable()\n };\n\n /// Counts the number of heads in `n` coin tosses.\n /// Seed blob must contain at least ((n+7) / 8) bytes.\n public func binomialFrom(n : Nat8, seed : Blob) : Nat8 {\n binomialIter(n, seed.vals())\n };\n\n // internal worker method, expects iterator with sufficient supply\n func binomialIter(n : Nat8, it : I.Iter<Nat8>) : Nat8 {\n var nn = n;\n var acc : Nat8 = 0;\n for (i in it) {\n if (8 : Nat8 <= nn)\n { acc +%= Prim.popcntNat8(i) }\n else if (0 : Nat8 == nn)\n { return acc }\n else {\n let mask : Nat8 = 0xff << (8 - nn);\n let residue = Prim.popcntNat8(i & mask);\n return (acc +% residue)\n };\n nn -= 8\n };\n P.unreachable()\n }\n\n}\n"},"Result.mo":{"content":"/// Error handling with the Result type.\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport Order \"Order\";\n\nmodule {\n\n /// `Result<Ok, Err>` is the type used for returning and propagating errors. It\n /// is a type with the variants, `#ok(Ok)`, representing success and containing\n /// a value, and `#err(Err)`, representing error and containing an error value.\n ///\n /// The simplest way of working with `Result`s is to pattern match on them:\n ///\n /// For example, given a function `createUser(user : User) : Result<Id, String>`\n /// where `String` is an error message we could use it like so:\n /// ```motoko no-repl\n /// switch(createUser(myUser)) {\n /// case (#ok(id)) { Debug.print(\"Created new user with id: \" # id) };\n /// case (#err(msg)) { Debug.print(\"Failed to create user with the error: \" # msg) };\n /// }\n /// ```\n public type Result<Ok, Err> = {\n #ok : Ok;\n #err : Err;\n };\n\n // Compares two Result's for equality.\n public func equal<Ok, Err>(\n eqOk : (Ok, Ok) -> Bool,\n eqErr : (Err, Err) -> Bool,\n r1 : Result<Ok, Err>,\n r2 : Result<Ok, Err>\n ) : Bool {\n switch (r1, r2) {\n case (#ok(ok1), #ok(ok2)) {\n eqOk(ok1, ok2)\n };\n case (#err(err1), #err(err2)) {\n eqErr(err1, err2);\n };\n case _ { false };\n };\n };\n\n // Compares two Results. `#ok` is larger than `#err`. This ordering is\n // arbitrary, but it lets you for example use Results as keys in ordered maps.\n public func compare<Ok, Err>(\n compareOk : (Ok, Ok) -> Order.Order,\n compareErr : (Err, Err) -> Order.Order,\n r1 : Result<Ok, Err>,\n r2 : Result<Ok, Err>\n ) : Order.Order {\n switch (r1, r2) {\n case (#ok(ok1), #ok(ok2)) {\n compareOk(ok1, ok2)\n };\n case (#err(err1), #err(err2)) {\n compareErr(err1, err2)\n };\n case (#ok(_), _) { #greater };\n case (#err(_), _) { #less };\n };\n };\n\n /// Allows sequencing of `Result` values and functions that return\n /// `Result`'s themselves.\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// type Result<T,E> = Result.Result<T, E>;\n /// func largerThan10(x : Nat) : Result<Nat, Text> =\n /// if (x > 10) { #ok(x) } else { #err(\"Not larger than 10.\") };\n ///\n /// func smallerThan20(x : Nat) : Result<Nat, Text> =\n /// if (x < 20) { #ok(x) } else { #err(\"Not smaller than 20.\") };\n ///\n /// func between10And20(x : Nat) : Result<Nat, Text> =\n /// Result.chain(largerThan10(x), smallerThan20);\n ///\n /// assert(between10And20(15) == #ok(15));\n /// assert(between10And20(9) == #err(\"Not larger than 10.\"));\n /// assert(between10And20(21) == #err(\"Not smaller than 20.\"));\n /// ```\n public func chain<R1, R2, Error>(\n x : Result<R1, Error>,\n y : R1 -> Result<R2, Error>\n ) : Result<R2, Error> {\n switch x {\n case (#err(e)) { #err(e) };\n case (#ok(r)) { y(r) };\n }\n };\n\n /// Flattens a nested Result.\n ///\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// assert(Result.flatten<Nat, Text>(#ok(#ok(10))) == #ok(10));\n /// assert(Result.flatten<Nat, Text>(#err(\"Wrong\")) == #err(\"Wrong\"));\n /// assert(Result.flatten<Nat, Text>(#ok(#err(\"Wrong\"))) == #err(\"Wrong\"));\n /// ```\n public func flatten<Ok, Error>(\n result : Result<Result<Ok, Error>, Error>\n ) : Result<Ok, Error> {\n switch result {\n case (#ok(ok)) { ok };\n case (#err(err)) { #err(err) };\n }\n };\n\n\n /// Maps the `Ok` type/value, leaving any `Error` type/value unchanged.\n public func mapOk<Ok1, Ok2, Error>(\n x : Result<Ok1, Error>,\n f : Ok1 -> Ok2\n ) : Result<Ok2, Error> {\n switch x {\n case (#err(e)) { #err(e) };\n case (#ok(r)) { #ok(f(r)) };\n }\n };\n\n /// Maps the `Err` type/value, leaving any `Ok` type/value unchanged.\n public func mapErr<Ok, Error1, Error2>(\n x : Result<Ok, Error1>,\n f : Error1 -> Error2\n ) : Result<Ok, Error2> {\n switch x {\n case (#err(e)) { #err (f(e)) };\n case (#ok(r)) { #ok(r) };\n }\n };\n\n /// Create a result from an option, including an error value to handle the `null` case.\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// assert(Result.fromOption(?42, \"err\") == #ok(42));\n /// assert(Result.fromOption(null, \"err\") == #err(\"err\"));\n /// ```\n public func fromOption<R, E>(x : ?R, err : E) : Result<R, E> {\n switch x {\n case (?x) { #ok(x) };\n case null { #err(err) };\n }\n };\n\n /// Create an option from a result, turning all #err into `null`.\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// assert(Result.toOption(#ok(42)) == ?42);\n /// assert(Result.toOption(#err(\"err\")) == null);\n /// ```\n public func toOption<R, E>(r : Result<R, E>) : ?R {\n switch r {\n case (#ok(x)) { ?x };\n case (#err(_)) { null };\n }\n };\n\n /// Applies a function to a successful value, but discards the result. Use\n /// `iterate` if you're only interested in the side effect `f` produces.\n ///\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// var counter : Nat = 0;\n /// Result.iterate<Nat, Text>(#ok(5), func (x : Nat) { counter += x });\n /// assert(counter == 5);\n /// Result.iterate<Nat, Text>(#err(\"Wrong\"), func (x : Nat) { counter += x });\n /// assert(counter == 5);\n /// ```\n public func iterate<Ok, Err>(res : Result<Ok, Err>, f : Ok -> ()) {\n switch res {\n case (#ok(ok)) { f(ok) };\n case _ {};\n }\n };\n\n // Whether this Result is an `#ok`\n public func isOk(r : Result<Any, Any>) : Bool {\n switch r {\n case (#ok(_)) { true };\n case (#err(_)) { false };\n }\n };\n\n // Whether this Result is an `#err`\n public func isErr(r : Result<Any, Any>) : Bool {\n switch r {\n case (#ok(_)) { false };\n case (#err(_)) { true };\n }\n };\n\n /// Asserts that its argument is an `#ok` result, traps otherwise.\n public func assertOk(r : Result<Any,Any>) {\n switch(r) {\n case (#err(_)) { assert false };\n case (#ok(_)) {};\n }\n };\n\n /// Asserts that its argument is an `#err` result, traps otherwise.\n public func assertErr(r : Result<Any,Any>) {\n switch(r) {\n case (#err(_)) {};\n case (#ok(_)) assert false;\n }\n };\n\n}\n"},"Text.mo":{"content":"/// Text values\n///\n/// This type represents human-readable text as sequences of characters of type `Char`.\n/// If `t` is a value of type `Text`, then:\n///\n/// * `t.chars()` returns an _iterator_ of type `Iter<Char>` enumerating its characters from first to last.\n/// * `t.size()` returns the _size_ (or length) of `t` (and `t.chars()`) as a `Nat`.\n/// * `t1 # t2` concatenates texts `t1` and `t2`.\n///\n/// Represented as ropes of UTF-8 character sequences with O(1) concatenation.\n///\n/// This module defines additional operations on `Text` values.\n\nimport Char \"Char\";\nimport Iter \"Iter\";\nimport Hash \"Hash\";\nimport Stack \"Stack\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Text values.\n public type Text = Prim.Types.Text;\n\n /// Conversion.\n /// Returns the text value of size 1 containing the single character `c`.\n public let fromChar : (c : Char) -> Text = Prim.charToText;\n\n /// Conversion.\n /// Creates an iterator that traverses the characters of the text `t`.\n public func toIter(t : Text) : Iter.Iter<Char> =\n t.chars();\n\n /// Conversion.\n /// Returns the text value containing the sequence of characters in `cs`.\n public func fromIter(cs : Iter.Iter<Char>) : Text {\n var r = \"\";\n for (c in cs) {\n r #= Prim.charToText(c);\n };\n return r;\n };\n\n /// Returns `t.size()`, the number of characters in `t` (and `t.chars()`).\n public func size(t : Text) : Nat { t.size(); };\n\n /// Returns a hash obtained by using the `djb2` algorithm from http://www.cse.yorku.ca/~oz/hash.html\n ///\n /// This function is _good enough_ for use in a hash-table but it's not a cryptographic hash function!\n public func hash(t : Text) : Hash.Hash {\n var x : Nat32 = 5381;\n for (char in t.chars()) {\n let c : Nat32 = Prim.charToNat32(char);\n x := ((x << 5) +% x) +% c;\n };\n return x\n };\n\n /// Returns the concatenation of `t1` and `t2`, `t1 # t2`.\n public func concat(t1 : Text, t2 : Text) : Text =\n t1 # t2;\n\n /// Returns `t1 == t2`.\n public func equal(t1 : Text, t2 : Text) : Bool { t1 == t2 };\n\n /// Returns `t1 != t2`.\n public func notEqual(t1 : Text, t2 : Text) : Bool { t1 != t2 };\n\n /// Returns `t1 < t2`.\n public func less(t1 : Text, t2 : Text) : Bool { t1 < t2 };\n\n /// Returns `t1 <= t2`.\n public func lessOrEqual(t1 : Text, t2 : Text) : Bool { t1 <= t2 };\n\n /// Returns `t1 > t2`.\n public func greater(t1 : Text, t2 : Text) : Bool { t1 > t2 };\n\n /// Returns `t1 >= t2`.\n public func greaterOrEqual(t1 : Text, t2 : Text) : Bool { t1 >= t2 };\n\n /// Returns the order of `t1` and `t2`.\n public func compare(t1 : Text, t2 : Text) : { #less; #equal; #greater } {\n let c = Prim.textCompare(t1, t2);\n if (c < 0) #less else if (c == 0) #equal else #greater\n };\n\n\n private func extract(t : Text, i : Nat, j : Nat) : Text {\n let size = t.size();\n if (i == 0 and j == size) return t;\n assert (j <= size);\n let cs = t.chars();\n var r = \"\";\n var n = i;\n while (n > 0) {\n ignore cs.next();\n n -= 1;\n };\n n := j;\n while (n > 0) {\n switch (cs.next()) {\n case null { assert false };\n case (?c) { r #= Prim.charToText(c) }\n };\n n -= 1;\n };\n return r;\n };\n\n /// Returns the concatenation of text values in `ts`, separated by `sep`.\n public func join(sep : Text, ts : Iter.Iter<Text>) : Text {\n var r = \"\";\n if (sep.size() == 0) {\n for (t in ts) {\n r #= t\n };\n return r;\n };\n let next = ts.next;\n switch (next()) {\n case null { return r; };\n case (?t) {\n r #= t;\n }\n };\n loop {\n switch (next()) {\n case null { return r; };\n case (?t) {\n r #= sep;\n r #= t;\n }\n }\n }\n };\n\n\n /// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate single-character text values.\n public func map(t : Text, f : Char -> Char) : Text {\n var r = \"\";\n for (c in t.chars()) {\n r #= Prim.charToText(f(c));\n };\n return r;\n };\n\n /// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate text values.\n public func translate(t : Text, f : Char -> Text) : Text {\n var r = \"\";\n for (c in t.chars()) {\n r #= f(c);\n };\n return r;\n };\n\n\n /// A pattern `p` describes a sequence of characters. A pattern has one of the following forms:\n ///\n /// * `#char c` matches the single character sequence, `c`.\n /// * `#predicate p` matches any single character sequence `c` satisfying predicate `p(c)`.\n /// * `#text t` matches multi-character text sequence `t`.\n ///\n /// A _match_ for `p` is any sequence of characters matching the pattern `p`.\n public type Pattern = { #char : Char; #text : Text; #predicate : (Char -> Bool) };\n\n private func take(n : Nat, cs : Iter.Iter<Char>) : Iter.Iter<Char> {\n var i = n;\n object {\n public func next() : ?Char {\n if (i == 0) return null;\n i -= 1;\n return cs.next();\n }\n }\n };\n\n private func empty() : Iter.Iter<Char> {\n object {\n public func next() : ?Char = null;\n };\n };\n\n private type Match = {\n /// #success on complete match\n #success;\n /// #fail(cs,c) on partial match of cs, but failing match on c\n #fail : (cs : Iter.Iter<Char>, c : Char);\n /// #empty(cs) on partial match of cs and empty stream\n #empty : (cs : Iter.Iter<Char> )\n };\n\n private func sizeOfPattern(pat : Pattern) : Nat {\n switch pat {\n case (#text(t)) { t.size() };\n case (#predicate(_) or #char(_)) { 1 };\n }\n };\n\n private func matchOfPattern(pat : Pattern) : (cs : Iter.Iter<Char>) -> Match {\n switch pat {\n case (#char(p)) {\n func (cs : Iter.Iter<Char>) : Match {\n switch (cs.next()) {\n case (?c) {\n if (p == c) {\n #success\n } else {\n #fail(empty(), c) }\n };\n case null { #empty(empty()) };\n }\n }\n };\n case (#predicate(p)) {\n func (cs : Iter.Iter<Char>) : Match {\n switch (cs.next()) {\n case (?c) {\n if (p(c)) {\n #success\n } else {\n #fail(empty(), c) }\n };\n case null { #empty(empty()) };\n }\n }\n };\n case (#text(p)) {\n func (cs : Iter.Iter<Char>) : Match {\n var i = 0;\n let ds = p.chars();\n loop {\n switch (ds.next()) {\n case (?d) {\n switch (cs.next()) {\n case (?c) {\n if (c != d) {\n return #fail(take(i, p.chars()), c)\n };\n i += 1;\n };\n case null {\n return #empty(take(i, p.chars()));\n }\n }\n };\n case null { return #success };\n }\n }\n }\n }\n }\n };\n\n private class CharBuffer(cs : Iter.Iter<Char>) : Iter.Iter<Char> = {\n\n var stack : Stack.Stack<(Iter.Iter<Char>, Char)> = Stack.Stack();\n\n public func pushBack(cs0: Iter.Iter<Char>, c : Char) {\n stack.push((cs0, c));\n };\n\n public func next() : ?Char {\n switch (stack.peek()) {\n case (?(buff, c)) {\n switch (buff.next()) {\n case null {\n ignore stack.pop();\n return ?c;\n };\n case oc {\n return oc;\n };\n }\n };\n case null {\n return cs.next();\n };\n };\n };\n };\n\n /// Returns the sequence of fields in `t`, derived from start to end,\n /// separated by text matching pattern `p`.\n /// Two fields are separated by exactly one match.\n public func split(t : Text, p : Pattern) : Iter.Iter<Text> {\n let match = matchOfPattern(p);\n let cs = CharBuffer(t.chars());\n var state = 0;\n var field = \"\";\n object {\n public func next() : ?Text {\n switch state {\n case (0 or 1) {\n loop {\n switch (match(cs)) {\n case (#success) {\n let r = field;\n field := \"\";\n state := 1;\n return ?r\n };\n case (#empty(cs1)) {\n for (c in cs1) {\n field #= fromChar(c);\n };\n let r =\n if (state == 0 and field == \"\") {\n null\n } else {\n ?field\n };\n state := 2;\n return r;\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1,c);\n switch (cs.next()) {\n case (?ci) {\n field #= fromChar(ci);\n };\n case null {\n let r =\n if (state == 0 and field == \"\") {\n null\n } else {\n ?field\n };\n state := 2;\n return r;\n }\n }\n }\n }\n }\n };\n case _ { return null };\n }\n }\n }\n };\n\n /// Returns the sequence of tokens in `t`, derived from start to end.\n /// A _token_ is a non-empty maximal subsequence of `t` not containing a match for pattern `p`.\n /// Two tokens may be separated by one or more matches of `p`.\n public func tokens(t : Text, p : Pattern) : Iter.Iter<Text> {\n let fs = split(t, p);\n object {\n public func next() : ?Text {\n switch (fs.next()) {\n case (?\"\") { next() };\n case ot { ot };\n }\n }\n }\n };\n\n /// Returns true if `t` contains a match for pattern `p`.\n public func contains(t : Text, p : Pattern) : Bool {\n let match = matchOfPattern(p);\n let cs = CharBuffer(t.chars());\n loop {\n switch (match(cs)) {\n case (#success) {\n return true\n };\n case (#empty(cs1)) {\n return false;\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c);\n switch (cs.next()) {\n case null {\n return false\n };\n case _ { }; // continue\n }\n }\n }\n }\n };\n\n /// Returns `true` if `t` starts with a prefix matching pattern `p`, otherwise returns `false`.\n public func startsWith(t : Text, p : Pattern) : Bool {\n var cs = t.chars();\n let match = matchOfPattern(p);\n switch (match(cs)) {\n case (#success) { true };\n case _ { false };\n }\n };\n\n /// Returns `true` if `t` ends with a suffix matching pattern `p`, otherwise returns `false`.\n public func endsWith(t : Text, p : Pattern) : Bool {\n let s2 = sizeOfPattern(p);\n if (s2 == 0) return true;\n let s1 = t.size();\n if (s2 > s1) return false;\n let match = matchOfPattern(p);\n var cs1 = t.chars();\n var diff : Nat = s1 - s2;\n while (diff > 0) {\n ignore cs1.next();\n diff -= 1;\n };\n switch (match(cs1)) {\n case (#success) { true };\n case _ { false };\n }\n };\n\n /// Returns `t` with all matches of pattern `p` replaced by text `r`.\n public func replace(t : Text, p : Pattern, r : Text) : Text {\n let match = matchOfPattern(p);\n let size = sizeOfPattern(p);\n let cs = CharBuffer(t.chars());\n var res = \"\";\n label l\n loop {\n switch (match(cs)) {\n case (#success) {\n res #= r;\n if (size > 0) {\n continue l;\n }\n };\n case (#empty(cs1)) {\n for (c1 in cs1) {\n res #= fromChar(c1);\n };\n break l;\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c);\n }\n };\n switch (cs.next()) {\n case null {\n break l;\n };\n case (?c1) {\n res #= fromChar(c1);\n }; // continue\n }\n };\n return res;\n };\n\n\n\n /// Returns the optioned suffix of `t` obtained by eliding exactly one leading match of pattern `p`, otherwise `null`.\n public func stripStart(t : Text, p : Pattern) : ?Text {\n let s = sizeOfPattern(p);\n if (s == 0) return ?t;\n var cs = t.chars();\n let match = matchOfPattern(p);\n switch (match(cs)) {\n case (#success) return ?fromIter(cs);\n case _ return null;\n }\n };\n\n /// Returns the optioned prefix of `t` obtained by eliding exactly one trailing match of pattern `p`, otherwise `null`.\n public func stripEnd(t : Text, p : Pattern) : ?Text {\n let s2 = sizeOfPattern(p);\n if (s2 == 0) return ?t;\n let s1 = t.size();\n if (s2 > s1) return null;\n let match = matchOfPattern(p);\n var cs1 = t.chars();\n var diff : Nat = s1 - s2;\n while (diff > 0) {\n ignore cs1.next();\n diff -= 1;\n };\n switch (match(cs1)) {\n case (#success) return ?extract(t, 0, s1 - s2);\n case _ return null;\n }\n };\n\n /// Returns the suffix of `t` obtained by eliding all leading matches of pattern `p`.\n public func trimStart(t : Text, p : Pattern) : Text {\n let cs = t.chars();\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n var matchSize = 0;\n let match = matchOfPattern(p);\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size;\n }; // continue\n case (#empty(cs1)) {\n return if (matchSize == 0) {\n t\n } else {\n fromIter(cs1)\n }\n };\n case (#fail(cs1, c)) {\n return if (matchSize == 0) {\n t\n } else {\n fromIter(cs1) # fromChar(c) # fromIter(cs)\n }\n }\n }\n }\n };\n\n /// Returns the prefix of `t` obtained by eliding all trailing matches of pattern `p`.\n public func trimEnd(t : Text, p : Pattern) : Text {\n let cs = CharBuffer(t.chars());\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n let match = matchOfPattern(p);\n var matchSize = 0;\n label l\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size;\n }; // continue\n case (#empty(cs1)) {\n switch (cs1.next()) {\n case null break l;\n case (?_) return t;\n }\n };\n case (#fail(cs1, c)) {\n matchSize := 0;\n cs.pushBack(cs1, c);\n ignore cs.next();\n }\n }\n };\n extract(t, 0, t.size() - matchSize)\n };\n\n /// Returns the subtext of `t` obtained by eliding all leading and trailing matches of pattern `p`.\n public func trim(t : Text, p : Pattern) : Text {\n let cs = t.chars();\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n var matchSize = 0;\n let match = matchOfPattern(p);\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size;\n }; // continue\n case (#empty(cs1)) {\n return if (matchSize == 0) { t } else { fromIter(cs1) }\n };\n case (#fail(cs1, c)) {\n let start = matchSize;\n let cs2 = CharBuffer(cs);\n cs2.pushBack(cs1, c);\n ignore cs2.next();\n matchSize := 0;\n label l\n loop {\n switch (match(cs2)) {\n case (#success) {\n matchSize += size;\n }; // continue\n case (#empty(cs3)) {\n switch (cs1.next()) {\n case null break l;\n case (?_) return t;\n }\n };\n case (#fail(cs3, c1)) {\n matchSize := 0;\n cs2.pushBack(cs3, c1);\n ignore cs2.next();\n }\n }\n };\n return extract(t, start, t.size() - matchSize - start);\n }\n }\n }\n };\n\n /// Returns the lexicographic comparison of `t1` and `t2`, using the given character ordering `cmp`.\n public func compareWith(\n t1 : Text,\n t2 : Text,\n cmp : (Char, Char)-> { #less; #equal; #greater })\n : { #less; #equal; #greater } {\n let cs1 = t1.chars();\n let cs2 = t2.chars();\n loop {\n switch (cs1.next(), cs2.next()) {\n case (null, null) { return #equal };\n case (null, ?_) { return #less };\n case (?_, null) { return #greater };\n case (?c1, ?c2) {\n switch (cmp(c1, c2)) {\n case (#equal) { }; // continue\n case other { return other; }\n }\n }\n }\n }\n };\n\n /// Returns the UTF-8 encoding of the given text\n public let encodeUtf8 : Text -> Blob = Prim.encodeUtf8;\n\n /// Tries to decode the given `Blob` as UTF-8.\n /// Returns `null` if the blob is _not_ valid UTF-8.\n public let decodeUtf8 : Blob -> ?Text = Prim.decodeUtf8;\n}\n"},"Trie.mo":{"content":"/// Functional key-value hash maps.\n///\n/// Functional maps (and sets) whose representation is \"canonical\", and\n/// independent of operation history (unlike other popular search trees).\n///\n/// The representation we use here comes from Section 6 of [\"Incremental computation via function caching\", Pugh & Teitelbaum](https://dl.acm.org/citation.cfm?id=75305).\n///\n/// ## User's overview\n///\n/// This module provides an applicative (functional) hash map.\n/// Notably, each `put` produces a **new trie _and value being replaced, if any_**.\n///\n/// Those looking for a more familiar (imperative,\n/// object-oriented) hash map should consider `TrieMap` or `HashMap` instead.\n///\n/// The basic `Trie` operations consist of:\n/// - `put` - put a key-value into the trie, producing a new version.\n/// - `get` - get a key's value from the trie, or `null` if none.\n/// - `iter` - visit every key-value in the trie.\n///\n/// The `put` and `get` operations work over `Key` records,\n/// which group the hash of the key with its non-hash key value.\n///\n/// ```motoko\n/// import Trie \"mo:base/Trie\";\n/// import Text \"mo:base/Text\";\n///\n/// type Trie<K, V> = Trie.Trie<K, V>;\n/// type Key<K> = Trie.Key<K>;\n///\n/// func key(t: Text) : Key<Text> { { key = t; hash = Text.hash t } };\n///\n/// let t0 : Trie<Text, Nat> = Trie.empty();\n/// let t1 : Trie<Text, Nat> = Trie.put(t0, key \"hello\", Text.equal, 42).0;\n/// let t2 : Trie<Text, Nat> = Trie.put(t1, key \"world\", Text.equal, 24).0;\n/// let n : ?Nat = Trie.put(t1, key \"hello\", Text.equal, 0).1;\n/// assert (n == ?42);\n/// ```\n///\n\n// ## Implementation overview\n//\n// A (hash) trie is a binary tree container for key-value pairs that\n// consists of leaf and branch nodes.\n//\n// Each internal **branch node**\n// represents having distinguished its key-value pairs on a single bit of\n// the keys.\n// By following paths in the trie, we determine an increasingly smaller\n// and smaller subset of the keys.\n//\n// Each **leaf node** consists of an association list of key-value pairs.\n//\n// Each non-empty trie node stores a size; we discuss that more below.\n//\n// ### Adaptive depth\n//\n// We say that a leaf is valid if it contains no more than `MAX_LEAF_SIZE`\n// key-value pairs. When a leaf node grows too large, the\n// binary tree produces a new internal binary node, and splits the leaf into\n// a pair of leaves using an additional bit of their keys' hash strings.\n//\n// For small mappings, the trie structure consists of a single\n// leaf, which contains up to MAX_LEAF_SIZE key-value pairs.\n//\n// ### Cached sizes\n//\n// At each branch and leaf, we use a stored size to support a\n// memory-efficient `toArray` function, which itself relies on\n// per-element projection via `nth`; in turn, `nth` directly uses the\n// O(1)-time function `size` for achieving an acceptable level of\n// algorithmic efficiency. Notably, leaves are generally lists of\n// key-value pairs, and we do not store a size for each Cons cell in the\n// list.\n//\n\nimport Debug \"mo:base/Debug\";\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport Option \"Option\";\nimport Hash \"Hash\";\nimport A \"Array\";\n\nimport List \"List\";\nimport AssocList \"AssocList\";\nimport I \"Iter\";\n\nmodule {\n\n let MAX_LEAF_SIZE = 8; // to do -- further profiling and tuning\n\n /// Binary hash tries: either empty, a leaf node, or a branch node\n public type Trie<K, V> = {\n #empty;\n #leaf : Leaf<K, V>;\n #branch : Branch<K, V>;\n };\n\n /// Leaf nodes of trie consist of key-value pairs as a list.\n public type Leaf<K, V> = {\n size : Nat ;\n keyvals : AssocList<Key<K>, V> ;\n };\n\n /// Branch nodes of the trie discriminate on a bit position of the keys' hashes.\n /// we never store this bitpos; rather,\n /// we enforce a style where this position is always known from context.\n public type Branch<K, V> = {\n size : Nat;\n left : Trie<K, V>;\n right : Trie<K, V>;\n };\n\n public type AssocList<K, V> = AssocList.AssocList<K, V>;\n\n //// A `Key` for the trie has an associated hash value\n public type Key<K> = {\n /// `hash` permits fast inequality checks, and permits collisions\n hash: Hash.Hash;\n /// `key` permits precise equality checks, but only used after equal hashes.\n key: K;\n };\n\n type List<T> = List.List<T>;\n\n /// Equality function for two `Key<K>`s, in terms of equality of `K`'s.\n public func equalKey<K>(keq : (K, K) -> Bool) : ((Key<K>, Key<K>) -> Bool) {\n func (key1 : Key<K>, key2 : Key<K>) : Bool {\n Hash.equal(key1.hash, key2.hash) and keq(key1.key, key2.key)\n }\n };\n\n /// @deprecated `isValid` is an internal predicate and will be removed in future.\n public func isValid<K, V>(t : Trie<K, V>, _enforceNormal : Bool) : Bool {\n func rec(t : Trie<K, V>, bitpos : ?Hash.Hash, bits : Hash.Hash, mask : Hash.Hash) : Bool {\n switch t {\n case (#empty) {\n true;\n };\n case (#leaf(l)) {\n let len = List.size(l.keyvals);\n len <= MAX_LEAF_SIZE\n and\n len == l.size\n and\n List.all(\n l.keyvals,\n func ((k : Key<K>, v : V)) : Bool {\n ((k.hash & mask) == bits)\n }\n )\n };\n case (#branch(b)) {\n let bitpos1 =\n switch bitpos {\n case null {Prim.natToNat32(0)};\n case (?bp) {Prim.natToNat32(Prim.nat32ToNat(bp) + 1)}\n };\n let mask1 = mask | (Prim.natToNat32(1) << bitpos1);\n let bits1 = bits | (Prim.natToNat32(1) << bitpos1);\n let sum = size(b.left) + size(b.right);\n (b.size == sum) and\n rec(b.left, ?bitpos1, bits, mask1) and\n rec(b.right, ?bitpos1, bits1, mask1)\n };\n }\n };\n rec(t, null, 0, 0)\n };\n\n\n /// A 2D trie maps dimension-1 keys to another\n /// layer of tries, each keyed on the dimension-2 keys.\n public type Trie2D<K1, K2, V> = Trie<K1, Trie<K2, V>>;\n\n /// A 3D trie maps dimension-1 keys to another\n /// layer of 2D tries, each keyed on the dimension-2 and dimension-3 keys.\n public type Trie3D<K1, K2, K3, V> = Trie<K1, Trie2D<K2, K3, V> >;\n\n /// An empty trie.\n public func empty<K, V>() : Trie<K, V> { #empty; };\n\n /// Get the number of key-value pairs in the trie, in constant time.\n\n /// Get size in O(1) time.\n public func size<K, V>(t : Trie<K, V>) : Nat {\n switch t {\n case (#empty) { 0 };\n case (#leaf(l)) { l.size };\n case (#branch(b)) { b.size };\n }\n };\n\n /// Construct a branch node, computing the size stored there.\n public func branch<K, V>(l : Trie<K, V>, r : Trie<K, V>) : Trie<K, V> {\n let sum = size(l) + size(r);\n #branch {\n size = sum;\n left = l;\n right = r\n };\n };\n\n /// Construct a leaf node, computing the size stored there.\n ///\n /// This helper function automatically enforces the MAX_LEAF_SIZE\n /// by constructing branches as necessary; to do so, it also needs the bitpos\n /// of the leaf.\n public func leaf<K, V>(kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n fromList(null, kvs, bitpos)\n };\n\n module ListUtil {\n /* Deprecated: List.lenClamp */\n /// Return the list length unless the number of items in the list exceeds\n /// a maximum value. If the list length exceed the maximum, the function\n /// returns `null`.\n public func lenClamp<T>(l : List<T>, max : Nat) : ?Nat {\n func rec(l : List<T>, max : Nat, i : Nat) : ?Nat {\n switch l {\n case null { ?i };\n case (?(_, t)) {\n if ( i >= max ) { null }\n else { rec(t, max, i + 1) }\n };\n }\n };\n rec(l, max, 0)\n };\n };\n\n /// Transform a list into a trie, splitting input list into small (leaf) lists, if necessary.\n public func fromList<K, V>(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n func rec(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n switch kvc {\n case null {\n switch (ListUtil.lenClamp(kvs, MAX_LEAF_SIZE)) {\n case null {} /* fall through to branch case. */;\n case (?len) {\n return #leaf({ size = len; keyvals = kvs })\n };\n }\n };\n case (?c) {\n if ( c == 0 ) {\n return #empty\n } else if ( c <= MAX_LEAF_SIZE ) {\n return #leaf({ size = c; keyvals = kvs })\n } else {\n /* fall through to branch case */\n }\n };\n };\n let (ls, l, rs, r) = splitList(kvs, bitpos);\n if ( ls == 0 and rs == 0 ) {\n #empty\n } else if (rs == 0 and ls <= MAX_LEAF_SIZE) {\n #leaf({ size = ls; keyvals = l })\n } else if (ls == 0 and rs <= MAX_LEAF_SIZE) {\n #leaf({ size = rs; keyvals = r })\n } else {\n branch(rec(?ls, l, bitpos + 1), rec(?rs, r, bitpos + 1))\n }\n };\n rec(kvc, kvs, bitpos)\n };\n\n /// Clone the trie efficiently, via sharing.\n ///\n /// Purely-functional representation permits _O(1)_ copy, via persistent sharing.\n public func clone<K, V>(t : Trie<K, V>) : Trie<K, V> = t;\n\n /// Replace the given key's value option with the given one, returning the previous one\n public func replace<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : ?V) : (Trie<K, V>, ?V) {\n let key_eq = equalKey(k_eq);\n\n func rec(t : Trie<K, V>, bitpos : Nat) : (Trie<K, V>, ?V) {\n switch t {\n case (#empty) {\n let (kvs, _) = AssocList.replace(null, k, key_eq, v);\n (leaf(kvs, bitpos), null)\n };\n case (#branch(b)) {\n let bit = Hash.bit(k.hash, bitpos);\n // rebuild either the left or right path with the (k, v) pair\n if (not bit) {\n let (l, v_) = rec(b.left, bitpos + 1);\n (branch(l, b.right), v_)\n }\n else {\n let (r, v_) = rec(b.right, bitpos + 1);\n (branch(b.left, r), v_)\n }\n };\n case (#leaf(l)) {\n let (kvs2, old_val) =\n AssocList.replace(l.keyvals, k, key_eq, v);\n (leaf(kvs2, bitpos), old_val)\n };\n }\n };\n let (to, vo) = rec(t, 0);\n //assert(isValid<K, V>(to, false));\n (to, vo)\n };\n\n /// Put the given key's value in the trie; return the new trie, and the previous value associated with the key, if any\n public func put<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : (Trie<K, V>, ?V) {\n replace(t, k, k_eq, ?v)\n };\n\n /// Get the value of the given key in the trie, or return null if nonexistent\n public func get<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V =\n find(t, k, k_eq);\n\n /// Find the given key's value in the trie, or return null if nonexistent\n public func find<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V {\n let key_eq = equalKey(k_eq);\n func rec(t : Trie<K, V>, bitpos : Nat) : ?V {\n switch t {\n case (#empty) { null };\n case (#leaf(l)) {\n AssocList.find(l.keyvals, k, key_eq)\n };\n case (#branch(b)) {\n let bit = Hash.bit(k.hash, bitpos);\n if (not bit) {\n rec(b.left, bitpos + 1)\n }\n else {\n rec(b.right, bitpos + 1)\n }\n };\n }\n };\n rec(t, 0)\n };\n\n\n\n func splitAssocList<K, V>(al : AssocList<Key<K>, V>, bitpos : Nat)\n : (AssocList<Key<K>, V>, AssocList<Key<K>, V>)\n {\n List.partition(\n al,\n func ((k : Key<K>, v : V)) : Bool {\n not Hash.bit(k.hash, bitpos)\n }\n )\n };\n\n func splitList<K, V>(l : AssocList<Key<K>, V>, bitpos : Nat)\n : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>)\n {\n func rec(l : AssocList<Key<K>, V>) : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>) {\n switch l {\n case null { (0, null, 0, null) };\n case (?((k, v), t)) {\n let (cl, l, cr, r) = rec(t) ;\n if (not Hash.bit(k.hash, bitpos)){\n (cl + 1, ?((k, v), l), cr, r)\n } else {\n (cl, l, cr + 1, ?((k, v), r))\n }\n };\n }\n };\n rec(l)\n };\n\n /// Merge tries, preferring the left trie where there are collisions\n /// in common keys.\n ///\n /// note: the `disj` operation generalizes this `merge`\n /// operation in various ways, and does not (in general) lose\n /// information; this operation is a simpler, special case.\n public func merge<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> {\n switch (tl, tr) {\n case (#empty, _) { return tr };\n case (_, #empty) { return tl };\n case (#leaf(l1), #leaf(l2)) {\n leaf(\n AssocList.disj(\n l1.keyvals, l2.keyvals,\n key_eq,\n func (x : ?V, y : ?V) : V {\n switch (x, y) {\n case (null, null) { P.unreachable() };\n case (null, ?v) { v };\n case (?v, _) { v };\n }\n }\n ),\n bitpos)\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right))\n };\n }\n };\n rec(0, tl, tr)\n };\n\n /// Merge tries like `merge`, except signals a\n /// dynamic error if there are collisions in common keys between the\n /// left and right inputs.\n public func mergeDisjoint<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> {\n switch (tl, tr) {\n case (#empty, _) { return tr };\n case (_, #empty) { return tl };\n case (#leaf(l1), #leaf(l2)) {\n leaf(\n AssocList.disjDisjoint(\n l1.keyvals, l2.keyvals,\n func (x : ?V, y : ?V) : V {\n switch (x, y) {\n case (null, ?v) { v };\n case (?v, null) { v };\n case (_, _) { P.unreachable() };\n }\n }\n ),\n bitpos\n )\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(\n rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right)\n )\n };\n }\n };\n rec(0, tl, tr)\n };\n\n /// Difference of tries. The output consists are pairs of\n /// the left trie whose keys are not present in the right trie; the\n /// values of the right trie are irrelevant.\n public func diff<K, V, W>(tl : Trie<K, V>, tr : Trie<K, W>, k_eq : ( K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, V> {\n switch (tl, tr) {\n case (#empty, _) { return #empty };\n case (_, #empty) { return tl };\n case (#leaf(l1), #leaf(l2)) {\n leaf(\n AssocList.diff(\n l1.keyvals, l2.keyvals,\n key_eq,\n ),\n bitpos\n )\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right))\n };\n }\n };\n rec(0, tl, tr)\n };\n\n /// Map disjunction.\n ///\n /// This operation generalizes the notion of \"set union\" to finite maps.\n ///\n /// Produces a \"disjunctive image\" of the two tries, where the values of\n /// matching keys are combined with the given binary operator.\n ///\n /// For unmatched key-value pairs, the operator is still applied to\n /// create the value in the image. To accomodate these various\n /// situations, the operator accepts optional values, but is never\n /// applied to (null, null).\n ///\n /// Implements the database idea of an [\"outer join\"](https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join).\n ///\n public func disj<K, V, W, X>(\n tl : Trie<K, V>,\n tr : Trie<K, W>,\n k_eq : (K, K) -> Bool,\n vbin : (?V, ?W) -> X\n ) : Trie<K, X> {\n let key_eq = equalKey(k_eq);\n\n /* empty right case; build from left only: */\n func recL(t : Trie<K, V>, bitpos : Nat) : Trie<K, X> {\n switch t {\n case (#empty) { #empty };\n case (#leaf(l)) {\n leaf(AssocList.disj(l.keyvals, null, key_eq, vbin), bitpos)\n };\n case (#branch(b)) {\n branch(recL(b.left, bitpos + 1),\n recL(b.right, bitpos + 1)) };\n }\n };\n\n /* empty left case; build from right only: */\n func recR(t : Trie<K, W>, bitpos : Nat) : Trie<K, X> {\n switch t {\n case (#empty) { #empty };\n case (#leaf(l)) {\n leaf(AssocList.disj(null, l.keyvals, key_eq, vbin), bitpos)\n };\n case (#branch(b)) {\n branch(recR(b.left, bitpos + 1),\n recR(b.right, bitpos + 1)) };\n }\n };\n\n /* main recursion */\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, X> {\n switch (tl, tr) {\n case (#empty, #empty) { #empty };\n case (#empty, _) { recR(tr, bitpos) };\n case (_, #empty) { recL(tl, bitpos) };\n case (#leaf(l1), #leaf(l2)) {\n leaf(AssocList.disj(l1.keyvals, l2.keyvals, key_eq, vbin), bitpos)\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right))\n };\n }\n };\n\n rec(0, tl, tr)\n };\n\n /// Map join.\n ///\n /// Implements the database idea of an [\"inner join\"](https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join).\n ///\n /// This operation generalizes the notion of \"set intersection\" to\n /// finite maps. The values of matching keys are combined with the given binary\n /// operator, and unmatched key-value pairs are not present in the output.\n ///\n public func join<K, V, W, X>(\n tl : Trie<K, V>,\n tr : Trie<K, W>,\n k_eq : (K, K) -> Bool,\n vbin : (V, W) -> X\n ) : Trie<K, X> {\n let key_eq = equalKey(k_eq);\n\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, X> {\n switch (tl, tr) {\n case (#empty, _) { #empty };\n case (_, #empty) { #empty };\n case (#leaf(l1), #leaf(l2)) {\n leaf(AssocList.join(l1.keyvals, l2.keyvals, key_eq, vbin), bitpos)\n };\n case (#leaf(l), _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf(l)) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch(b1), #branch(b2)) {\n branch(rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right))\n };\n }\n };\n\n rec(0, tl, tr)\n };\n\n /// This operation gives a recursor for the internal structure of\n /// tries. Many common operations are instantiations of this function,\n /// either as clients, or as hand-specialized versions (e.g., see , map,\n /// mapFilter, some and all below).\n public func foldUp<K, V, X>(t : Trie<K, V>, bin : (X, X) -> X, leaf : (K, V) -> X, empty : X) : X {\n func rec(t : Trie<K, V>) : X {\n switch t {\n case (#empty) { empty };\n case (#leaf(l)) {\n AssocList.fold(\n l.keyvals, empty,\n func (k : Key<K>, v : V, x : X) : X { bin(leaf(k.key, v), x) }\n )\n };\n case (#branch(b)) { bin(rec(b.left), rec(b.right)) };\n }\n };\n rec(t)\n };\n\n\n /// Map product.\n ///\n /// Conditional _catesian product_, where the given\n /// operation `op` _conditionally_ creates output elements in the\n /// resulting trie.\n ///\n /// The keyed structure of the input tries are not relevant for this\n /// operation: all pairs are considered, regardless of keys matching or\n /// not. Moreover, the resulting trie may use keys that are unrelated to\n /// these input keys.\n ///\n public func prod<K1, V1, K2, V2, K3, V3>(\n tl : Trie<K1, V1>,\n tr : Trie<K2, V2>,\n op : (K1, V1, K2, V2) -> ?(Key<K3>, V3),\n k3_eq : (K3, K3) -> Bool\n ) : Trie<K3, V3> {\n\n /*- binary case: merge disjoint results: */\n func merge (a : Trie<K3, V3>, b : Trie<K3, V3>) : Trie<K3, V3> =\n mergeDisjoint(a, b, k3_eq);\n\n /*- \"`foldUp` squared\" (imagine two nested loops): */\n foldUp(\n tl, merge,\n func (k1 : K1, v1 : V1) : Trie<K3, V3> {\n foldUp(\n tr, merge,\n func (k2 : K2, v2 : V2) : Trie<K3, V3> {\n switch (op(k1, v1, k2, v2)) {\n case null { #empty };\n case (?(k3, v3)) { (put(#empty, k3, k3_eq, v3)).0 };\n }\n },\n #empty\n )\n },\n #empty\n )\n };\n\n /// Returns an `Iter` over the key-value entries of the trie.\n ///\n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n public func iter<K, V>(t : Trie<K, V>) : I.Iter<(K, V)> {\n object {\n var stack = ?(t, null) : List.List<Trie<K, V>>;\n public func next() : ?(K, V) {\n switch stack {\n case null { null };\n case (?(trie, stack2)) {\n switch trie {\n case (#empty) {\n stack := stack2;\n next()\n };\n case (#leaf({ keyvals = null })) {\n stack := stack2;\n next()\n };\n case (#leaf({ size = c; keyvals = ?((k, v), kvs) })) {\n stack := ?(#leaf({ size = c-1; keyvals = kvs }), stack2);\n ?(k.key, v)\n };\n case (#branch(br)) {\n stack := ?(br.left, ?(br.right, stack2));\n next()\n };\n }\n }\n }\n }\n }\n };\n\n /// Represent the construction of tries as data.\n ///\n /// This module provides optimized variants of normal tries, for\n /// more efficient join queries.\n ///\n /// The central insight is that for (unmaterialized) join query results, we\n /// do not need to actually build any resulting trie of the resulting\n /// data, but rather, just need a collection of what would be in that\n /// trie. Since query results can be large (quadratic in the DB size),\n /// avoiding the construction of this trie provides a considerable savings.\n ///\n /// To get this savings, we use an ADT for the operations that _would_ build this trie,\n /// if evaluated. This structure specializes a rope: a balanced tree representing a\n /// sequence. It is only as balanced as the tries from which we generate\n /// these build ASTs. They have no intrinsic balance properties of their\n /// own.\n ///\n public module Build {\n /// The build of a trie, as an AST for a simple DSL.\n public type Build<K, V> = {\n #skip ;\n #put : (K, ?Hash.Hash, V) ;\n #seq : {\n size : Nat;\n left : Build<K, V>;\n right : Build<K, V>;\n } ;\n };\n\n /// Size of the build, measured in `#put` operations\n public func size<K, V>(tb : Build<K, V>) : Nat {\n switch tb {\n case (#skip) { 0 };\n case (#put(_, _, _)) { 1 };\n case (#seq(seq)) { seq.size };\n }\n };\n\n /// Build sequence of two sub-builds\n public func seq<K, V>(l : Build<K, V>, r : Build<K, V>) : Build<K, V> {\n let sum = size(l) + size(r);\n #seq({ size = sum; left = l; right = r })\n };\n\n /// Like [`prod`](#prod), except do not actually do the put calls, just\n /// record them, as a (binary tree) data structure, isomorphic to the\n /// recursion of this function (which is balanced, in expectation).\n public func prod<K1, V1, K2, V2, K3, V3>(\n tl : Trie<K1, V1>,\n tr : Trie<K2, V2>,\n op : (K1, V1, K2, V2) -> ?(K3, V3),\n k3_eq : (K3, K3) -> Bool\n ) : Build<K3, V3> {\n\n func outer_bin (a : Build<K3, V3>, b : Build<K3, V3>)\n : Build<K3, V3> {\n seq(a, b)\n };\n\n func inner_bin (a : Build<K3, V3>, b : Build<K3, V3>)\n : Build<K3, V3> {\n seq(a, b)\n };\n\n /// double-nested folds\n foldUp(\n tl, outer_bin,\n func (k1 : K1, v1 : V1) : Build<K3, V3> {\n foldUp(\n tr, inner_bin,\n func (k2 : K2, v2 : V2) : Build<K3, V3> {\n switch (op(k1, v1, k2, v2)) {\n case null { #skip };\n case (?(k3, v3)) { #put(k3, null, v3) };\n }\n },\n #skip\n )\n },\n #skip\n )\n };\n\n /// Project the nth key-value pair from the trie build.\n ///\n /// This position is meaningful only when the build contains multiple uses of one or more keys, otherwise it is not.\n public func nth<K, V>(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) {\n func rec(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) {\n switch tb {\n case (#skip) { P.unreachable() };\n case (#put(k, h, v)) {\n assert(i == 0);\n ?(k, h, v)\n };\n case (#seq(s)) {\n let size_left = size(s.left);\n if (i < size_left) { rec(s.left, i) }\n else { rec(s.right, i - size_left) }\n };\n }\n };\n\n if (i >= size(tb)) {\n return null\n };\n rec(tb, i)\n };\n\n /// Like [`mergeDisjoint`](#mergedisjoint), except that it avoids the\n /// work of actually merging any tries; rather, just record the work for\n /// latter (if ever).\n public func projectInner<K1, K2, V>(t : Trie<K1, Build<K2, V>>)\n : Build<K2, V> {\n foldUp(\n t,\n func (t1 : Build<K2, V>, t2 : Build<K2, V>) : Build<K2, V> { seq(t1, t2) },\n func (_ : K1, t : Build<K2, V>) : Build<K2, V> { t },\n #skip\n )\n };\n\n /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n public func toArray<K, V, W>(tb : Build<K, V>, f: (K, V) -> W) : [W] {\n let c = size(tb);\n let a = A.init<?W>(c, null);\n var i = 0;\n func rec(tb : Build<K, V>) {\n switch tb {\n case (#skip) {};\n case (#put(k, _, v)) { a[i] := ?f(k, v); i := i + 1 };\n case (#seq(s)) { rec(s.left); rec(s.right) };\n }\n };\n rec(tb);\n A.tabulate(c, func(i : Nat) : W {\n switch (a[i]) {\n case null { P.unreachable() };\n case (?x) { x }\n }})\n };\n\n };\n\n /// Fold over the key-value pairs of the trie, using an accumulator.\n /// The key-value pairs have no reliable or meaningful ordering.\n public func fold<K, V, X>(t : Trie<K, V>, f : (K, V, X) -> X, x : X) : X {\n func rec(t : Trie<K, V>, x : X) : X {\n switch t {\n case (#empty) { x };\n case (#leaf(l)) {\n AssocList.fold(\n l.keyvals, x,\n func (k : Key<K>, v : V, x : X) : X = f(k.key, v, x)\n )\n };\n case (#branch(b)) { rec(b.left, rec(b.right, x)) };\n };\n };\n rec(t, x)\n };\n\n /// Test whether a given key-value pair is present, or not.\n public func some<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n func rec(t : Trie<K, V>) : Bool {\n switch t {\n case (#empty) { false };\n case (#leaf(l)) {\n List.some(\n l.keyvals, func ((k : Key<K>, v:V)) : Bool = f(k.key, v)\n )\n };\n case (#branch(b)) { rec(b.left) or rec(b.right) };\n };\n };\n rec(t)\n };\n\n /// Test whether all key-value pairs have a given property.\n public func all<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n func rec(t : Trie<K, V>) : Bool {\n switch t {\n case (#empty) { true };\n case (#leaf(l)) {\n List.all(\n l.keyvals, func ((k : Key<K>, v : V)) : Bool=f(k.key, v)\n )\n };\n case (#branch(b)) { rec(b.left) and rec(b.right) };\n };\n };\n rec(t)\n };\n\n /// Project the nth key-value pair from the trie.\n ///\n /// Note: This position is not meaningful; it's only here so that we\n /// can inject tries into arrays using functions like `Array.tabulate`.\n public func nth<K, V>(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) {\n func rec(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) {\n switch t {\n case (#empty) { P.unreachable() };\n case (#leaf(l)) { List.get(l.keyvals, i) };\n case (#branch(b)) {\n let size_left = size(b.left);\n if (i < size_left) { rec(b.left, i) }\n else { rec(b.right, i - size_left) }\n }\n }\n };\n if (i >= size(t)) {\n return null\n };\n rec(t, i)\n };\n\n\n /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n public func toArray<K, V, W>(t : Trie<K, V>, f : (K, V) -> W) : [W] {\n let a = A.tabulate<W> (\n size(t),\n func (i : Nat) : W {\n let (k, v) = switch (nth(t, i)) {\n case null { P.unreachable() };\n case (?x) { x };\n };\n f(k.key, v)\n }\n );\n a\n };\n\n /// Test for \"deep emptiness\": subtrees that have branching structure,\n /// but no leaves. These can result from naive filtering operations;\n /// filter uses this function to avoid creating such subtrees.\n public func isEmpty<K, V>(t : Trie<K, V>) : Bool {\n size(t) == 0\n };\n\n /// Filter the key-value pairs by a given predicate.\n public func filter<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Trie<K, V> {\n func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, V> {\n switch t {\n case (#empty) { #empty };\n case (#leaf(l)) {\n leaf(\n List.filter(\n l.keyvals,\n func ((k : Key<K>, v : V)) : Bool = f(k.key, v)\n ),\n bitpos\n )\n };\n case (#branch(b)) {\n let fl = rec(b.left, bitpos + 1);\n let fr = rec(b.right, bitpos + 1);\n if (isEmpty(fl) and isEmpty(fr)) {\n #empty\n } else {\n branch(fl, fr)\n }\n }\n }\n };\n rec(t, 0)\n };\n\n /// Map and filter the key-value pairs by a given predicate.\n public func mapFilter<K, V, W>(t : Trie<K, V>, f : (K, V) -> ?W) : Trie<K, W> {\n func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, W> {\n switch t {\n case (#empty) { #empty };\n case (#leaf(l)) {\n leaf(\n List.mapFilter(\n l.keyvals,\n // retain key and hash, but update key's value using f:\n func ((k : Key<K>, v : V)) : ?(Key<K>, W) {\n switch (f(k.key, v)) {\n case null { null };\n case (?w) { ?({key = k.key; hash = k.hash}, w) };\n }\n }\n ),\n bitpos\n )\n };\n case (#branch(b)) {\n let fl = rec(b.left, bitpos + 1);\n let fr = rec(b.right, bitpos + 1);\n if (isEmpty(fl) and isEmpty(fr)) {\n #empty\n } else {\n branch(fl, fr)\n }\n }\n }\n };\n\n rec(t, 0)\n };\n\n /// Test for equality, but naively, based on structure.\n /// Does not attempt to remove \"junk\" in the tree;\n /// For instance, a \"smarter\" approach would equate\n /// `#bin {left = #empty; right = #empty}`\n /// with\n /// `#empty`.\n /// We do not observe that equality here.\n public func equalStructure<K, V>(\n tl : Trie<K, V>,\n tr : Trie<K, V>,\n keq : (K, K) -> Bool,\n veq : (V, V) -> Bool\n ) : Bool {\n func rec(tl : Trie<K, V>, tr : Trie<K, V>) : Bool {\n switch (tl, tr) {\n case (#empty, #empty) { true };\n case (#leaf(l1), #leaf(l2)) {\n List.equal(l1.keyvals, l2.keyvals,\n func ((k1 : Key<K>, v1 : V), (k2 : Key<K>, v2 : V)) : Bool =\n keq(k1.key, k2.key) and veq(v1, v2)\n )\n };\n case (#branch(b1), #branch(b2)) {\n rec(b1.left, b2.left) and rec(b2.right, b2.right)\n };\n case _ { false };\n }\n };\n rec(tl, tr)\n };\n\n /// Replace the given key's value in the trie,\n /// and only if successful, do the success continuation,\n /// otherwise, return the failure value\n public func replaceThen<K, V, X>(\n t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v2 : V,\n success: (Trie<K, V>, V) -> X,\n fail: () -> X\n ) : X {\n let (t2, ov) = replace(t, k, k_eq, ?v2);\n switch ov {\n case null { /* no prior value; failure to remove */ fail() };\n case (?v1) { success(t2, v1) };\n }\n };\n\n /// Put the given key's value in the trie; return the new trie; assert that no prior value is associated with the key\n public func putFresh<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : Trie<K, V> {\n let (t2, none) = replace(t, k, k_eq, ?v);\n switch none {\n case null {};\n case (?_) assert false;\n };\n t2\n };\n\n /// Put the given key's value in the 2D trie; return the new 2D trie.\n public func put2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n v:V\n ) : Trie2D<K1, K2, V> {\n let inner = find(t, k1, k1_eq);\n let (updated_inner, _) = switch inner {\n case null { put(#empty, k2, k2_eq, v) };\n case (?inner) { put(inner, k2, k2_eq, v) };\n };\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n updated_outer;\n };\n\n /// Put the given key's value in the trie; return the new trie;\n public func put3D<K1, K2, K3, V> (\n t : Trie3D<K1, K2, K3, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n k3 : Key<K3>,\n k3_eq : (K3, K3) -> Bool,\n v : V\n ) : Trie3D<K1, K2, K3, V> {\n let inner1 = find(t, k1, k1_eq);\n let (updated_inner1, _) = switch inner1 {\n case null {\n put(\n #empty, k2, k2_eq,\n (put(#empty, k3, k3_eq, v)).0\n )\n };\n case (?inner1) {\n let inner2 = find(inner1, k2, k2_eq);\n let (updated_inner2, _) = switch inner2 {\n case null { put(#empty, k3, k3_eq, v) };\n case (?inner2) { put(inner2, k3, k3_eq, v) };\n };\n put(inner1, k2, k2_eq, updated_inner2 )\n };\n };\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner1);\n updated_outer;\n };\n\n /// Remove the given key's value in the trie; return the new trie\n public func remove<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : (Trie<K, V>, ?V) {\n replace(t, k, k_eq, null)\n };\n\n /// Remove the given key's value in the trie,\n /// and only if successful, do the success continuation,\n /// otherwise, return the failure value\n public func removeThen<K, V, X>(\n t : Trie<K, V>,\n k : Key<K>,\n k_eq : (K, K) -> Bool,\n success : (Trie<K, V>, V) -> X,\n fail : () -> X\n ) : X {\n let (t2, ov) = replace(t, k, k_eq, null);\n switch ov {\n case null { /* no prior value; failure to remove */ fail() };\n case (?v) { success(t2, v) };\n }\n };\n\n\n /// remove the given key-key pair's value in the 2D trie; return the\n /// new trie, and the prior value, if any.\n public func remove2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool\n ) : (Trie2D<K1, K2, V>, ?V) {\n switch (find(t, k1, k1_eq)) {\n case null {\n (t, null)\n };\n case (?inner) {\n let (updated_inner, ov) = remove(inner, k2, k2_eq);\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n (updated_outer, ov)\n };\n }\n };\n\n /// Remove the given key-key pair's value in the 3D trie; return the\n /// new trie, and the prior value, if any.\n public func remove3D<K1, K2, K3, V>(\n t : Trie3D<K1, K2, K3, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n k3 : Key<K3>,\n k3_eq : (K3, K3) -> Bool,\n ) : (Trie3D<K1, K2, K3, V>, ?V) {\n switch (find(t, k1, k1_eq)) {\n case null {\n (t, null)\n };\n case (?inner) {\n let (updated_inner, ov) = remove2D(inner, k2, k2_eq, k3, k3_eq);\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n (updated_outer, ov)\n };\n }\n };\n\n /// Like [`mergeDisjoint`](#mergedisjoint), except instead of merging a\n /// pair, it merges the collection of dimension-2 sub-trees of a 2D\n /// trie.\n public func mergeDisjoint2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1_eq : (K1, K1) -> Bool,\n k2_eq : (K2, K2) -> Bool\n ) : Trie<K2, V> {\n foldUp(\n t,\n func (t1 : Trie<K2, V>, t2 : Trie<K2, V>) : Trie<K2, V> {\n mergeDisjoint(t1, t2, k2_eq)\n },\n func (_ : K1, t : Trie<K2, V>) : Trie<K2, V> { t },\n #empty\n )\n };\n\n}\n"},"None.mo":{"content":"/// The absent value\n///\n/// The `None` type represents a type with _no_ value.\n///\n/// It is often used to type code that fails to return control (e.g. an infinite loop)\n/// or to designate impossible values (e.g. the type `?None` only contains `null`).\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// The empty type. A subtype of all types.\n public type None = Prim.Types.None;\n\n /// Turns an absurd value into an arbitrary type.\n public let impossible : <A> None -> A = func<A>(x : None) : A {\n switch (x) {};\n };\n}\n"},"Nat8.mo":{"content":"/// 8-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 8-bit natural numbers.\n public type Nat8 = Prim.Types.Nat8;\n\n /// Conversion.\n public let toNat : Nat8 -> Nat = Prim.nat8ToNat;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromNat : Nat -> Nat8 = Prim.natToNat8;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Nat8 = Prim.intToNat8Wrap;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Nat8) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat8, y : Nat8) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat8, y : Nat8) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat8, y : Nat8) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat8, y : Nat8) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat8, y : Nat8) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat8, y : Nat8) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat8, y : Nat8) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Nat8, y : Nat8) : Nat8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Nat8, y : Nat8) : Nat8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Nat8, y : Nat8) : Nat8 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat8, y : Nat8) : Nat8 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat8, y : Nat8) : Nat8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Nat8, y : Nat8) : Nat8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Nat8, y : Nat8) : Nat8 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Nat8, y : Nat8) : Nat8 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Nat8, y : Nat8) : Nat8 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Nat8, y : Nat8) : Nat8 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Nat8, y : Nat8) : Nat8 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Nat8, y : Nat8) : Nat8 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Nat8, y : Nat8) : Nat8 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Nat8, y : Nat8) : Nat8 { x <>> y };\n\n /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`.\n public func bittest(x : Nat8, p : Nat) : Bool {\n Prim.btstNat8(x, Prim.natToNat8(p));\n };\n\n /// Returns the value of setting bit `p mod 8` in `x` to `1`.\n public func bitset(x : Nat8, p : Nat) : Nat8 {\n x | (1 << Prim.natToNat8(p));\n };\n\n /// Returns the value of clearing bit `p mod 8` in `x` to `0`.\n public func bitclear(x : Nat8, p : Nat) : Nat8 {\n x & ^(1 << Prim.natToNat8(p));\n };\n\n /// Returns the value of flipping bit `p mod 8` in `x`.\n public func bitflip(x : Nat8, p : Nat) : Nat8 {\n x ^ (1 << Prim.natToNat8(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Nat8) -> Nat8 = Prim.popcntNat8;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Nat8) -> Nat8 = Prim.clzNat8;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Nat8) -> Nat8 = Prim.ctzNat8;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Nat8, y : Nat8) : Nat8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Nat8, y : Nat8) : Nat8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Nat8, y : Nat8) : Nat8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n public func powWrap(x : Nat8, y : Nat8) : Nat8 { x **% y };\n\n}\n"},"Nat64.mo":{"content":"/// 64-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 64-bit natural numbers.\n public type Nat64 = Prim.Types.Nat64;\n\n /// Conversion.\n public let toNat : Nat64 -> Nat = Prim.nat64ToNat;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromNat : Nat -> Nat64 = Prim.natToNat64;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Nat64 = Prim.intToNat64Wrap;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Nat64) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat64, y : Nat64) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat64, y : Nat64) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat64, y : Nat64) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat64, y : Nat64) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat64, y : Nat64) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat64, y : Nat64) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat64, y : Nat64) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Nat64, y : Nat64) : Nat64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Nat64, y : Nat64) : Nat64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Nat64, y : Nat64) : Nat64 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat64, y : Nat64) : Nat64 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat64, y : Nat64) : Nat64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Nat64, y : Nat64) : Nat64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Nat64, y : Nat64) : Nat64 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Nat64, y : Nat64) : Nat64 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Nat64, y : Nat64) : Nat64 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Nat64, y : Nat64) : Nat64 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Nat64, y : Nat64) : Nat64 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Nat64, y : Nat64) : Nat64 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Nat64, y : Nat64) : Nat64 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Nat64, y : Nat64) : Nat64 { x <>> y };\n\n /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`.\n public func bittest(x : Nat64, p : Nat) : Bool {\n Prim.btstNat64(x, Prim.natToNat64(p));\n };\n\n /// Returns the value of setting bit `p mod 64` in `x` to `1`.\n public func bitset(x : Nat64, p : Nat) : Nat64 {\n x | (1 << Prim.natToNat64(p));\n };\n\n /// Returns the value of clearing bit `p mod 64` in `x` to `0`.\n public func bitclear(x : Nat64, p : Nat) : Nat64 {\n x & ^(1 << Prim.natToNat64(p));\n };\n\n /// Returns the value of flipping bit `p mod 64` in `x`.\n public func bitflip(x : Nat64, p : Nat) : Nat64 {\n x ^ (1 << Prim.natToNat64(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Nat64) -> Nat64 = Prim.popcntNat64;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Nat64) -> Nat64 = Prim.clzNat64;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Nat64) -> Nat64 = Prim.ctzNat64;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Nat64, y : Nat64) : Nat64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Nat64, y : Nat64) : Nat64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Nat64, y : Nat64) : Nat64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n public func powWrap(x : Nat64, y : Nat64) : Nat64 { x **% y };\n\n}\n"},"Nat32.mo":{"content":"/// 32-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 32-bit natural numbers.\n public type Nat32 = Prim.Types.Nat32;\n\n /// Conversion.\n public let toNat : Nat32 -> Nat = Prim.nat32ToNat;\n\n /// Conversion. Traps on overflow/underflow.\n public let fromNat : Nat -> Nat32 = Prim.natToNat32;\n\n /// Conversion. Wraps on overflow/underflow.\n public let fromIntWrap : Int -> Nat32 = Prim.intToNat32Wrap;\n\n /// Returns the Text representation of `x`.\n public func toText(x : Nat32) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n public func min(x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n public func max( x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { y } else { x }\n };\n\n /// Returns `x == y`.\n public func equal(x : Nat32, y : Nat32) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Nat32, y : Nat32) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Nat32, y : Nat32) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Nat32, y : Nat32) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Nat32, y : Nat32) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Nat32, y : Nat32) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Nat32, y : Nat32) : { #less; #equal; #greater } {\n if (x < y) { #less }\n else if (x == y) { #equal }\n else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n public func add(x : Nat32, y : Nat32) : Nat32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n public func sub(x : Nat32, y : Nat32) : Nat32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n public func mul(x : Nat32, y : Nat32) : Nat32 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n public func div(x : Nat32, y : Nat32) : Nat32 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n public func rem(x : Nat32, y : Nat32) : Nat32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n public func pow(x : Nat32, y : Nat32) : Nat32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n public func bitnot(x : Nat32, y : Nat32) : Nat32 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n public func bitand(x : Nat32, y : Nat32) : Nat32 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x \\| y`.\n public func bitor(x : Nat32, y : Nat32) : Nat32 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n public func bitxor(x : Nat32, y : Nat32) : Nat32 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n public func bitshiftLeft(x : Nat32, y : Nat32) : Nat32 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n public func bitshiftRight(x : Nat32, y : Nat32) : Nat32 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n public func bitrotLeft(x : Nat32, y : Nat32) : Nat32 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n public func bitrotRight(x : Nat32, y : Nat32) : Nat32 { x <>> y };\n\n /// Returns the value of bit `p mod 32` in `x`, `(x & 2^(p mod 32)) == 2^(p mod 32)`.\n public func bittest(x : Nat32, p : Nat) : Bool {\n Prim.btstNat32(x, Prim.natToNat32(p));\n };\n\n /// Returns the value of setting bit `p mod 32` in `x` to `1`.\n public func bitset(x : Nat32, p : Nat) : Nat32 {\n x | (1 << Prim.natToNat32(p));\n };\n\n /// Returns the value of clearing bit `p mod 32` in `x` to `0`.\n public func bitclear(x : Nat32, p : Nat) : Nat32 {\n x & ^(1 << Prim.natToNat32(p));\n };\n\n /// Returns the value of flipping bit `p mod 32` in `x`.\n public func bitflip(x : Nat32, p : Nat) : Nat32 {\n x ^ (1 << Prim.natToNat32(p));\n };\n\n /// Returns the count of non-zero bits in `x`.\n public let bitcountNonZero : (x : Nat32) -> Nat32 = Prim.popcntNat32;\n\n /// Returns the count of leading zero bits in `x`.\n public let bitcountLeadingZero : (x : Nat32) -> Nat32 = Prim.clzNat32;\n\n /// Returns the count of trailing zero bits in `x`.\n public let bitcountTrailingZero : (x : Nat32) -> Nat32 = Prim.ctzNat32;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n public func addWrap(x : Nat32, y : Nat32) : Nat32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n public func subWrap(x : Nat32, y : Nat32) : Nat32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n public func mulWrap(x : Nat32, y : Nat32) : Nat32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n public func powWrap(x : Nat32, y : Nat32) : Nat32 { x **% y };\n\n}\n"},"List.mo":{"content":"/// Purely-functional, singly-linked lists.\n\nimport Array \"Array\";\nimport Iter \"IterType\";\nimport Option \"Option\";\nimport Order \"Order\";\nimport Result \"Result\";\n\nmodule {\n\n // A singly-linked list consists of zero or more _cons cells_, wherein\n // each cell contains a single list element (the cell's _head_), and a pointer to the\n // remainder of the list (the cell's _tail_).\n public type List<T> = ?(T, List<T>);\n\n /// Create an empty list.\n public func nil<T>() : List<T> = null;\n\n /// Check whether a list is empty and return true if the list is empty.\n public func isNil<T>(l : List<T>) : Bool {\n switch l {\n case null { true };\n case _ { false };\n }\n };\n\n /// Construct a list by pre-pending a value.\n /// This function is similar to a `list.cons(item)` function.\n public func push<T>(x : T, l : List<T>) : List<T> = ?(x, l);\n\n /// Return the last element of the list, if present.\n public func last<T>(l : List<T>) : ?T {\n switch l {\n case null { null };\n case (?(x, null)) { ?x };\n case (?(_, t)) { last<T>(t) };\n }\n };\n\n /// Treat the list as a stack.\n /// This function combines the `head` and (non-failing) `tail` operations into one operation.\n public func pop<T>(l : List<T>) : (?T, List<T>) {\n switch l {\n case null { (null, null) };\n case (?(h, t)) { (?h, t) };\n }\n };\n\n /// Return the length of the list.\n public func size<T>(l : List<T>) : Nat {\n func rec(l : List<T>, n : Nat) : Nat {\n switch l {\n case null { n };\n case (?(_, t)) { rec(t, n + 1) };\n }\n };\n rec(l,0)\n };\n /// Access any item in a list, zero-based.\n ///\n /// NOTE: Indexing into a list is a linear operation, and usually an\n /// indication that a list might not be the best data structure\n /// to use.\n public func get<T>(l : List<T>, n : Nat) : ?T {\n switch (n, l) {\n case (_, null) { null };\n case (0, (?(h, t))) { ?h };\n case (_, (?(_, t))) { get<T>(t, n - 1) };\n }\n };\n\n /// Reverses the list\n public func reverse<T>(l : List<T>) : List<T> {\n func rec(l : List<T>, r : List<T>) : List<T> {\n switch l {\n case null { r };\n case (?(h, t)) { rec(t, ?(h, r)) };\n }\n };\n rec(l, null)\n };\n\n /// Call the given function with each list element in turn.\n ///\n /// This function is equivalent to the `app` function in Standard ML Basis,\n /// and the `iter` function in OCaml.\n public func iterate<T>(l : List<T>, f : T -> ()) {\n switch l {\n case null { () };\n case (?(h, t)) { f(h); iterate<T>(t, f) };\n }\n };\n\n /// Call the given function on each list element and collect the results\n /// in a new list.\n public func map<T, S>(l : List<T>, f : T -> S) : List<S> {\n switch l {\n case null { null };\n case (?(h, t)) { ?(f(h), map<T, S>(t, f)) };\n }\n };\n\n /// Create a new list with only those elements of the original list for which\n /// the given function (often called the _predicate_) returns true.\n public func filter<T>(l : List<T>, f : T -> Bool) : List<T> {\n switch l {\n case null { null };\n case (?(h,t)) {\n if (f(h)) {\n ?(h,filter<T>(t, f))\n } else {\n filter<T>(t, f)\n }\n };\n };\n };\n\n /// Create two new lists from the results of a given function (`f`).\n /// The first list only includes the elements for which the given\n /// function `f` returns true and the second list only includes\n /// the elements for which the function returns false.\n public func partition<T>(l : List<T>, f : T -> Bool) : (List<T>, List<T>) {\n switch l {\n case null { (null, null) };\n case (?(h, t)) {\n if (f(h)) { // call f in-order\n let (l, r) = partition<T>(t, f);\n (?(h, l), r)\n } else {\n let (l, r) = partition<T>(t, f);\n (l, ?(h, r))\n }\n };\n };\n };\n\n /// Call the given function on each list element, and collect the non-null results\n /// in a new list.\n public func mapFilter<T,S>(l : List<T>, f : T -> ?S) : List<S> {\n switch l {\n case null { null };\n case (?(h,t)) {\n switch (f(h)) {\n case null { mapFilter<T,S>(t, f) };\n case (?h_){ ?(h_,mapFilter<T,S>(t, f)) };\n }\n };\n };\n };\n\n /// Maps a Result-returning function over a List and returns either\n /// the first error or a list of successful values.\n public func mapResult<A, R, E>(xs : List<A>, f : A -> Result.Result<R, E>) : Result.Result<List<R>, E> {\n func go(xs : List<A>, acc : List<R>) : Result.Result<List<R>, E> {\n switch xs {\n case null { #ok(acc) };\n case (?(head, tail)) {\n switch (f(head)) {\n case (#err(err)) { #err(err) };\n case (#ok(ok)) { go(tail, ?(ok, acc)) };\n };\n };\n }\n };\n Result.mapOk(go(xs, null), func (xs : List<R>) : List<R> = reverse(xs))\n };\n\n /// Append the elements from the reverse of one list to another list.\n func revAppend<T>(l : List<T>, m : List<T>) : List<T> {\n switch l {\n case null { m };\n case (?(h, t)) { revAppend(t, ?(h, m)) };\n }\n };\n\n /// Append the elements from one list to another list.\n public func append<T>(l : List<T>, m : List<T>) : List<T> {\n revAppend(reverse(l), m);\n };\n\n /// Concatenate a list of lists.\n ///\n /// In some languages, this operation is also known as a `list join`.\n public func flatten<T>(l : List<List<T>>) : List<T> {\n foldLeft<List<T>, List<T>>(l, null, func(a, b) { append<T>(a,b) });\n };\n\n /// Returns the first `n` elements of the given list.\n /// If the given list has fewer than `n` elements, this function returns\n /// a copy of the full input list.\n public func take<T>(l : List<T>, n:Nat) : List<T> {\n switch (l, n) {\n case (_, 0) { null };\n case (null, _) { null };\n case (?(h, t), m) {?(h, take<T>(t, m - 1))};\n }\n };\n\n /// Drop the first `n` elements from the given list.\n public func drop<T>(l : List<T>, n:Nat) : List<T> {\n switch (l, n) {\n case (l_, 0) { l_ };\n case (null, _) { null };\n case ((?(h, t)), m) { drop<T>(t, m - 1) };\n }\n };\n\n /// Fold the list left-to-right using the given function (`f`).\n public func foldLeft<T, S>(l : List<T>, a : S, f : (S, T) -> S) : S {\n switch l {\n case null { a };\n case (?(h, t)) { foldLeft(t, f(a, h), f) };\n };\n };\n\n /// Fold the list right-to-left using the given function (`f`).\n public func foldRight<T, S>(l : List<T>, a : S, f : (T, S) -> S) : S {\n switch l {\n case null { a };\n case (?(h, t)) { f(h, foldRight<T,S>(t, a, f)) };\n };\n };\n\n /// Return the first element for which the given predicate `f` is true,\n /// if such an element exists.\n public func find<T>(l: List<T>, f:T -> Bool) : ?T {\n switch l {\n case null { null };\n case (?(h, t)) { if (f(h)) { ?h } else { find<T>(t, f) } };\n };\n };\n\n /// Return true if there exists a list element for which\n /// the given predicate `f` is true.\n public func some<T>(l : List<T>, f : T -> Bool) : Bool {\n switch l {\n case null { false };\n case (?(h, t)) { f(h) or some<T>(t, f)};\n };\n };\n\n /// Return true if the given predicate `f` is true for all list\n /// elements.\n public func all<T>(l : List<T>, f : T -> Bool) : Bool {\n switch l {\n case null { true };\n case (?(h, t)) { f(h) and all<T>(t, f) };\n }\n };\n\n /// Merge two ordered lists into a single ordered list.\n /// This function requires both list to be ordered as specified\n /// by the given relation `lte`.\n public func merge<T>(l1 : List<T>, l2 : List<T>, lte : (T, T) -> Bool) : List<T> {\n switch (l1, l2) {\n case (null, _) { l2 };\n case (_, null) { l1 };\n case (?(h1, t1), ?(h2, t2)) {\n if (lte(h1, h2)) {\n ?(h1, merge<T>(t1, l2, lte))\n } else {\n ?(h2, merge<T>(l1, t2, lte))\n }\n };\n }\n };\n\n /// Compare two lists using lexicographic ordering specified by the given relation `lte`.\n public func compare<T>(l1 : List<T>, l2 : List<T>, compElm: (T, T) -> Order.Order) : Order.Order {\n switch (l1, l2) {\n case (null, null) { #equal };\n case (null, _) { #less };\n case (_, null) { #greater };\n case (?(h1, t1), ?(h2, t2)) {\n let hOrder = compElm(h1, h2);\n if (Order.isEqual(hOrder)) {\n compare<T>(t1, t2, compElm)\n } else {\n hOrder\n }\n };\n };\n };\n\n /// Compare two lists for equality as specified by the given relation `eq` on the elements.\n ///\n /// The function `isEq(l1, l2)` is equivalent to `lessThanEq(l1, l2) && lessThanEq(l2, l1)`,\n /// but the former is more efficient.\n public func equal<T>(l1 : List<T>, l2 : List<T>, eq :(T, T) -> Bool) : Bool {\n switch (l1, l2) {\n case (null, null) { true };\n case (null, _) { false };\n case (_, null) { false };\n case (?(h1, t1), ?(h2, t2)) { eq(h1, h2) and equal<T>(t1, t2, eq) };\n }\n };\n\n /// Generate a list based on a length and a function that maps from\n /// a list index to a list element.\n public func tabulate<T>(n : Nat, f : Nat -> T) : List<T> {\n var i = 0;\n var l : List<T> = null;\n while (i < n) {\n l := ?(f(i), l);\n i += 1;\n };\n reverse(l);\n };\n\n /// Create a list with exactly one element.\n public func make<X>(x : X) : List<X> = ?(x, null);\n\n /// Create a list of the given length with the same value in each position.\n public func replicate<X>(n : Nat, x : X) : List<X> {\n var i = 0;\n var l : List<X> = null;\n while (i < n) {\n l := ?(x, l);\n i += 1;\n };\n l;\n };\n\n /// Create a list of pairs from a pair of lists.\n ///\n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n public func zip<X, Y>(xs : List<X>, ys : List<Y>) : List<(X, Y)> =\n zipWith<X, Y, (X, Y)>(xs, ys, func (x, y) { (x, y) });\n\n /// Create a list in which elements are calculated from the function `f` and\n /// include elements occuring at the same position in the given lists.\n ///\n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n public func zipWith<X, Y, Z>(\n xs : List<X>,\n ys : List<Y>,\n f : (X, Y) -> Z\n ) : List<Z> {\n switch (pop<X>(xs)) {\n case (null, _) { null };\n case (?x, xt) {\n switch (pop<Y>(ys)) {\n case (null, _) { null };\n case (?y, yt) {\n push<Z>(f(x, y), zipWith<X, Y, Z>(xt, yt, f))\n }\n }\n }\n }\n };\n\n /// Split the given list at the given zero-based index.\n public func split<X>(n : Nat, xs : List<X>) : (List<X>, List<X>) {\n if (n == 0) {\n (null, xs)\n } else {\n func rec(n : Nat, xs : List<X>) : (List<X>, List<X>) {\n switch (pop<X>(xs)) {\n case (null, _) {\n (null, null)\n };\n case (?h, t) {\n if (n == 1) {\n (make<X>(h), t)\n } else {\n let (l, r) = rec(n - 1, t);\n (push<X>(h, l), r)\n }\n }\n }\n };\n rec(n, xs)\n }\n };\n\n /// Split the given list into chunks of length `n`.\n /// The last chunk will be shorter if the length of the given list\n /// does not divide by `n` evenly.\n public func chunks<X>(n : Nat, xs : List<X>) : List<List<X>> {\n let (l, r) = split<X>(n, xs);\n if (isNil<X>(l)) {\n null\n } else {\n push<List<X>>(l, chunks<X>(n, r))\n }\n };\n\n /// Convert an array into a list.\n public func fromArray<A>(xs : [A]) : List<A> {\n Array.foldRight<A, List<A>>(\n xs, nil<A>(),\n func (x : A, ys : List<A>) : List<A> {\n push<A>(x, ys);\n });\n };\n\n /// Convert a mutable array into a list.\n public func fromVarArray<A>(xs : [var A]) : List<A> =\n fromArray<A>(Array.freeze<A>(xs));\n\n /// Create an array from a list.\n public func toArray<A>(xs : List<A>) : [A] {\n let length = size<A>(xs);\n var list = xs;\n Array.tabulate<A>(length, func (i) {\n let popped = pop<A>(list);\n list := popped.1;\n switch (popped.0) {\n case null { loop { assert false } };\n case (?x) x;\n }\n });\n };\n\n /// Create a mutable array from a list.\n public func toVarArray<A>(xs : List<A>) : [var A] =\n Array.thaw<A>(toArray<A>(xs));\n\n /// Create an iterator from a list.\n public func toIter<A>(xs : List<A>) : Iter.Iter<A> {\n var state = xs;\n object {\n public func next() : ?A =\n switch state {\n case (?(hd, tl)) { state := tl; ?hd };\n case _ null\n }\n }\n }\n\n}\n"}}}