type TruthAssignmentsMap = Map<number, boolean[]>;

declare enum Glyph {
    Implication = "=>",// →
    ReversedImplication = "<=",// ←
    Conjunction = "&",// ∧
    Disjunction = "|",// ∨
    Negation = "~",// ¬
    Equivalence = "<=>",// ≡
    ExclusiveConjunction = "^",// ⊕ (XOR)
    ShefferStroke = "!&",// ↑ (NAND)
    WebbOperation = "!|",// ↓ (NOR)
    AntiImplication = "!=>",// ↛ (A and not B)
    ReversedAntiImplication = "!<=",// ↚ (B and not A)
    Contradiction = "#",// ⊥ (Always False)
    Tautology = "@",// ⊤ (Always True)
    OpenParenthesis = "(",
    CloseParenthesis = ")"
}

declare enum GlyphType {
    Variable = "variable",
    Operator = "operator",
    Parenthesis = "parenthesis"
}

declare enum GlyphUnicode {
    Implication = "\u2192",// →
    ReversedImplication = "\u2190",// ←
    Conjunction = "\u2227",// ∧
    Disjunction = "\u2228",// ∨
    Negation = "\u00AC",// ¬
    Equivalence = "\u2261",// ≡
    ExclusiveConjunction = "\u2295",// ⊕
    ShefferStroke = "\u2191",// ↑ (NAND)
    WebbOperation = "\u2193",// ↓ (NOR)
    AntiImplication = "\u219B",// ↛ (A and not B)
    ReversedAntiImplication = "\u219A",// ↚ (B and not A)
    Contradiction = "\u22A5",// ⊥
    Tautology = "\u22A4",// ⊤
    OpenParenthesis = "(",
    CloseParenthesis = ")"
}

declare enum Operator {
    Var = "VAR",
    Not = "NOT",
    And = "AND",
    Or = "OR",
    Implies = "IMPLIES",
    ReversedImplies = "REVERSED_IMPLIES",
    Equiv = "EQUIV",
    Xor = "XOR",
    Nand = "NAND",
    Nor = "NOR",
    AntiImplies = "ANTI_IMPLIES",
    ReversedAntiImplies = "REVERSED_ANTI_IMPLIES",
    Contradiction = "CONTRADICTION",
    Tautology = "TAUTOLOGY"
}

declare enum PropFormulaCheck {
    areEqual = "areEqual",
    isIE = "isIE",
    isDE = "isDE",
    isCE = "isCE",
    isEE = "isEE",
    isNE = "isNE",
    isDI = "isDI",
    isCI = "isCI",
    isEI = "isEI",
    isNI = "isNI",
    isII = "isII"
}

declare enum Step {
    Premise = "Premise",
    Assumption = "Assumption",
    Shortcut = "Shortcut",
    Reiteration = "Reiteration",
    Derivation = "Derivation",
    Axiom = "Axiom"
}

declare enum HilbertCalculusSchema {
    II = "II",
    ID = "ID",
    IR = "IR",
    IE = "IE"
}

declare enum NaturalCalculusRule {
    NI = "NI",
    CI = "CI",
    DI = "DI",
    II = "II",
    EI = "EI",
    NE = "NE",
    CE = "CE",
    DE = "DE",
    IE = "IE",
    EE = "EE"
}

type PropAtom = [string];
interface PropSymbol {
    atom: PropAtom;
    type: GlyphType;
    position: number;
    view: string;
}
type PropExpression = PropSymbol[];
interface PropFormula {
    operator: Operator;
    values: PropFormula[] | PropAtom;
}
type PropFormulaVariablesMap = Map<number, PropAtom>;
interface PropProofStep {
    index: number;
    step: Step;
    formula: PropFormula;
    expression: PropExpression;
    stringView: string;
    comment: string;
    derivedFrom?: number[];
    level?: number;
    assumptionIndex?: number;
}

/**
 * Performs equivalence elimination on the given formulas.
 *
 * If A <=> B, then we derive (A => B) and (B => A).
 *
 * @param formulas An array of propositional formulas.
 * @returns {PropFormula[]} An array containing the inferred formulas.
 * @throws {Error} if the formulas are not all equivalences.
 */
declare function equivalenceElimination(formulas: PropFormula[]): PropFormula[];

