motoko 3.0.2 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contrib/monaco.js +30 -1
- package/contrib/snippets.json +425 -0
- package/lib/ast.d.ts +1 -0
- package/lib/ast.d.ts.map +1 -1
- package/lib/ast.js +6 -0
- package/lib/ast.js.map +1 -1
- package/package.json +2 -2
- package/packages/latest/base.json +1 -1
- package/src/ast.ts +10 -0
- package/versions/latest/moc.min.js +1 -1
- package/versions/latest/moc_interpreter.min.js +1 -1
@@ -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(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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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 + 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"}}}
|