UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

116 lines 3.75 kB
"use strict"; /* ---------------------------------------------------------------------------------- * Copyright 2023 Informal Systems * Licensed under the Apache License, Version 2.0. * See LICENSE in the project root for license information. * --------------------------------------------------------------------------------- */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.insertSorted = exports.findMap = exports.zip = exports.unreachable = void 0; /** * General purpose utilities used within the quint codebase * * @author Shon Feder * * @module */ const json_bigint_1 = __importDefault(require("json-bigint")); const lodash_1 = __importDefault(require("lodash")); const maybe_1 = require("@sweet-monads/maybe"); /** Add this at the end of a switch statement or if/then sequence to enforce exhaustiveness checking * * E.g., * * ``` * switch (foo.bar) { * case 'bax': ... * case 'qux': ... * default: unreachable(foo) * } * ``` * See https://stackoverflow.com/a/39419171 */ function unreachable(object) { throw new Error(`impossible: non-exhuastive check should fail during type checking ${json_bigint_1.default.stringify(object)}`); } exports.unreachable = unreachable; /** A wrapper around lodash zip that ensures all zipped elements are defined * * Raises `Error` if the arrays are not the same length */ function zip(a, b) { return lodash_1.default.zip(a, b).map(([x, y]) => { if (x === undefined || y === undefined) { throw new Error('Illegal arguments to zip: array lengths unequal'); } else { return [x, y]; } }); } exports.zip = zip; /** `findMap(xs)` is `just(y)` if there is an `x` in `xs` for which `f(x)` is `just(y)` * otherwise, it is `none` * * This is like `Array.prototype.find`, except that it works on any iterable and * enables transforming the found value. * * Example: * * ``` * const result = findMap([1,2,3], (x) => x % 2 === 0 ? just(x) : none<int>()) * lodash.isEqual(result, just(2)) * ``` * */ function findMap(xs, f) { for (const x of xs) { const maybeY = f(x); if (maybeY.isJust()) { return maybeY; } } return (0, maybe_1.none)(); } exports.findMap = findMap; /** Insert an item into an array sorted in ascending order by the given comparator. * * Important: The array must be sorted in ascending order. * * Complexity: O(log n) */ function insertSorted(array, item, cmp) { if (array.length === 0) { array.push(item); return; } const index = findInsertionIndex(array, x => cmp(x, item) > 0); array.splice(index, 0, item); } exports.insertSorted = insertSorted; /** Find the first `index` in `array` where the predicate `pred(array[index])` is true. * * Important: The array must be sorted in ascending order. * * Implements a binary search with complexity: O(log n) * * This function is not exported as it is only meant to be used internally by `insertSorted`. */ function findInsertionIndex(array, pred) { var low = 0; var high = array.length; while (low < high) { // Integer version of `Math.floor((low + high) / 2)` const mid = (low + high) >>> 1; if (pred(array[mid])) { // The element at mid satisfies the predicate, so we need to search to the left high = mid; } else { // The element at mid does not satisfy the predicate, so we need to search to the right low = mid + 1; } } return low; } //# sourceMappingURL=util.js.map