/**
 * Applies the rule of Implication Elimination.
 *
 * Given an implication (A => B) and its antecedent A,
 * it derives the consequent B.
 *
 * @param formulas An array of propositional formulas.
 * @returns {[PropFormula]} A tuple containing the inferred formula.
 * @throws {Error} if implication elimination is not applicable.
 */
declare function implicationElimination$1(formulas: PropFormula[]): [PropFormula];

/**
 * Applies the disjunction elimination rule:
 * Given formulas (A ∨ B), (A => C), and (B => C), we can infer C.
 *
 * @param formulas An array of propositional formulas.
 * @returns {[PropFormula]} A tuple containing the inferred formula.
 * @throws {Error} if the formulas do not satisfy disjunction elimination conditions.
 */
declare function disjunctionElimination(formulas: PropFormula[]): [PropFormula];

/**
 * Applies Conjunction Elimination rule to an array of conjunction formulas.
 *
 * Given (A ∧ B), this rule allows us to infer A and B separately.
 *
 * @param formulas An array of conjunction formulas to eliminate.
 * @returns {PropFormula[]} An array of inferred formulas after applying conjunction elimination.
 * @throws {Error} if any formula is not a conjunction.
 */
declare function conjunctionElimination(formulas: PropFormula[]): PropFormula[];

/**
 * Applies negation elimination rule:
 * If ~(~A), then we can infer ~A.
 *
 * @param formulas An array of propositional formulas.
 * @returns {[PropFormula]} A tuple containing the inferred formula.
 * @throws {Error} if negation introduction rule is not applicable.
 */
declare function negationElimination(formulas: PropFormula[]): [PropFormula];

/**
 * Introduces an equivalence (A <=> B) given two implications (A => B) and (B => A).
 *
 * @param formulas An array of propositional formulas.
 * @returns {[PropFormula]} A tuple containing the inferred formula.
 * @throws {Error} if the input formulas do not satisfy the equivalence introduction conditions.
 */
declare function equivalenceIntroduction(formulas: PropFormula[]): [PropFormula];

/**
 * Applies the implication introduction rule.
 *
 * Given two formulas premise and conclusion, it returns their implication
 *
 * @param formulas An array of propositional formulas.
 * @returns {[PropFormula]} A tuple containing the inferred formula.
 * @throws {Error} if the formulas do not satisfy disjunction introduction conditions.
 */
declare function implicationIntroduction$1(formulas: PropFormula[]): [PropFormula];

/**
 * Applies the disjunction introduction rule.
 *
 * Given two formulas A and B, it returns two disjunctions: (A ∨ B) and (B ∨ A)
 *
 * @param formulas An array of propositional formulas.
 * @returns {[PropFormula, PropFormula]} A tuple containing the two inferred formulas.
 * @throws {Error} if the formulas do not satisfy disjunction introduction conditions.
 */
declare function disjunctionIntroduction(formulas: PropFormula[]): [PropFormula, PropFormula];

/**
 * Applies the conjunction introduction rule.
 *
 * Given two formulas A and B, it returns two conjunctions: (A ∧ B) and (B ∧ A)
 *
 * @param formulas An array of propositional formulas.
 * @returns {[PropFormula, PropFormula]} A tuple containing the two inferred formulas.
 * @throws {Error} if the formulas do not satisfy conjunction introduction conditions.
 */
declare function conjunctionIntroduction(formulas: PropFormula[]): [PropFormula, PropFormula];

/**
 * Applies negation introduction rule:
 * If (A => B) and (A => ~B), then we can infer ~A.
 *
 * @param formulas - An array of propositional formulas.
 * @returns {[PropFormula]} A tuple containing the inferred formula.
 * @throws {Error} if negation introduction rule is not applicable.
 */
declare function negationIntroduction(formulas: PropFormula[]): [PropFormula];

type DerivedPayload$1 = {
    formulas: PropFormula[];
    rule: NaturalCalculusRule;
    derivedFrom: number[];
};
type BasePayload$1 = {
    formula: PropFormula;
};
interface NaturalProofStepInput<T> {
    index: number;
    level: number;
    assumptionIndex?: number;
    step: T extends Step.Derivation ? Step.Derivation : Exclude<Step, Step.Derivation | Step.Axiom>;
    payload: T extends Step.Derivation ? DerivedPayload$1 : BasePayload$1;
}
/**
 * Generates a PropProofStep object for use in Natural-style logic derivations.
 * Supports Assumption, Derivation, Premise, Reiteration and Shortcut step types. Applies appropriate
 * rule-based transformations and constructs the string and symbolic expression views.
 * @param input - An object with necessary data for the new proof step.
 * @returns An array of new proof steps based on the input.
 */
