import type { MapFunction as IterableMapFunction } from "@nodef/extra-iterable";
/**
 * Handle reading of a single value.
 * @returns value
 */ export type ReadFunction<T> = () => T;
/**
 * Handle combining of two values.
 * @param a a value
 * @param b another value
 * @returns combined value
 */ export type CombineFunction<T> = (a: T, b: T) => T;
/**
 * Handle comparison of two values.
 * @param a a value
 * @param b another value
 * @returns a<b: -ve, a=b: 0, a>b: +ve
 */ export type CompareFunction<T> = (a: T, b: T) => number;
/**
 * Handle processing of values in a set.
 * @param v value in set
 * @param k key of value in set (= value)
 * @param x set containing the value
 */ export type ProcessFunction<T> = (v: T, k: T, x: Set<T>) => void;
/**
 * Handle selection of values in a set.
 * @param v value in set
 * @param k key of value in set (= value)
 * @param x set containing the value
 * @returns selected?
 */ export type TestFunction<T> = (v: T, k: T, x: Set<T>) => boolean;
/**
 * Handle transformation of a value to another.
 * @param v value in set
 * @param k key of value in set (= value)
 * @param x set containing the value
 * @returns transformed value
 */ export type MapFunction<T, U> = (v: T, k: T, x: Set<T> | null) => U;
/**
 * Handle reduction of multiple values into a single value.
 * @param acc accumulator (temporary result)
 * @param v value in set
 * @param k key of value in set (= value)
 * @param x set containing the value
 * @returns reduced value
 */ export type ReduceFunction<T, U> = (acc: U, v: T, k: T, x: Set<T>) => U;
/**
 * Handle ending of a combined set.
 * @param dones iᵗʰ set done?
 * @returns combined set done?
 */ export type EndFunction = (dones: boolean[]) => boolean;
/**
 * Check if value is a set.
 * @param v a value
 * @returns v is a set?
 */ export declare function is(v: unknown): v is Set<unknown>;
/**
 * List all values.
 * @param x a set
 * @returns v₀, v₁, ... | vᵢ ∈ x
 */ export declare function values<T>(x: Set<T>): IterableIterator<T>;
export { values as keys };
/**
 * List all value-value pairs.
 * @param x a set
 * @returns [v₀, v₀], [v₁, v₁], ... | vᵢ ∈ x
 */ export declare function entries<T>(x: Set<T>): IterableIterator<[T, T]>;
/**
 * Convert an iterable to set.
 * @param x an iterable
 * @param fm map function (v, i, x)
 * @returns x as set
 */ export declare function from<T, U = T>(x: Iterable<T>, fm?: IterableMapFunction<T, U> | null): Set<T | U>;
/**
 * Convert an iterable to set.
 * @param x an iterable (updatable if set!)
 * @returns x as set
 */ export declare function from$<T>(x: Iterable<T>): Set<T>;
/**
 * Compare two sets.
 * @param x a set
 * @param y another set
 * @returns x=y: 0, otherwise: -ve/+ve
 */ export declare function compare<T>(x: Set<T>, y: Set<T>): number;
/**
 * Check if two sets are equal.
 * @param x a set
 * @param y another set
 * @returns x = y?
 */ export declare function isEqual<T>(x: Set<T>, y: Set<T>): boolean;
/**
 * Find the size of a set.
 * @param x a set
 * @returns |x|
 */ export declare function size<T>(x: Set<T>): number;
export { size as length };
/**
 * Check if a set is empty.
 * @param x a set
 * @returns |x| = 0?
 */ export declare function isEmpty<T>(x: Set<T>): boolean;
/**
 * Add a value to set.
 * @param x a set
 * @param v value
 * @returns x ∪ \{v\}
 */ export declare function add<T>(x: Set<T>, v: T): Set<T>;
/**
 * Add a value to set.
 * @param x a set (updated)
 * @param v value
 * @returns x = x ∪ \{v\}
 */ export declare function add$<T>(x: Set<T>, v: T): Set<T>;
/**
 * Delete a value from set.
 * @param x a set
 * @param v value
 * @returns x \\ \{v\}
 */ export declare function remove<T>(x: Set<T>, v: T): Set<T>;
/**
 * Delete a value from set.
 * @param x a set (updated)
 * @param v value
 * @returns x = x \\ \{v\}
 */ export declare function remove$<T>(x: Set<T>, v: T): Set<T>;
/**
 * Count values which satisfy a test.
 * @param x a set
 * @param ft test function (v, v, x)
 * @returns Σtᵢ | tᵢ = 1 if ft(vᵢ) else 0; vᵢ ∈ x
 */ export declare function count<T>(x: Set<T>, ft: TestFunction<T>): number;
