import { Ternary } from '../../util/logic';
import { AbstractDomain } from './abstract-domain';
import { Bottom, Top } from './lattice';
import { type SetDomain, SetComparator } from './value-abstract-domain';
/** The type of the actual values of the set upper bound domain as set */
type SetUpperBoundValue<T> = ReadonlySet<T>;
/** The type of the Top element of the set upper bound domain as {@link Top} symbol */
type SetUpperBoundTop = typeof Top;
/** The type of the Bottom element of the set upper bound domain as {@link Bottom} symbol */
type SetUpperBoundBottom = typeof Bottom;
/** The type of the abstract values of the set upper bound domain that are Top, Bottom, or actual values */
type SetUpperBoundLift<T> = SetUpperBoundValue<T> | SetUpperBoundTop | SetUpperBoundBottom;
/**
 * The set upper bound abstract domain as sets capturing possible values of the concrete set bounded by a `limit` for the maximum number of inferred values.
 * The Bottom element is defined as the{@link Bottom} 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 SetUpperBoundDomain<T, Value extends SetUpperBoundLift<T> = SetUpperBoundLift<T>> extends AbstractDomain<SetUpperBoundValue<T>, SetUpperBoundTop, SetUpperBoundBottom, Value> implements SetDomain<T> {
    readonly limit: number;
    protected readonly setType: typeof Set<T>;
    /**
     * @param limit -  A limit for the maximum number of elements to store in the set
     * @param newSet - An optional set constructor for the domain elements if the type `T` is not storable in a HashSet
     */
    constructor(value: Value | T[], limit?: number, setType?: typeof Set<T>);
    create(value: SetUpperBoundLift<T> | T[]): this;
    from(...values: ReadonlySet<T>[] | T[][]): this;
    static top<T>(limit?: number, setType?: typeof Set<T>): SetUpperBoundDomain<T, SetUpperBoundTop>;
    static bottom<T>(limit?: number, setType?: typeof Set<T>): SetUpperBoundDomain<T, SetUpperBoundBottom>;
    static from<T>(values: Set<T> | T[] | Set<T>[] | T[][], limit?: number, setType?: typeof Set<T>): SetUpperBoundDomain<T>;
    top(): this & SetUpperBoundDomain<T, SetUpperBoundTop>;
    bottom(): this & SetUpperBoundDomain<T, SetUpperBoundBottom>;
    protected equalsValue(this: SetUpperBoundDomain<T, SetUpperBoundValue<T>>, other: SetUpperBoundDomain<T, SetUpperBoundValue<T>>): boolean;
    protected leqValue(this: SetUpperBoundDomain<T, SetUpperBoundValue<T>>, other: SetUpperBoundDomain<T, SetUpperBoundValue<T>>): boolean;
    protected joinValue(this: this & SetUpperBoundDomain<T, SetUpperBoundValue<T>>, other: SetUpperBoundDomain<T, SetUpperBoundValue<T>>): this;
    protected meetValue(this: this & SetUpperBoundDomain<T, SetUpperBoundValue<T>>, other: SetUpperBoundDomain<T, SetUpperBoundValue<T>>): this;
    union(other: this | SetUpperBoundLift<T> | T[]): this;
    intersect(other: this | SetUpperBoundLift<T> | T[]): this;
    subtract(other: this | SetUpperBoundLift<T>): this;
    satisfies(set: ReadonlySet<T> | T[], comparator?: SetComparator): Ternary;
    protected jsonify(this: SetUpperBoundDomain<T, SetUpperBoundValue<T>>): unknown;
    protected stringify(this: SetUpperBoundDomain<T, SetUpperBoundValue<T>>): string;
    isTop(): this is this & SetUpperBoundDomain<T, SetUpperBoundTop>;
    isBottom(): this is this & SetUpperBoundDomain<T, SetUpperBoundBottom>;
    isValue(): this is this & SetUpperBoundDomain<T, SetUpperBoundValue<T>>;
}
export {};