declare function generateNaturalProofSteps<T>(input: NaturalProofStepInput<T>): PropProofStep[];

/**
 * Applies the rule of Implication Elimination (Modus Ponens).
 *
 * Given an implication (A => B) and its antecedent A,
 * it derives the consequent B.
 *
 * @param formulas - An array of propositional formulas.
 * @returns The consequent of the implication if the rule is applicable.
 * @throws {Error} if implication elimination is not applicable.
 */
declare function implicationElimination(formulas: PropFormula[]): PropFormula;

/**
 * Constructs a formula based on the Implication Reversal axiom schema:
 * ((~A => ~B) => (B => A))
 *
 * @param formulas - An array of propositional formulas.
 * @returns A new propositional formula representing the implication reversal.
 */
declare function implicationReversal(formulas: PropFormula[]): PropFormula;

/**
 * Constructs a formula based on the Implication Distribution axiom schema:
 * ((A => (B => C)) => ((A => B) => (A => C)))
 *
 * @param formulas - An array of propositional formulas.
 * @returns A new propositional formula representing the axiom schema.
 */
declare function implicationDistribution(formulas: PropFormula[]): PropFormula;

/**
 * Generates a formula based on the Implication Introduction axiom schema.
 *
 * Given two formulas A and B, this function returns the formula:
 * (A => (B => A)).
 *
 * @param formulas - An array of propositional formulas.
 * @returns A new formula representing (A => (B => A)).
 */
declare function implicationIntroduction(formulas: PropFormula[]): PropFormula;

type AxiomPayload = {
    formulas: PropFormula[];
    schema: HilbertCalculusSchema;
};
type DerivedPayload = {
    formulas: PropFormula[];
    schema: HilbertCalculusSchema.IE;
    derivedFrom: number[];
};
type BasePayload = {
    formula: PropFormula;
};
interface HilbertProofStepInput<T> {
    index: number;
    step: T extends Step.Derivation ? Step.Derivation : T extends Step.Axiom ? Step.Axiom : Exclude<Step, Step.Derivation | Step.Axiom | Step.Assumption>;
    payload: T extends Step.Derivation ? DerivedPayload : T extends Step.Axiom ? AxiomPayload : BasePayload;
}
/**
 * Generates a PropProofStep object for use in Hilbert-style logic derivations.
 * Supports Axiom, Derivation, Premise, Reiteration and Shortcut step types. Applies appropriate
 * schema-based transformations and constructs the string and symbolic expression views.
 * @param input - An object with necessary data for the new proof step.
 * @returns A new proof step based on the input.
 */
declare function generateHilbertProofStep<T>(input: HilbertProofStepInput<T>): PropProofStep;

/**
 * Applies a series of propositional formula checks to an array of formulas.
 *
 * @param formulas - An array of propositional formulas to check.
 * @param checks - An array of check names to apply (defaults to all available checks).
 * @returns An object mapping each check name to its boolean result.
 */
declare function applyPropFormulaChecks(formulas: PropFormula[], checks?: PropFormulaCheck[]): Record<PropFormulaCheck, boolean>;

/**
 * Generates all possible truth assignments for a given number of variables.
 *
 * @param varCount - The number of boolean variables.
 * @param limit - The maximum allowed number of variables (default: 100).
 * @returns A map of truth assignments, indexed by binary count.
 * @throws {Error} If varCount exceeds the limit.
 */
declare function generateTruthAssignments(varCount: number, limit?: number): TruthAssignmentsMap;

/**
 * Generates a truth table for the given propositional formula.
 *
 * @param {PropFormula} formula - The propositional formula.
 * @param {number} [limit=100] - The max number of variables in the formula.
 * @returns {TruthAssignmentsMap} - A map where keys are assignments, and values are truth values.
 * @throws {Error} If the formula has more variables than the limit allows.
 */
declare function generatePropTruthTable(formula: PropFormula, limit?: number): TruthAssignmentsMap;