/**
 * Count occurrences of values.
 * @param x a set
 * @param fm map function (v, v, x)
 * @returns Map \{value ⇒ count\}
 */ export declare function countAs<T, U = T>(x: Set<T>, fm: MapFunction<T, T | U>): Map<T | U, number>;
/**
 * Find smallest value.
 * @param x a set
 * @param fc compare function (a, b)
 * @param fm map function (v, v, x)
 * @returns v | v ≤ vᵢ; vᵢ ∈ x
 */ export declare function min<T, U = T>(x: Set<T>, fc?: CompareFunction<T | U> | null, fm?: MapFunction<T, T | U> | null): T | undefined;
/**
 * Find largest value.
 * @param x a set
 * @param fc compare function (a, b)
 * @param fm map function (v, v, x)
 * @returns v | v ≥ vᵢ; vᵢ ∈ x
 */ export declare function max<T, U = T>(x: Set<T>, fc?: CompareFunction<T | U> | null, fm?: MapFunction<T, T | U> | null): T | undefined;
/**
 * Find smallest and largest entries.
 * @param x a set
 * @param fc compare function (a, b)
 * @param fm map function (v, v, x)
 * @returns [min_value, max_value]
 */ export declare function range<T, U = T>(x: Set<T>, fc?: CompareFunction<T | U> | null, fm?: MapFunction<T, T | U> | null): [T | undefined, T | undefined];
/**
 * Get first value from set (default order).
 * @param x a set
 * @param vd default value
 * @returns v₀ if x ≠ Φ else vd | v₀ ∈ x
 */ export declare function head<T>(x: Set<T>, vd?: T): T | undefined;
/**
 * Get a set without its first value (default order).
 * @param x a set
 * @returns x \\ \{v₀\} if x ≠ Φ else x | v₀ ∈ x
 */ export declare function tail<T>(x: Set<T>): Set<T>;
/**
 * Keep first n values only (default order).
 * @param x a set
 * @param n number of values [1]
 * @returns \{v₀, v₁, ...\} | vᵢ ∈ x and |\{v₀, v₁, ...\}| ≤ n
 */ export declare function take<T>(x: Iterable<T>, n?: number): Set<T>;
/**
 * Keep first n values only (default order).
 * @param x a set (updated)
 * @param n number of values [1]
 * @returns x = \{v₀, v₁, ...\} | vᵢ ∈ x and |\{v₀, v₁, ...\}| ≤ n
 */ export declare function take$<T>(x: Set<T>, n?: number): Set<T>;
/**
 * Remove first n values (default order).
 * @param x a set
 * @param n number of values [1]
 * @returns \{vₙ, vₙ₊₁, ...\} | vᵢ ∈ x and |\{vₙ, vₙ₊₁, ...\}| ≤ max(|x| - n, 0)
 */ export declare function drop<T>(x: Set<T>, n?: number): Set<T>;
/**
 * Remove first n values (default order).
 * @param x a set (updated)
 * @param n number of values [1]
 * @returns x = \{vₙ, vₙ₊₁, ...\} | vᵢ ∈ x and |\{vₙ, vₙ₊₁, ...\}| ≤ max(|x| - n, 0)
 */ export declare function drop$<T>(x: Set<T>, n?: number): Set<T>;
/**
 * List all possible subsets.
 * @param x a set
 * @param n number of values [-1 ⇒ any]
 * @returns elements selected by bit from 0..2^|x| if n<0; only of length n otherwise
 */ export declare function subsets<T>(x: Set<T>, n?: number): IterableIterator<Set<T>>;
/**
 * Pick an arbitrary value.
 * @param x a set
 * @param fr random number generator ([0, 1))
 * @returns vᵢ | vᵢ ∈ x
 */ export declare function randomValue<T>(x: Set<T>, fr?: ReadFunction<number>): T;
export { randomValue as randomKey };
export { randomValue as value };
export { randomValue as key };
/**
 * Pick an arbitrary entry.
 * @param x a set
 * @param fr random number generator ([0, 1))
 * @returns [vᵢ, vᵢ] | vᵢ ∈ x
 */ export declare function randomEntry<T>(x: Set<T>, fr?: ReadFunction<number>): [T, T];
export { randomEntry as entry };
/**
 * Pick an arbitrary subset.
 * @param x a set
 * @param n number of values [-1 ⇒ any]
 * @param fr random number generator ([0, 1))
 * @returns \{vᵢ, vⱼ, ...\} | vᵢ, vⱼ, ... ∈ x; |\{vᵢ, vⱼ, ...\}| = |x| if n<0 else n
 */ export declare function randomSubset<T>(x: Set<T>, n?: number, fr?: ReadFunction<number>): Set<T>;
