import { Ternary } from '../../util/logic';
import { AbstractDomain } from './abstract-domain';
import { Bottom, Top } from './lattice';
import type { SatisfiableDomain } from './satisfiable-domain';
import { SetComparator } from './satisfiable-domain';
/** The Top element of the set range domain with an empty set as minimum set and {@link Top} as range set */
export declare const SetRangeTop: {
    readonly min: Set<never>;
    readonly range: typeof Top;
};
/** The type of the actual values of the set range domain as tuple with a minimum set and range set of additional possible values (i.e. `[{"id","name"}, ∅]`, or `[{"id"}, {"score"}]`) */
type SetRangeValue<T> = {
    readonly min: ReadonlySet<T>;
    readonly range: ReadonlySet<T> | typeof Top;
};
/** The type of the Top element of the set range domain as tuple with the empty set as minimum set and {@link Top} as range 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 range (the range cannot be Top) */
type SetRangeFinite<T> = {
    readonly min: ReadonlySet<T>;
    readonly range: ReadonlySet<T>;
};
/** The type of the actual values of the set range domain as array tuple with a minimum array and range array for better readability (e.g. `[["id","name"], []]`, or `[["id"], ["score"]]`) */
export type ArrayRangeValue<T> = {
    readonly min: T[];
    readonly range: T[] | typeof Top;
};
/** The type for the maximum number of elements in the minimum set and maximum set of the set range domain before over-approximation */
export type SetRangeLimit = {
    readonly min: number;
    readonly range: number;
};
/**
 * The set range abstract domain as range of possible value sets with a minimum set of values and a range of possible additional values
 * (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 minimum set is the empty set and the range 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<ReadonlySet<T>, SetRangeValue<T>, SetRangeTop, SetRangeBottom, Value> implements SatisfiableDomain<ReadonlySet<T>> {
    readonly limit: SetRangeLimit;
    private readonly setType;
    /**
     * @param limit -  A limit for the maximum number of elements to store in the minimum set and maximum 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 minimum set (lower bound) of the set range representing all values that must exist (subset of {@link upper}).
     */
    lower(): Value extends SetRangeValue<T> ? ReadonlySet<T> : ReadonlySet<T> | typeof Bottom;
    /**
     * The maximum set (upper bound) of the set range representing all values that can possibly exist (union of {@link lower} and range).
     */
    upper(): Value extends SetRangeFinite<T> ? ReadonlySet<T> : Value extends SetRangeValue<T> ? ReadonlySet<T> | typeof Top : ReadonlySet<T> | typeof Top | typeof Bottom;
    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 abstract<T>(concrete: ReadonlySet<ReadonlySet<T>> | typeof Top, limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T>;
    top(): this & SetRangeDomain<T, SetRangeTop>;
    bottom(): this & SetRangeDomain<T, SetRangeBottom>;
    equals(other: this): boolean;
    leq(other: this): boolean;
    join(other: SetRangeLift<T> | ArrayRangeValue<T>): this;
    join(other: this): this;
    meet(other: SetRangeLift<T> | ArrayRangeValue<T>): this;
    meet(other: this): this;
    /**
     * Creates the union of this abstract value and another abstract value by creating the union of the minimum and maximum set, respectively.
     */
    union(other: this | SetRangeLift<T> | ArrayRangeValue<T>): this;
    /**
     * Creates the intersection of this abstract value and another abstract value by creating the intersection of the minimum and maximum set, respectively.
     */
    intersect(other: this | SetRangeLift<T> | ArrayRangeValue<T>): this;
    /**
     * 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: this | SetRangeLift<T> | ArrayRangeValue<T>): this;
    widen(other: this): this;
    narrow(other: this): this;
    concretize(limit: number): ReadonlySet<ReadonlySet<T>> | typeof Top;
    abstract(concrete: ReadonlySet<ReadonlySet<T>> | typeof Top): this;
    satisfies(set: ReadonlySet<T> | T[], comparator?: SetComparator): Ternary;
    /**
     * Extends the minimum set of the current abstract value down to the empty set.
     */
    widenDown(): this;
    /**
     * Extends the maximum set of the current abstract value up to {@link Top}.
     */
    widenUp(): this;
    toJson(): unknown;
    toString(): string;
    isTop(): this is SetRangeDomain<T, SetRangeTop>;
    isBottom(): this is SetRangeDomain<T, SetRangeBottom>;
    isValue(): this is SetRangeDomain<T, SetRangeValue<T>>;
    isFinite(): this is SetRangeDomain<T, SetRangeFinite<T>>;
}
export {};