/**
 * Evaluates the logical value of a binary operation given two boolean operands.
 *
 * @param operator - The logical operator to apply.
 * @param leftOperand - The boolean value of the left operand.
 * @param rightOperand - The boolean value of the right operand.
 * @returns The result of applying the operator to the operands.
 * @throws {Error} If the operator is not a binary operator.
 */
declare function getBinaryOperationValue({ operator, leftOperand, rightOperand, }: {
    operator: Operator;
    leftOperand: boolean;
    rightOperand: boolean;
}): boolean;

/**
 * Computes the logical value of an unary operator applied to an operand.
 *
 * @param operator - The unary operator to evaluate.
 * @param operand - The boolean value of the operand.
 * @returns The computed boolean value after applying the unary operator.
 * @throws {Error} If an unsupported operator is provided.
 */
declare function getUnaryOperationValue({ operator, operand }: {
    operator: Operator;
    operand: boolean;
}): boolean;

/**
 * Checks whether a given propositional expression is a well-formed formula (WFF).
 *
 * A WFF follows these rules:
 * 1) Any single variable itself is a WFF.
 * 2) Any WFF can be prefixed with "~" to form another WFF.
 * 3) Any two WFFs can be combined with "&", "|", "=>", or "<=>" inside parentheses to form another WFF.
 *
 * Parentheses are mandatory when joining two WFFs using binary operators.
 *
 * @param expression - The propositional expression as an array of PropSymbols.
 * @returns `true` if the expression is a valid WFF, otherwise `false`.
 */
declare function isWellFormedFormula(expression: PropExpression): boolean;

/**
 * Extracts all true sub-formulas from a given propositional formula.
 * This function does not include atomic formulas (Operator.Var) as sub-formulas,
 * nor does it include the input formula itself.
 *
 * @param {PropFormula} formula - The propositional formula to extract sub-formulas from.
 * @returns {PropFormula[]} An array of unique sub-formulas, sorted in evaluation order.
 */
declare function extractPropSubFormulas(formula: PropFormula): PropFormula[];

/**
 * Extracts all propositional variables from a given formula and returns them in a sorted map.
 *
 * @param formula - The propositional formula.
 * @returns A map of variables, sorted alphabetically.
 */
declare function extractPropVariables(formula: PropFormula): PropFormulaVariablesMap;

declare function convertPropFormulaToExpression(formula: PropFormula): PropExpression;

/**
 * Converts a propositional formula into a string representation using Unicode logical symbols.
 *
 * @param {PropFormula} formula - The propositional formula to convert.
 * @returns {string} The string representation of the formula using Unicode glyphs.
 */
declare function convertPropFormulaToString(formula: PropFormula): string;

/**
 * Evaluates a propositional formula based on a given truth assignment.
 *
 * @param {Object} params - Function parameters.
 * @param {PropFormula} params.formula - The propositional formula in tree-like structure.
 * @param {boolean[]} params.assignment - The truth assignment for the variables.
 * @param {variablesMap} [params.variablesMap] -  The map of formula variables ordered alphabetically
 * @returns {boolean} - The boolean result of the evaluated formula.
 * @throws {Error} If the number of variables in the formula does not match the assignment length.
 */
declare function calculatePropFormula({ formula, assignment, variablesMap, }: {
    formula: PropFormula;
    assignment: boolean[];
    variablesMap?: PropFormulaVariablesMap;
}): boolean;

/**
 * Converts a given `PropSymbol` into its corresponding logical operator.
 *
 * - If the symbol represents a known logical operator glyph, returns the matching `Operator` enum.
 * - If the symbol represents a variable, returns `Operator.Var`.
 * - Throws an error if the symbol is neither a recognized operator nor a variable.
 *
 * @param symbol - The `PropSymbol` to be converted into an `Operator`.
 * @returns The corresponding `Operator` enum value.
 * @throws {Error} If the symbol is not recognized as an operator or a variable.
 */
declare function createOperator(symbol: PropSymbol): Operator;

/**
 * Creates a `PropSymbol` representing a propositional logic symbol.
 *
 * - If the character is a parenthesis, it is classified as `GlyphType.Parenthesis`.
 * - If the character is a known logical glyph, it is classified as `GlyphType.Operator`.
 * - If the character is a Latin letter, it is classified as `GlyphType.Variable`, and its view is the lowercase letter.
 * - Throws an error if the character is unrecognized.
 *
 * @param char - A single character representing a logical symbol.
 * @param position - The position of the symbol in the input expression.
 * @returns A `PropSymbol` containing the atom, type, position, and view.
 * @throws {Error} If the character is not a recognized logical symbol or a Latin letter.
 */