/**
 * Checks if set has a subset.
 * @param x a set
 * @param y search subset
 * @returns y ⊆ x?
 */ export declare function hasSubset<T>(x: Set<T>, y: Set<T>): boolean;
/**
 * Check if set has a value.
 * @param x a set
 * @param v search value
 * @returns v ∈ x?
 */ export declare function has<T>(x: Set<T>, v: T): boolean;
/**
 * Find first value passing a test (default order).
 * @param x a set
 * @param ft test function (v, v, x)
 * @returns first v | ft(v) = true; v ∈ x
 */ export declare function find<T>(x: Set<T>, ft: TestFunction<T>): T | undefined;
export { find as search };
/**
 * Find all values passing a test.
 * @param x a set
 * @param ft test function (v, v, x)
 * @returns [v₀, v₁, ...] | ft(vᵢ) = true; vᵢ ∈ x
 */ export declare function findAll<T>(x: Set<T>, ft: TestFunction<T>): T[];
export { findAll as searchAll };
/**
 * Call a function for each value.
 * @param x a set
 * @param fp process function (v, v, x)
 */ export declare function forEach<T>(x: Set<T>, fp: ProcessFunction<T>): void;
/**
 * Check if any value satisfies a test.
 * @param x a set
 * @param ft test function (v, v, x)
 * @returns true if ft(vᵢ) = true for some vᵢ ∈ x
 */ export declare function some<T>(x: Set<T>, ft?: TestFunction<T> | null): boolean;
/**
 * Check if all values satisfy a test.
 * @param x a set
 * @param ft test function (v, v, x)
 * @returns true if ft(vᵢ) = true for all vᵢ ∈ x
 */ export declare function every<T>(x: Set<T>, ft?: TestFunction<T> | null): boolean;
/**
 * Transform values of a set.
 * @param x a set
 * @param fm map function (v, v, x)
 * @returns \{fm(v₀), fm(v₁), ...\} | vᵢ ∈ x
 */ export declare function map<T, U = T>(x: Set<T>, fm: MapFunction<T, T | U>): Set<T | U>;
/**
 * Transform values of a set.
 * @param x a set (updated)
 * @param fm map function (v, v, x)
 * @returns x = \{fm(v₀), fm(v₁), ...\} | vᵢ ∈ x
 */ export declare function map$<T>(x: Set<T>, fm: MapFunction<T, T>): Set<T>;
/**
 * Reduce values of set to a single value.
 * @param x a set
 * @param fr reduce function (acc, v, v, x)
 * @param acc initial value
 * @returns fr(fr(acc, v₀), v₁)... | fr(acc, v₀) = v₀ if acc not given
 */ export declare function reduce<T, U = T>(x: Set<T>, fr: ReduceFunction<T, T | U>, acc?: T | U): T | U;
/**
 * Keep values which pass a test.
 * @param x a set
 * @param ft test function (v, v, x)
 * @returns \{v₀, v₁, ...\} | ft(vᵢ) = true; vᵢ ∈ x
 */ export declare function filter<T>(x: Set<T>, ft: TestFunction<T>): Set<T>;
/**
 * Keep values which pass a test.
 * @param x a set (updated)
 * @param ft test function (v, v, x)
 * @returns x = \{v₀, v₁, ...\} | ft(vᵢ) = true; vᵢ ∈ x
 */ export declare function filter$<T>(x: Set<T>, ft: TestFunction<T>): Set<T>;
/**
 * Discard values which pass a test.
 * @param x a set
 * @param ft test function (v, v, x)
 * @returns \{v₀, v₁, ...\} | ft(vᵢ) = false; vᵢ ∈ x
 */ export declare function reject<T>(x: Set<T>, ft: TestFunction<T>): Set<T>;
/**
 * Discard values which pass a test.
 * @param x a set (updated)
 * @param ft test function (v, v, x)
 * @returns x = \{v₀, v₁, ...\} | ft(vᵢ) = false; vᵢ ∈ x
 */ export declare function reject$<T>(x: Set<T>, ft: TestFunction<T>): Set<T>;
/**
 * Flatten nested set to given depth.
 * @param x a nested set
 * @param n maximum depth [-1 ⇒ all]
 * @param fm map function (v, v, x)
 * @param ft flatten test function (v, v, x) [is]
 * @returns flat set
 */ export declare function flat<T = unknown>(x: Set<T>, n?: number, fm?: MapFunction<T, unknown> | null, ft?: TestFunction<T> | null): Set<unknown>;
