import { type JSONSchema } from '../json-schema/index.js';
import type { RawDNF, ConjunctionOfLiterals } from '../atomic-schema/to-raw-dnf/index.js';
import type { JSONSchemaType } from '../json-schema-type/index.js';
import { type InternalOptions, type Options, type OptionsSimplificationPlugin } from '../options/index.js';
import { type NonConstConjunctionSchemaObject, type ConjunctionSchemaObject, type SimplificationPlugin, type SimplificationResultSchemaByType, type SimplificationResultSchemaForType, type ValidateConst } from '../plugin/index.js';
import type { InstancesByConstructor } from '../utils/instances-by-constructor/index.js';
import type { BuiltInSimplificationPlugin } from '../built-in-plugins/index.js';
export declare function createValidateConst(options: InternalOptions, schema: JSONSchema): ValidateConst;
/**
 * Brings the given disjunct of a {@link RawDNF} to a simpler canonical form by
 * summarizing keywords. Returns `false` (which is a valid JSON Schema) if there
 * is a contradiction in the disjunct.
 *
 */
export declare function simplifyDisjunct<Type extends JSONSchemaType, SimplificationPlugin_ extends SimplificationPlugin>({ type, atomicSchemasByConstructor, negatedAtomicSchemasByConstructor, options, validateConst, }: {
    type: Type;
    atomicSchemasByConstructor: InstancesByConstructor;
    negatedAtomicSchemasByConstructor: InstancesByConstructor;
    options: InternalOptions<SimplificationPlugin_>;
    validateConst: ValidateConst;
}): SimplificationResultSchemaForType<SimplificationPlugin_, Type>;
export type JSONSchemaTypeForDNF = Exclude<JSONSchemaType, 'null' | 'boolean'>;
export declare function isJSONSchemaTypeForDNF(type: JSONSchemaType): type is JSONSchemaTypeForDNF;
/**
 * @param rawDisjunct Represents multiple disjuncts, because there might be
 * multiple types
 *
 */
export declare function simplifyRawDisjunct<SimplificationPlugin_ extends SimplificationPlugin>(rawDisjunct: ConjunctionOfLiterals, validateConst: ValidateConst, options: InternalOptions<SimplificationPlugin_>): SimplificationResultSchemaByType<SimplificationPlugin_, JSONSchemaTypeForDNF>[];
export type Disjunct<SimplificationPlugin_ extends SimplificationPlugin> = Exclude<SimplificationResultSchemaByType<SimplificationPlugin_, JSONSchemaTypeForDNF>, boolean>;
export type DNF<SimplificationPlugin_ extends SimplificationPlugin> = boolean | {
    anyOf: Disjunct<SimplificationPlugin_>[];
};
/**
 * This is equivalent to
 *
 * ```ts
 * type GeneralDNFSpelledOut =
 *   | boolean
 *   | {
 *       anyOf: (
 *         | { const: unknown }
 *         | {
 *             [mergeableKeyword: string]: unknown
 *             type: 'string' | 'number' | 'object' | 'array'
 *             allOf?: JSONSchema[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *       )[]
 *     }
 * ```
 *
 */
export type GeneralDNF = DNF<SimplificationPlugin>;
/**
 * Is equivalent to {@link GeneralDNF}
 *
 */
