import type { JSONSchema } from '../json-schema/index.js';
import type { Options } from '../options/index.js';
/**
 * Tries to determine whether the first argument JSON schema
 * (`potentialSubsetSchema`) describes a subset of the set of data values
 * described by the second argument JSON schema (`potentialSupersetSchema`).
 *
 * @returns Returns `true` if it does find a reason to do so.
 *
 * If such a reason cannot be found, usually `null` is returned to indicate
 * the possibility of false negatives. (Not having found any reason to return
 * `true` doesn't mean that there aren't any.)
 *
 * This behavior is sufficient for many use cases and has been the focus so far.
 * The ability to determine true positive `true` results is fairly powerful and
 * will work in many complex cases. (See the following [examples](https://github.com/jobohner/json-schema-describes-subset/blob/v0.4.0/src/schema-describes-subset/schema-describes-subset.ts#example) and
 * [Limitations](https://github.com/jobohner/json-schema-describes-subset/blob/v0.4.0/docs/README.md#limitations).)
 * The true positive `false` return value is currently only returned if an
 * example data value that satisfies `potentialSubsetSchema` but not
 * `potentialSupersetSchema` can be trivially found.
 * See [Limitations](https://github.com/jobohner/json-schema-describes-subset/blob/v0.4.0/docs/README.md#limitations) for more details.
 *
 * @example If a few of the following examples that return `true` seem unintuitive
 * at first glance, try to find a data value that satisfies the first schema but
 * not the second one. Failing to find such a data value might help to
 * understand why `true` is returned. (If, contrary to expectations, you
 * actually are able to find such a data value, please do report a
 * [bug](https://github.com/jobohner/json-schema-describes-subset/issues)).
 *
 * ```ts
 * import { schemaDescribesSubset } from 'json-schema-describes-subset'
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       type: 'number',
 *     },
 *     true,
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(false, {
 *     type: 'number',
 *   }),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       type: ['number', 'boolean', 'string', 'null'],
 *     },
 *     { type: ['number', 'null'] },
 *   ),
 * ) // logs: `false`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     { type: 'integer' },
 *     { type: ['number', 'string', 'boolean'] },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       minimum: 5.5,
 *     },
 *     {
 *       exclusiveMinimum: 5.5,
 *     },
 *   ),
 * ) // logs: `false`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       minimum: 5.6,
 *     },
 *     {
 *       exclusiveMinimum: 5.5,
 *     },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     { minimum: 10, maximum: 30, multipleOf: 5 },
 *     { anyOf: [{ multipleOf: 3 }, { multipleOf: 20 }, { enum: [10, 25] }] },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     { type: 'string', maxLength: 5, minLength: 10 },
 *     { type: 'null' },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       prefixItems: [{ type: 'string' }, { type: 'boolean' }],
 *       items: { type: 'object' },
 *     },
 *     {
 *       prefixItems: [
 *         { type: ['string', 'number'] },
 *         { type: 'boolean' },
 *         { type: 'object' },
 *       ],
 *     },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     { contains: { type: 'number' }, minContains: 5 },
 *     { minItems: 5 },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       prefixItems: [{ type: 'number' }, { type: 'boolean' }],
 *       items: { type: 'string' },
 *       maxItems: 3,
 *     },
 *     { uniqueItems: true },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     { required: ['a'], maxProperties: 2 },
 *     {
 *       anyOf: [
 *         { properties: { b: { type: 'string' } } },
 *         { properties: { c: { type: 'string' } } },
 *       ],
 *     },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     { maxProperties: 2, required: ['abc', 'def'] },
 *     { propertyNames: { minLength: 2 } },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     { maxProperties: 1 },
 *     {
 *       anyOf: [
 *         { properties: { x: { type: 'string' } } },
 *         { patternProperties: { '^a$': { type: 'string' } } },
 *       ],
 *     },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       additionalProperties: { type: 'number' },
 *       properties: { a: { type: 'string' } },
 *     },
 *     {
 *       additionalProperties: { type: 'number' },
 *       properties: {
 *         a: { type: 'string' },
 *         b: { type: ['boolean', 'number'] },
 *       },
 *     },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       allOf: [
 *         {
 *           properties: {
 *             aa: { type: 'string' },
 *             aaa: { type: 'string' },
 *             aaaa: { type: 'string' },
 *           },
 *           patternProperties: {
 *             '^b+$': { type: 'string' },
 *           },
 *         },
 *         {
 *           additionalProperties: { type: 'number' },
 *           patternProperties: {
 *             '^a+$': { type: 'string' },
 *             '^b+$': true,
 *           },
 *         },
 *         {
 *           propertyNames: { not: { pattern: '^b+$' } },
 *         },
 *       ],
 *     },
 *     {
 *       additionalProperties: { type: 'number' },
 *       patternProperties: {
 *         '^a+$': { type: 'string' },
 *       },
 *     },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       patternProperties: {
 *         '^a+$': { type: 'string' },
 *         '^b+$': { type: 'boolean' },
 *       },
 *       propertyNames: { pattern: '^a+$' },
 *     },
 *     {
 *       additionalProperties: false,
 *       patternProperties: { '^a+$': { type: 'string' } },
 *     },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     { required: ['a', 'b', 'c'] },
 *     { dependentRequired: { a: ['b', 'c'] } },
 *   ),
 * ) // logs: `true`
 *
 * console.log(
 *   schemaDescribesSubset(
 *     {
 *       properties: {
 *         b: { type: 'number' },
 *       },
 *       additionalProperties: false,
 *     },
 *     {
 *       properties: {
 *         b: { type: ['string', 'number'] },
 *       },
 *       dependentSchemas: {
 *         a: {
 *           properties: {
 *             b: {
 *               type: 'string',
 *             },
 *           },
 *         },
 *       },
 *     },
 *   ),
 * ) // logs: `true`
 * ```
 *
 * @remarks Use Cases
 *
 * This function is useful whenever you want to ensure that different data
 * interfaces are compatible with each other.
 *
 * For example, it can be used to check whether a new API version is backwards
 * compatible with the old one.
 *
 * Several other good use cases where a function like
 * `schemaDescribesSubset` might come in handy, are described in the
 * introduction of the paper
 * [Type Safety with JSON Subschema](https://arxiv.org/abs/2106.05271), which
 * follows the same goal as this function using a slightly different approach.
 *
 * ### How does this work?
 *
 * The implementation utilizes {@link schemaDescribesEmptySet} and the fact that
 * A ⊆ B if and only if A ∩ ¬B = ∅. (That
 * relation should be obvious if illustrated in a venn diagram.)
 *
 * It basically looks similar to this:
 *
 * ```typescript
 * function schemaDescribesSubset(
 *   potentialSubsetSchema: JSONSchema,
 *   potentialSupersetSchema: JSONSchema,
 * ): boolean | null {
 *   return schemaDescribesEmptySet({
 *     allOf: [
 *       potentialSubsetSchema,
 *       { not: potentialSupersetSchema },
 *     ],
 *   })
 * }
 * ```
 *
 * ### Good to know: Validation using `schemaDescribesSubset`
 *
 * `schemaDescribesSubset` uses
 * [Ajv](https://ajv.js.org/json-schema.html#draft-2020-12) to validate `consts`
 * among others. It can be configured using {@link ValidationPlugin}s. If you
 * ever need a routine that validates a value `a` against a schema `B` and that
 * is equally configured, an alternative to importing and configuring Ajv would
 * be to use:
 *
 * ```typescript
 * schemaDescribesSubset({const: a}, B)
 * ```
 *
 * This is one of the cases where
 * [a definite boolean is always returned and never `null`](https://github.com/jobohner/json-schema-describes-subset/blob/v0.4.0/docs/README.md#limitations).
 *
 * However, since this is not optimized for performance, configuring and using a
 * validator might often be the better choice.
 *
 */
export declare function schemaDescribesSubset(potentialSubsetSchema: JSONSchema, potentialSupersetSchema: JSONSchema, options?: Options | undefined): boolean | null;
export type SchemaDescribesSubset = typeof schemaDescribesSubset;