/**
 * Flatten nested set, based on map function.
 * @param x a nested set
 * @param fm map function (v, v, x)
 * @param ft flatten test function (v, v, x) [is]
 * @returns flat set
 */ export declare function flatMap<T = unknown>(x: Set<T>, fm?: MapFunction<T, unknown> | null, ft?: TestFunction<T> | null): Set<unknown>;
/**
 * Segregate values by test result.
 * @param x a set
 * @param ft test function (v, v, x)
 * @returns [satisfies, doesnt]
 */ export declare function partition<T>(x: Set<T>, ft: TestFunction<T>): [Set<T>, Set<T>];
/**
 * Segregates values by similarity.
 * @param x a set
 * @param fm map function (v, v, x)
 * @returns Map \{key ⇒ values\}
 */ export declare function partitionAs<T, U = T>(x: Set<T>, fm: MapFunction<T, T | U>): Map<T | U, Set<T>>;
/**
 * Break set into chunks of given size.
 * @param x a set
 * @param n chunk size [1]
 * @param s chunk step [n]
 * @returns [x[0..n], x[s..s+n], x[2s..2s+n], ...]
 */ export declare function chunk<T>(x: Set<T>, n?: number, s?: number): Set<T>[];
/**
 * Append values from sets.
 * @param xs sets
 * @returns x₀ ∪ x₁ ∪ ... | [x₀, x₁, ...] = xs
 */ export declare function concat<T>(...xs: Set<T>[]): Set<T>;
/**
 * Append values from sets.
 * @param x a set (updated)
 * @param ys other sets
 * @returns x = x ∪ y₀ ∪ y₁ ∪ ... | [y₀, y₁, ...] = ys
 */ export declare function concat$<T>(x: Set<T>, ...ys: Iterable<T>[]): Set<T>;
/**
 * Join values together into a string.
 * @param x a set
 * @param sep separator [,]
 * @returns "$\{v₀\}$\{sep\}$\{v₁\}..." | vᵢ ∈ x
 */ export declare function join<T>(x: Set<T>, sep?: string): string;
/**
 * Check if sets have no value in common.
 * @param x a set
 * @param y another set
 * @returns x ∩ y = Φ?
 */ export declare function isDisjoint<T>(x: Set<T>, y: Iterable<T>): boolean;
/**
 * Obtain values present in any set.
 * @param x a set
 * @param y another set
 * @returns x ∪ y = \{v | v ∈ x or v ∈ y\}
 */ export declare function union<T>(x: Iterable<T>, y: Iterable<T>): Set<T>;
/**
 * Obtain values present in any set.
 * @param x a set (updated)
 * @param y another set
 * @returns x = x ∪ y = \{v | v ∈ x or v ∈ y\}
 */ export declare function union$<T>(x: Set<T>, y: Iterable<T>): Set<T>;
/**
 * Obtain values present in both sets.
 * @param x a set
 * @param y another set
 * @returns x ∩ y = \{v | v ∈ x, v ∈ y\}
 */ export declare function intersection<T>(x: Set<T>, y: Iterable<T>): Set<T>;
/**
 * Obtain values present in both sets.
 * @param x a set (updated)
 * @param y another set
 * @returns x = x ∩ y = \{v | v ∈ x, v ∈ y\}
 */ export declare function intersection$<T>(x: Set<T>, y: Set<T>): Set<T>;
/**
 * Obtain values not present in another set.
 * @param x a set
 * @param y another set
 * @returns x - y = \{v | v ∈ x, v ∉ y\}
 */ export declare function difference<T>(x: Set<T>, y: Set<T>): Set<T>;
/**
 * Obtain values not present in another set.
 * @param x a set (updated)
 * @param y another set
 * @returns x = x - y = \{v | v ∈ x, v ∉ y\}
 */ export declare function difference$<T>(x: Set<T>, y: Iterable<T>): Set<T>;
/**
 * Obtain values not present in both sets.
 * @param x a set
 * @param y another set
 * @returns x-y ∪ y-x
 */ export declare function symmetricDifference<T>(x: Set<T>, y: Set<T>): Set<T>;
/**
 * Obtain values not present in both sets.
 * @param x a set (updated)
 * @param y another set
 * @returns x = x-y ∪ y-x
 */ export declare function symmetricDifference$<T>(x: Set<T>, y: Iterable<T>): Set<T>;
/**
 * List cartesian product of sets.
 * @param xs sets
 * @param fm map function (vs, vs)
 * @returns x₀ × x₁ × ... = \{\{v₀, v₁, ...\} | v₀ ∈ x₀, v₁ ∈ x₁, ...]\}
 */ export declare function cartesianProduct<T, U = Set<T>>(xs: Set<T>[], fm?: MapFunction<Set<T>, Set<T> | U> | null): IterableIterator<Set<T> | U>;
export default cartesianProduct;
