import { type AbstractDomain } from './abstract-domain';
import { Top } from './lattice';
/** The type of an abstract product of a product domain mapping named properties of the product to abstract domains */
export type AbstractProduct = Record<string, AbstractDomain<unknown, unknown, unknown, unknown>>;
/** The type of the concrete product of an abstract product mapping each property to a concrete value in the respective concrete domain */
export type ConcreteProduct<Product extends AbstractProduct> = {
    [Key in keyof Product]: Product[Key] extends AbstractDomain<infer Concrete, unknown, unknown, unknown> ? Concrete : never;
};
/**
 * A product abstract domain as named Cartesian product of sub abstract domains.
 * The sub abstract domains are represented a record mapping property names to abstract domains.
 * The Bottom element is defined as mapping every sub abstract domain to Bottom and the Top element is defined as mapping every sub abstract domain to Top.
 * @template Product - Type of the abstract product of the product domain mapping property names to abstract domains
 */
export declare abstract class ProductDomain<Product extends AbstractProduct> implements AbstractDomain<ConcreteProduct<Product>, Product, Product, Product> {
    private _value;
    constructor(value: Product);
    /**
     * Creates an abstract value of the product domain for a given abstract value.
     */
    abstract create(value: Product): ProductDomain<Product>;
    get value(): Product;
    bottom(): ProductDomain<Product>;
    top(): ProductDomain<Product>;
    equals(other: ProductDomain<Product>): boolean;
    leq(other: ProductDomain<Product>): boolean;
    join(...values: ProductDomain<Product>[]): ProductDomain<Product>;
    meet(...values: ProductDomain<Product>[]): ProductDomain<Product>;
    widen(other: ProductDomain<Product>): ProductDomain<Product>;
    narrow(other: ProductDomain<Product>): ProductDomain<Product>;
    concretize(limit?: number): ReadonlySet<ConcreteProduct<Product>> | typeof Top;
    abstract(concrete: ReadonlySet<ConcreteProduct<Product>> | typeof Top): ProductDomain<Product>;
    toString(): string;
    isTop(): this is ProductDomain<Product>;
    isBottom(): this is ProductDomain<Product>;
    isValue(): this is ProductDomain<Product>;
}
