import { type AbstractDomain } from './abstract-domain';
import { Top } from './lattice';
/** The type of the actual values of the bounded set domain as set */
export type BoundedSetValue<T> = ReadonlySet<T>;
/** The type of the Top element of the bounded set domain as {@link Top} symbol */
export type BoundedSetTop = typeof Top;
/** The type of the Bottom element of the bounded set domain as empty set */
export type BoundedSetBottom = ReadonlySet<never>;
/** The type of the abstract values of the bounded set domain that are Top, Bottom, or actual values */
export type BoundedSetLift<T> = BoundedSetValue<T> | BoundedSetTop | BoundedSetBottom;
/**
 * The bounded set abstract domain as sets of possible values bounded by a `limit` indicating the maximum number of inferred values.
 * The Bottom element is defined as the empty set and the Top element is defined as {@link Top} symbol.
 * @template T     - Type of the values in the abstract domain
 * @template Value - Type of the constraint in the abstract domain (Top, Bottom, or an actual value)
 */
export declare class BoundedSetDomain<T, Value extends BoundedSetLift<T> = BoundedSetLift<T>> implements AbstractDomain<T, BoundedSetValue<T>, BoundedSetTop, BoundedSetBottom, Value> {
    private readonly limit;
    private _value;
    constructor(value: Value, limit?: number);
    get value(): Value;
    static top<T>(limit?: number): BoundedSetDomain<T, BoundedSetTop>;
    static bottom<T>(limit?: number): BoundedSetDomain<T, BoundedSetBottom>;
    static abstract<T>(concrete: ReadonlySet<T> | typeof Top, limit?: number): BoundedSetDomain<T>;
    top(): BoundedSetDomain<T, BoundedSetTop>;
    bottom(): BoundedSetDomain<T, BoundedSetBottom>;
    equals(other: BoundedSetDomain<T>): boolean;
    leq(other: BoundedSetDomain<T>): boolean;
    join(...values: BoundedSetDomain<T>[]): BoundedSetDomain<T>;
    meet(...values: BoundedSetDomain<T>[]): BoundedSetDomain<T>;
    /**
     * Subtracts another abstract value from the current abstract value by removing all elements of the other abstract value from the current abstract value.
     */
    subtract(other: BoundedSetDomain<T>): BoundedSetDomain<T>;
    widen(other: BoundedSetDomain<T>): BoundedSetDomain<T>;
    narrow(other: BoundedSetDomain<T>): BoundedSetDomain<T>;
    concretize(limit?: number): ReadonlySet<T> | typeof Top;
    abstract(concrete: ReadonlySet<T> | typeof Top): BoundedSetDomain<T>;
    toString(): string;
    isTop(): this is BoundedSetDomain<T, BoundedSetTop>;
    isBottom(): this is BoundedSetDomain<T, BoundedSetBottom>;
    isValue(): this is BoundedSetDomain<T, BoundedSetValue<T>>;
}
