from collections.abc import Generator
from typing import Any, Literal
from typing_extensions import Self

from sympy.core.basic import Basic
from sympy.core.cache import cacheit
from sympy.core.decorators import sympify_method_args, sympify_return
from sympy.core.function import Application, Derivative
from sympy.core.operations import LatticeOp
from sympy.core.relational import Eq, Ne
from sympy.core.singleton import Singleton
from sympy.core.symbol import Symbol

def as_Boolean(e) -> BooleanTrue | BooleanFalse | Symbol | Boolean: ...
@sympify_method_args
class Boolean(Basic):
    __slots__ = ...
    kind = ...
    @sympify_return([("other", "Boolean")], NotImplemented)
    def __and__(self, other) -> And: ...

    __rand__ = ...
    @sympify_return([("other", "Boolean")], NotImplemented)
    def __or__(self, other) -> Or: ...

    __ror__ = ...
    def __invert__(self) -> Not: ...
    @sympify_return([("other", "Boolean")], NotImplemented)
    def __rshift__(self, other) -> Implies: ...
    @sympify_return([("other", "Boolean")], NotImplemented)
    def __lshift__(self, other) -> Implies: ...

    __rrshift__ = ...
    __rlshift__ = ...
    @sympify_return([("other", "Boolean")], NotImplemented)
    def __xor__(self, other) -> BooleanFalse | Not | Xor: ...

    __rxor__ = ...
    def equals(self, other) -> bool: ...
    def to_nnf(self, simplify=...) -> Self: ...
    def as_set(self): ...
    @property
    def binary_symbols(self) -> set[Any | Basic]: ...

class BooleanAtom(Boolean):
    is_Boolean = ...
    is_Atom = ...
    _op_priority = ...
    def simplify(self, *a, **kw) -> Self: ...
    def expand(self, *a, **kw) -> Self: ...
    @property
    def canonical(self) -> Self: ...

    __add__ = ...
    __radd__ = ...
    __sub__ = ...
    __rsub__ = ...
    __mul__ = ...
    __rmul__ = ...
    __pow__ = ...
    __rpow__ = ...
    __truediv__ = ...
    __rtruediv__ = ...
    __mod__ = ...
    __rmod__ = ...
    _eval_power = ...
    def __lt__(self, other) -> bool: ...

    __le__ = ...
    __gt__ = ...
    __ge__ = ...

class BooleanTrue(BooleanAtom, metaclass=Singleton):
    def __bool__(self) -> Literal[True]: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other) -> bool: ...
    @property
    def negated(self) -> BooleanFalse: ...
    def as_set(self): ...

class BooleanFalse(BooleanAtom, metaclass=Singleton):
    def __bool__(self) -> Literal[False]: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other) -> bool: ...
    @property
    def negated(self) -> BooleanTrue: ...
    def as_set(self): ...

true = ...
false = ...

class BooleanFunction(Application, Boolean):
    is_Boolean = ...
    def simplify(self, **kwargs): ...
    def __lt__(self, other) -> bool: ...

    __le__ = ...
    __ge__ = ...
    __gt__ = ...
    @classmethod
    def binary_check_and_simplify(cls, *args) -> list[Any | BooleanTrue | Basic | BooleanFalse | Symbol | Boolean]: ...
    def to_nnf(self, simplify=...) -> Self: ...
    def to_anf(self, deep=...) -> Self: ...
    def diff(self, *symbols, **assumptions) -> Derivative: ...

class And(LatticeOp, BooleanFunction):
    zero = ...
    identity = ...
    nargs = ...
    def to_anf(self, deep=...) -> Self: ...

class Or(LatticeOp, BooleanFunction):
    zero = ...
    identity = ...
    def to_anf(self, deep=...) -> BooleanFalse | Not | Xor: ...

class Not(BooleanFunction):
    is_Not = ...
    @classmethod
    def eval(cls, arg) -> BooleanFalse | BooleanTrue | None: ...
    def to_nnf(self, simplify=...) -> Self | Or | And: ...
    def to_anf(self, deep=...) -> Xor: ...

class Xor(BooleanFunction):
    def __new__(cls, *args, remove_true=..., **kwargs) -> BooleanFalse | Not | Self: ...
    @property
    @cacheit
    def args(self) -> tuple[Any, ...]: ...
    def to_nnf(self, simplify=...) -> And: ...

class Nand(BooleanFunction):
    @classmethod
    def eval(cls, *args) -> Not: ...

class Nor(BooleanFunction):
    @classmethod
    def eval(cls, *args) -> Not: ...

class Xnor(BooleanFunction):
    @classmethod
    def eval(cls, *args) -> Not: ...

class Implies(BooleanFunction):
    @classmethod
    def eval(cls, *args) -> Or | BooleanTrue | Self | None: ...
    def to_nnf(self, simplify=...) -> Or: ...
    def to_anf(self, deep=...) -> Xor: ...

class Equivalent(BooleanFunction):
    def __new__(cls, *args, **options) -> BooleanFalse | BooleanTrue | And | Self: ...
    @property
    @cacheit
    def args(self) -> tuple[Any, ...]: ...
    def to_nnf(self, simplify=...) -> And: ...
    def to_anf(self, deep=...) -> Xor: ...

class ITE(BooleanFunction):
    def __new__(cls, *args, **kwargs) -> Self | Not | Basic | Ne | Eq: ...
    @classmethod
    def eval(cls, *args) -> Not | Basic | Ne | Eq | Self | None: ...
    def to_nnf(self, simplify=...) -> And: ...

class Exclusive(BooleanFunction):
    @classmethod
    def eval(cls, *args) -> And: ...

def conjuncts(expr) -> frozenset[Any]: ...
def disjuncts(expr) -> frozenset[Any]: ...
def distribute_and_over_or(expr): ...
def distribute_or_over_and(expr): ...
def distribute_xor_over_and(expr): ...
def to_anf(expr, deep=...): ...
def to_nnf(expr, simplify=...): ...
def to_cnf(expr, simplify=..., force=...) -> BooleanFunction: ...
def to_dnf(expr, simplify=..., force=...) -> BooleanFunction: ...
def is_anf(expr) -> bool: ...
def is_nnf(expr, simplified=...) -> bool: ...
def is_cnf(expr) -> bool: ...
def is_dnf(expr) -> bool: ...
def eliminate_implications(expr): ...
def is_literal(expr) -> bool: ...
def to_int_repr(clauses, symbols) -> list[set[Any]]: ...
def term_to_integer(term) -> int: ...

integer_to_term = ...

def truth_table(
    expr, variables, input=...
) -> Generator[tuple[list[Literal[0, 1]], Any | BooleanFunction] | Any | BooleanFunction, Any, None]: ...
def SOPform(variables, minterms, dontcares=...) -> BooleanFalse | Or: ...
def POSform(variables, minterms, dontcares=...) -> BooleanFalse | And: ...
def ANFform(variables, truthvalues) -> BooleanFalse | Not | Xor: ...
def anf_coeffs(truthvalues) -> list[Any]: ...
def bool_minterm(k, variables) -> And: ...
def bool_maxterm(k, variables) -> Or: ...
def bool_monomial(k, variables) -> BooleanTrue | And: ...
def simplify_logic(expr, form=..., deep=..., force=..., dontcare=...): ...
def bool_map(bool1, bool2) -> tuple[Any, dict[Any, Any]] | dict[Any, Any] | Literal[False] | None: ...
def simplify_univariate(expr) -> BooleanFunction | BooleanFalse | Or: ...

BooleanGates = ...

def gateinputcount(expr) -> int: ...