export type GeneralDNFSpelledOut = boolean | {
    anyOf: ({
        const: unknown;
    } | {
        [mergeableKeyword: string]: unknown;
        type: 'string' | 'number' | 'object' | 'array';
        allOf?: JSONSchema[];
        const?: never;
        anyOf?: never;
        not?: never;
    })[];
};
/**
 * This is equivalent to
 *
 * ```ts
 * type DefaultDNFSpelledOut =
 *   | boolean
 *   | {
 *       anyOf: (
 *         | { const: unknown }
 *         | {
 *             type: 'number'
 *             maximum?: number
 *             minimum?: number
 *             multipleOf?: number
 *             allOf?: (
 *               | { not: { const: number } }
 *               | { not: { multipleOf: number } }
 *               | { $ref: string }
 *               | { not: { $ref: string } }
 *             )[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *         | {
 *             type: 'string'
 *             maxLength?: number
 *             minLength?: number
 *             allOf?: (
 *               | { not: { const: string } }
 *               | { pattern: string }
 *               | { not: { pattern: string } }
 *               | { $ref: string }
 *               | { not: { $ref: string } }
 *             )[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *         | {
 *             type: 'object'
 *             maxProperties?: number
 *             minProperties?: number
 *             patternProperties?: Record<string, JSONSchema>
 *             properties?: Record<string, JSONSchema>
 *             propertyNames?: JSONSchema
 *             required?: string[]
 *             allOf?: (
 *               | { not: { const: Record<string, unknown> } }
 *               | {
 *                   additionalProperties: JSONSchema
 *                   properties?: Record<string, true>
 *                   patternProperties?: Record<string, true>
 *                 }
 *               | { not: { patternProperties: Record<string, JSONSchema> } }
 *               | {
 *                   not: {
 *                     additionalProperties: JSONSchema
 *                     properties?: Record<string, true>
 *                     patternProperties?: Record<string, true>
 *                   }
 *                 }
 *               | { not: { propertyNames: JSONSchema } }
 *               | { $ref: string }
 *               | { not: { $ref: string } }
 *             )[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *         | {
 *             type: 'array'
 *             items?: JSONSchema
 *             maxItems?: number
 *             minItems?: number
 *             prefixItems?: JSONSchema[]
 *             uniqueItems?: boolean
 *             allOf?: (
 *               | { not: { const: unknown[] } }
 *               | {
 *                   contains: JSONSchema
 *                   minContains?: number
 *                   maxContains?: number
 *                 }
 *               | {
 *                   not: { uniqueItems?: boolean }
 *                 }
 *               | {
 *                   not: {
 *                     prefixItems?: true[]
 *                     items?: JSONSchema
 *                   }
 *                 }
 *               | { $ref: string }
 *               | { not: { $ref: string } }
 *             )[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *       )[]
 *     }
 * ```
 *
 */
export type DefaultDNF = DNF<BuiltInSimplificationPlugin>;
/**
 * Is equivalent to {@link DefaultDNF}
 *
 */
export type DefaultDNFSpelledOut = boolean | {
    anyOf: ({
        const: unknown;
    } | {
        type: 'number';
        maximum?: number;
        minimum?: number;
        multipleOf?: number;
        allOf?: ({
            not: {
                const: number;
            };
        } | {
            not: {
                multipleOf: number;
            };
        } | {
            $ref: string;
        } | {
            not: {
                $ref: string;
            };
        })[];
        const?: never;
        anyOf?: never;
        not?: never;
    } | {
        type: 'string';
        maxLength?: number;
        minLength?: number;
        allOf?: ({
            not: {
                const: string;
            };
        } | {
            pattern: string;
        } | {
            not: {
                pattern: string;
            };
        } | {
            $ref: string;
        } | {
            not: {
                $ref: string;
            };
        })[];
        const?: never;
        anyOf?: never;
        not?: never;
    } | {
        type: 'object';
        maxProperties?: number;
        minProperties?: number;
        patternProperties?: Record<string, JSONSchema>;
        properties?: Record<string, JSONSchema>;
        propertyNames?: JSONSchema;
        required?: string[];
        allOf?: ({
            not: {
                const: Record<string, unknown>;
            };
        } | {
            additionalProperties: JSONSchema;
            properties?: Record<string, true>;
            patternProperties?: Record<string, true>;
        } | {
            not: {
                patternProperties: Record<string, JSONSchema>;
            };
        } | {
            not: {
                additionalProperties: JSONSchema;
                properties?: Record<string, true>;
                patternProperties?: Record<string, true>;
            };
        } | {
            not: {
                propertyNames: JSONSchema;
            };
        } | {
            $ref: string;
        } | {
            not: {
                $ref: string;
            };
        })[];
        const?: never;
        anyOf?: never;
        not?: never;
    } | {
        type: 'array';
        items?: JSONSchema;
        maxItems?: number;
        minItems?: number;
        prefixItems?: JSONSchema[];
        uniqueItems?: boolean;
        allOf?: ({
            not: {
                const: unknown[];
            };
        } | {
            contains: JSONSchema;
            minContains?: number;
            maxContains?: number;
        } | {
            not: {
                uniqueItems?: boolean;
            };
        } | {
            not: {
                prefixItems?: true[];
                items?: JSONSchema;
            };
        } | {
            $ref: string;
        } | {
            not: {
                $ref: string;
            };
        })[];
        const?: never;
        anyOf?: never;
        not?: never;
    })[];
};
/**
 * Sort const schemas to the start of the array (mainly for aesthetic reasons)
 *
 */
export declare function sortCompareDisjuncts(...disjuncts: [
    ConjunctionSchemaObject<NonConstConjunctionSchemaObject>,
    ConjunctionSchemaObject<NonConstConjunctionSchemaObject>
]): -1 | 0 | 1;
/**
 * Removes unnecessary disjuncts (if they are subsets of other disjuncts)
 *
 */
