import { Ternary } from '../../util/logic';
import { AbstractDomain } from './abstract-domain';
import { Bottom, Top } from './lattice';
import { SetComparator, type SetDomain } from './value-abstract-domain';
/** The Top element of the set range domain with an empty set as must set and {@link Top} as may set */
export declare const SetRangeTop: {
    readonly must: Set<never>;
    readonly may: typeof Top;
};
/** The type of the actual values of the set range domain as tuple with a set of values that must be present and a set of values that may be present (i.e. `[{"id","name"}, ∅]`, or `[{"id"}, {"score"}]`) */
export type SetRangeValue<T> = {
    readonly must: ReadonlySet<T>;
    readonly may: ReadonlySet<T> | typeof Top;
};
/** The type of the Top element of the set range domain as tuple with the empty set as must set and {@link Top} as may set (i.e. `[∅, Top]`) */
type SetRangeTop = typeof SetRangeTop;
/** The type of the Bottom element of the set range domain as {@link Bottom} */
type SetRangeBottom = typeof Bottom;
/** The type of the abstract values of the set range domain that are Top, Bottom, or actual values */
type SetRangeLift<T> = SetRangeValue<T> | SetRangeTop | SetRangeBottom;
/** The type of the actual values of the set range domain with a finite may set (the may set cannot be Top) */
type SetRangeFinite<T> = {
    readonly must: ReadonlySet<T>;
    readonly may: ReadonlySet<T>;
};
type SetRangeMustSet<T, Value extends SetRangeLift<T>> = Value extends SetRangeValue<T> ? ReadonlySet<T> : ReadonlySet<T> | typeof Bottom;
type SetRangeMaySet<T, Value extends SetRangeLift<T>> = Value extends SetRangeFinite<T> ? ReadonlySet<T> : Value extends SetRangeValue<T> ? ReadonlySet<T> | typeof Top : ReadonlySet<T> | typeof Top | typeof Bottom;
/** The type of the actual values of the set range domain as array tuple with a must array and may array for better readability (e.g. `[["id","name"], []]`, or `[["id"], ["score"]]`) */
export type ArrayRangeValue<T> = {
    readonly must: T[];
    readonly may: T[] | typeof Top;
};
/** The type for the maximum number of elements in the must set and may set of the set range domain before over-approximation */
export type SetRangeLimit = {
    readonly must: number;
    readonly may: number;
};
/**
 * The set range abstract domain as range of possible value sets with a set of values that must be present and a set of values that may be present
 * (similar to an interval-like structure with a lower bound and a difference to the upper bound).
 * The Bottom element is defined as {@link Bottom} symbol and the Top element is defined as the range `[∅, Top]` where the must set is the empty set and the may set is {@link Top}.
 * @template T     - Type of the values in the sets in the abstract domain
 * @template Value - Type of the constraint in the abstract domain (Top, Bottom, or an actual value)
 */
export declare class SetRangeDomain<T, Value extends SetRangeLift<T> = SetRangeLift<T>> extends AbstractDomain<SetRangeValue<T>, SetRangeTop, SetRangeBottom, Value> implements SetDomain<T> {
    readonly limit: SetRangeLimit;
    protected readonly setType: typeof Set<T>;
    /**
     * @param limit -  A limit for the maximum number of elements to store in the must set and may set before over-approximation
     * @param newSet - An optional set constructor for the domain elements if the type `T` is not storable in a HashSet
     */
    constructor(value: Value | ArrayRangeValue<T>, limit?: SetRangeLimit | number, setType?: typeof Set<T>);
    create(value: SetRangeLift<T> | ArrayRangeValue<T>): this;
    /**
     * The set of values that must be present in the set.
     */
    get must(): SetRangeMustSet<T, Value>;
    /**
     * The set of values that may be present in the set (can be {@link Top}).
     */
    get may(): SetRangeMaySet<T, Value>;
    /**
     * The lower bound of the set range representing all values that must be present (equals the must set).
     */
    lower(this: SetRangeDomain<T, SetRangeValue<T>>): ReadonlySet<T>;
    lower(this: SetRangeDomain<T, SetRangeLift<T>>): ReadonlySet<T> | typeof Bottom;
    /**
     * The upper bound of the set range representing all values that can possibly be present (union of must set and may set).
     */
    upper(this: SetRangeDomain<T, SetRangeFinite<T>>): ReadonlySet<T>;
    upper(this: SetRangeDomain<T, SetRangeValue<T>>): ReadonlySet<T> | typeof Top;
    upper(this: SetRangeDomain<T, SetRangeLift<T>>): ReadonlySet<T> | typeof Top | typeof Bottom;
    from(...values: ReadonlySet<T>[] | T[][]): this;
    static top<T>(limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T, SetRangeTop>;
    static bottom<T>(limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T, SetRangeBottom>;
    static from<T>(values: Set<T> | T[] | Set<T>[] | T[][], limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T>;
    top(): this & SetRangeDomain<T, SetRangeTop>;
    bottom(): this & SetRangeDomain<T, SetRangeBottom>;
    protected equalsValue(this: SetRangeDomain<T, SetRangeValue<T>>, other: SetRangeDomain<T, SetRangeValue<T>>): boolean;
    protected leqValue(this: SetRangeDomain<T, SetRangeValue<T>>, other: SetRangeDomain<T, SetRangeValue<T>>): boolean;
    protected joinValue(this: this & SetRangeDomain<T, SetRangeValue<T>>, other: SetRangeDomain<T, SetRangeValue<T>>): this;
    protected meetValue(this: this & SetRangeDomain<T, SetRangeValue<T>>, other: SetRangeDomain<T, SetRangeValue<T>>): this;
    union(other: this | SetRangeLift<T> | ArrayRangeValue<T>): this;
    intersect(other: this | SetRangeLift<T> | ArrayRangeValue<T>): this;
    subtract(other: this | SetRangeLift<T> | ArrayRangeValue<T>): this;
    protected widenValue(this: this & SetRangeDomain<T, SetRangeValue<T>>, other: SetRangeDomain<T, SetRangeValue<T>>): this;
    protected narrowValue(this: this & SetRangeDomain<T, SetRangeValue<T>>, other: SetRangeDomain<T, SetRangeValue<T>>): this;
    satisfies(set: ReadonlySet<T> | T[], comparator?: SetComparator): Ternary;
    /**
     * Extends the must set of the current abstract value down to the empty set.
     */
    widenDown(): this;
    /**
     * Extends the may set of the current abstract value up to {@link Top}.
     */
    widenUp(): this;
    protected jsonify(this: SetRangeDomain<T, SetRangeValue<T>>): unknown;
    protected stringify(this: SetRangeDomain<T, SetRangeValue<T>>): string;
    isTop(): this is this & SetRangeDomain<T, SetRangeTop>;
    isBottom(): this is this & SetRangeDomain<T, SetRangeBottom>;
    isValue(): this is this & SetRangeDomain<T, SetRangeValue<T>>;
    isFinite(): this is this & SetRangeDomain<T, SetRangeFinite<T>>;
    isInfinite(): this is this & SetRangeDomain<T, {
        readonly must: ReadonlySet<T>;
        readonly may: typeof Top;
    }>;
}
export {};