declare function createPropSymbol(char: string, position: number): PropSymbol;

/**
 * Converts a well-formed propositional expression into a tree-like PropFormula.
 *
 * @param expression - A validated propositional expression.
 * @returns The corresponding PropFormula.
 * @throws {Error} If the expression is not a well-formed formula.
 */
declare function createPropFormula(expression: PropExpression): PropFormula;

/**
 * Converts a logical expression string into an array of PropSymbols.
 *
 * - Uses `tokenizeString` to split the input string into tokens.
 * - Uses `createPropositionalSymbol` to convert tokens into `PropSymbol` objects.
 * - Assigns an index-based position to each symbol.
 *
 * @param input - The logical expression as a string.
 * @returns An array of `PropSymbol` objects representing the parsed expression.
 * @throws {Error}  If the input contains invalid characters.
 */
declare function createPropExpression(input: string): PropSymbol[];

/**
 * Tokenizes an input string into an array of known logical glyphs and variable names.
 *
 * - Recognizes logical glyphs defined in `Glyph`.
 * - Groups consecutive English letters into variables.
 * - Ignores spaces in the input.
 * - Throws an error if the input contains unsupported characters.
 *
 * @param input - The logical expression as a string.
 * @returns An array of tokens (glyphs and variables).
 * @throws {Error} If the input contains unsupported characters.
 */
declare function tokenizeString(input: string): string[];

/**
 * Converts a given Operator into its corresponding Glyph.
 *
 * @param {Operator} operator - The logical operator to convert.
 * @returns {Glyph} - The corresponding glyph.
 * @throws {Error} If the operator is not recognized.
 */
declare function getOperatorGlyph(operator: Operator): Glyph;

/**
 * Converts a given logical glyph character into its corresponding Unicode representation.
 *
 * @param char - A string representing a logical glyph (e.g., '=>', '&', '|', '~', etc.).
 * @returns The corresponding Unicode character from the `GlyphUnicode` enum.
 * @throws {Error} If the character is not a recognized `Glyph`.
 */
declare function getGlyphUnicode(char: string): GlyphUnicode;

declare const ChopLogicCore: Readonly<{
    Tokenizer: Readonly<{
        getGlyphUnicode: typeof getGlyphUnicode;
        getOperatorGlyph: typeof getOperatorGlyph;
        tokenizeString: typeof tokenizeString;
    }>;
    PropositionalFactory: Readonly<{
        createExpression: typeof createPropExpression;
        createFormula: typeof createPropFormula;
        createSymbol: typeof createPropSymbol;
        createOperator: typeof createOperator;
    }>;
    PropositionalUtils: Readonly<{
        calculateFormula: typeof calculatePropFormula;
        convertToString: typeof convertPropFormulaToString;
        convertToExpression: typeof convertPropFormulaToExpression;
        getVariables: typeof extractPropVariables;
        getSubFormulas: typeof extractPropSubFormulas;
        isWFF: typeof isWellFormedFormula;
        getUnaryValue: typeof getUnaryOperationValue;
        getBinaryValue: typeof getBinaryOperationValue;
        generateTT: typeof generatePropTruthTable;
        generateAssignments: typeof generateTruthAssignments;
        applyChecks: typeof applyPropFormulaChecks;
    }>;
    HilbertCalculus: Readonly<{
        generateStep: typeof generateHilbertProofStep;
        II: typeof implicationIntroduction;
        ID: typeof implicationDistribution;
        IR: typeof implicationReversal;
        IE: typeof implicationElimination;
    }>;
    NaturalCalculus: Readonly<{
        generateSteps: typeof generateNaturalProofSteps;
        NI: typeof negationIntroduction;
        CI: typeof conjunctionIntroduction;
        DI: typeof disjunctionIntroduction;
        II: typeof implicationIntroduction$1;
        EI: typeof equivalenceIntroduction;
        NE: typeof negationElimination;
        CE: typeof conjunctionElimination;
        DE: typeof disjunctionElimination;
        IE: typeof implicationElimination$1;
        EE: typeof equivalenceElimination;
    }>;
}>;

export { ChopLogicCore };