export declare function removeSubsetDisjuncts<Disjunct_ extends JSONSchema>(disjuncts: Disjunct_[], schemaDescribesSubset: (potentialSubset: JSONSchema, potentialSuperset: JSONSchema) => boolean | null): Disjunct_[];
/**
 * Removes unnecessary conjuncts (if they are supersets of other conjuncts)
 *
 */
export declare function removeSupersetConjuncts<Conjunct_ extends JSONSchema>(conjuncts: Conjunct_[], schemaDescribesSubset: (potentialSubset: JSONSchema, potentialSuperset: JSONSchema) => boolean | null): Conjunct_[];
export type DNFFromOptions<Options_ extends Options | undefined> = DNF<BuiltInSimplificationPlugin | OptionsSimplificationPlugin<Options_>>;
/**
 * Transforms the given schema to a [disjunctive normal
 * form](https://en.wikipedia.org/wiki/Disjunctive_normal_form) similar to the
 * one utilized by {@link schemaDescribesEmptySet}.
 *
 * @returns The resulting dnf schema will be equivalent to the provided schema (meaning
 * that it will accept the same data values) but all
 * [boolean combinations](https://json-schema.org/understanding-json-schema/reference/combining)
 * will be restructured.
 *
 * Subschemas that represent property values of a JSON object or elements of a
 * JSON array do not represent boolean combinations. They are currently
 * considered atomic for that purpose.
 *
 * The resulting dnf schema will be simplified so that disjuncts that were determined
 * to be unsatisfiable are already eliminated. If each disjunct was determined
 * to be unsatisfiable the return value is `false`.
 *
 * The return type's most general form (without specified
 * {@link Options.plugins | plugin} types, for example returned by
 * `toDNF<Options>(...)`) is equivalent to:
 *
 * ```ts
 * type GeneralDNFSpelledOut =
 *   | boolean
 *   | {
 *       anyOf: (
 *         | { const: unknown }
 *         | {
 *             [mergeableKeyword: string]: unknown
 *             type: 'string' | 'number' | 'object' | 'array'
 *             allOf?: JSONSchema[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *       )[]
 *     }
 * ```
 *
 * If the provided option's type does not contain any custom
 * {@link Options.plugins | plugins}, the default return type (for example
 * returned by `toDNF(schema)` (without options)  or by
 * `toDNF<{ plugins: [] }>(...)`) is equivalent to:
 *
 * ```ts
 * type DefaultDNFSpelledOut =
 *   | boolean
 *   | {
 *       anyOf: (
 *         | { const: unknown }
 *         | {
 *             type: 'number'
 *             maximum?: number
 *             minimum?: number
 *             multipleOf?: number
 *             allOf?: (
 *               | { not: { const: number } }
 *               | { not: { multipleOf: number } }
 *               | { $ref: string }
 *               | { not: { $ref: string } }
 *             )[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *         | {
 *             type: 'string'
 *             maxLength?: number
 *             minLength?: number
 *             allOf?: (
 *               | { not: { const: string } }
 *               | { pattern: string }
 *               | { not: { pattern: string } }
 *               | { $ref: string }
 *               | { not: { $ref: string } }
 *             )[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *         | {
 *             type: 'object'
 *             maxProperties?: number
 *             minProperties?: number
 *             patternProperties?: Record<string, JSONSchema>
 *             properties?: Record<string, JSONSchema>
 *             propertyNames?: JSONSchema
 *             required?: string[]
 *             allOf?: (
 *               | { not: { const: Record<string, unknown> } }
 *               | {
 *                   additionalProperties: JSONSchema
 *                   properties?: Record<string, true>
 *                   patternProperties?: Record<string, true>
 *                 }
 *               | { not: { patternProperties: Record<string, JSONSchema> } }
 *               | {
 *                   not: {
 *                     additionalProperties: JSONSchema
 *                     properties?: Record<string, true>
 *                     patternProperties?: Record<string, true>
 *                   }
 *                 }
 *               | { not: { propertyNames: JSONSchema } }
 *               | { $ref: string }
 *               | { not: { $ref: string } }
 *             )[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *         | {
 *             type: 'array'
 *             items?: JSONSchema
 *             maxItems?: number
 *             minItems?: number
 *             prefixItems?: JSONSchema[]
 *             uniqueItems?: boolean
 *             allOf?: (
 *               | { not: { const: unknown[] } }
 *               | {
 *                   contains: JSONSchema
 *                   minContains?: number
 *                   maxContains?: number
 *                 }
 *               | {
 *                   not: { uniqueItems?: boolean }
 *                 }
 *               | {
 *                   not: {
 *                     prefixItems?: true[]
 *                     items?: JSONSchema
 *                   }
 *                 }
 *               | { $ref: string }
 *               | { not: { $ref: string } }
 *             )[]
 *             const?: never
 *             anyOf?: never
 *             not?: never
 *           }
 *       )[]
 *     }
 * ```
 *
 * The return type will adjust according to the (explicit or inferred) type of
 * the property `plugins` of the provided `options`.
 *
 * @example ```typescript
 * import { toDNF } from 'json-schema-describes-subset'
 *
 * console.log(
 *   toDNF({
 *     anyOf: [{ minimum: 2 }, { exclusiveMinimum: 1 }],
 *   }),
 * )
 * ```
 *
 * logs:
 *
 * ```json
 * {
 *   "anyOf": [
 *     { "const": null },
 *     { "const": true },
 *     { "const": false },
 *     { "type": "number", "minimum": 1, "allOf": [{ "not": { "const": 1 } }] },
 *     { "type": "string" },
 *     { "type": "array" },
 *     { "type": "object" }
 *   ]
 * }
 * ```
 *
 * ***
 *
 * ```typescript
 * import { toDNF } from 'json-schema-describes-subset'
 *
 * console.log(
 *   toDNF({
 *     anyOf: [{ multipleOf: 2 }, { multipleOf: 3 }, { multipleOf: 4 }],
 *   }),
 * )
 * ```
 *
 * logs:
 *
 * ```json
 * {
 *   "anyOf": [
 *     { "const": null },
 *     { "const": true },
 *     { "const": false },
 *     { "type": "number", "multipleOf": 2 },
 *     { "type": "number", "multipleOf": 3 },
 *     { "type": "string" },
 *     { "type": "array" },
 *     { "type": "object" }
 *   ]
 * }
 * ```
 *
 * @remarks Use cases
 *
 * This function was created mainly for demonstration purposes, but might also
 * have some real world use cases. For example when creating a data mocking
 * tool, that generates example data for a given schema, it might be easier to
 * generate that data for one of the logically flat disjuncts instead of a
 * complex schema which is logically deeply nested.
 *
 */
export declare function toDNF<const Options_ extends Options | undefined = undefined>(schema: JSONSchema, options?: Options_): DNFFromOptions<Options_>;
export declare function rawDisjunctDescribesEmptySet<SimplificationPlugin_ extends SimplificationPlugin>(rawDisjunct: ConjunctionOfLiterals, validateConst: ValidateConst, options: InternalOptions<SimplificationPlugin_>): boolean | null;
export declare function rawDNFDescribesEmptySet(rawDNF: RawDNF, validateConst: ValidateConst, options: InternalOptions): boolean | null;
/**
 * Tries to determine whether the provided JSON Schema is unsatisfiable and
 * therefore describes the empty set. In that case, the schema would be
 * equivalent to the `false` schema.
 *
 * @returns Returns `true` if it does find a reason why the schema will not accept any
 * value.
 *
 * If such a reason cannot be found, usually `null` is returned to indicate the
 * possibility of false negatives.
 *
 * The true positive `false` return value is currently only returned if an
 * example data value that satisfies the schema can be trivially found.
 * See [Limitations](https://github.com/jobohner/json-schema-describes-subset/blob/v0.4.0/src/dnf/dnf.ts#limitations) for more details.
 *
 * @example ```ts
 * import { schemaDescribesEmptySet } from 'json-schema-describes-subset'
 *
 * console.log(schemaDescribesEmptySet(false)) // logs: `true`
 *
 * console.log(
 *   schemaDescribesEmptySet(
 *     // this schema will accept anything that is not a number
 *     { minimum: 2, maximum: 1 },
 *   ),
 * ) // logs: `false`
 *
 * console.log(
 *   schemaDescribesEmptySet({
 *     type: 'number',
 *     minimum: 2,
 *     maximum: 1,
 *   }),
 * ) // logs: `true`
 * ```
 *
 * @remarks How does this work?
 *
 * The provided schema is first transformed to a [disjunctive normal
 * form](https://en.wikipedia.org/wiki/Disjunctive_normal_form) similar to the
 * one returned by {@link toDNF}. Then each disjunct is checked for
 * contradictions which would make it unsatisfiable. If a contradiction is found
 * for each disjunct, the complete schema is unsatisfiable and `true` is
 * returned.
 *
 */
export declare function schemaDescribesEmptySet(schema: JSONSchema, options?: Options | undefined): boolean | null;
export type SchemaDescribesEmptySet = typeof schemaDescribesEmptySet;
export declare function schemaDescribesEmptySetInternal(schema: JSONSchema, options: InternalOptions): boolean | null;
export type SchemaDescribesEmptySetInternal = typeof schemaDescribesEmptySetInternal;
