from typing import Any
from typing_extensions import LiteralString, Self

from sympy.core.basic import Basic
from sympy.core.expr import Expr
from sympy.matrices import Matrix

class _QuantityMapper:
    _quantity_scale_factors_global: dict[Expr, Expr] = ...
    _quantity_dimensional_equivalence_map_global: dict[Expr, Expr] = ...
    _quantity_dimension_global: dict[Expr, Expr] = ...
    def __init__(self, *args, **kwargs) -> None: ...
    def set_quantity_dimension(self, quantity, dimension) -> None: ...
    def set_quantity_scale_factor(self, quantity, scale_factor) -> None: ...
    def get_quantity_dimension(self, unit) -> Expr | Dimension: ...
    def get_quantity_scale_factor(self, unit): ...

class Dimension(Expr):
    _op_priority = ...
    _dimensional_dependencies = ...
    is_commutative = ...
    is_number = ...
    is_positive = ...
    is_real = ...
    def __new__(cls, name, symbol=...) -> Self: ...
    @property
    def name(self): ...
    @property
    def symbol(self): ...
    def __repr__(self) -> LiteralString: ...
    def __neg__(self) -> Self: ...
    def __add__(self, other) -> Self: ...
    def __radd__(self, other) -> Self: ...
    def __sub__(self, other): ...
    def __rsub__(self, other): ...
    def __pow__(self, other) -> Dimension: ...
    def __mul__(self, other) -> Dimension | Self: ...
    def __rmul__(self, other) -> Dimension | Self: ...
    def __truediv__(self, other) -> Dimension | Self: ...
    def __rtruediv__(self, other): ...
    def has_integer_powers(self, dim_sys) -> bool: ...

class DimensionSystem(Basic, _QuantityMapper):
    def __new__(cls, base_dims, derived_dims=..., dimensional_dependencies=...) -> Self: ...
    @property
    def base_dims(self) -> Basic: ...
    @property
    def derived_dims(self) -> Basic: ...
    @property
    def dimensional_dependencies(self) -> Basic: ...
    def get_dimensional_dependencies(self, name, mark_dimensionless=...) -> dict[Dimension, int] | dict[Any, int | Any]: ...
    def equivalent_dims(self, dim1, dim2) -> bool: ...
    def extend(self, new_base_dims, new_derived_dims=..., new_dim_deps=...) -> DimensionSystem: ...
    def is_dimensionless(self, dimension) -> bool: ...
    @property
    def list_can_dims(self) -> tuple[Any, ...]: ...
    @property
    def inv_can_transf_matrix(self): ...
    @property
    def can_transf_matrix(self): ...
    def dim_can_vector(self, dim) -> Matrix: ...
    def dim_vector(self, dim): ...
    def print_dim_base(self, dim): ...
    @property
    def dim(self) -> int: ...
    @property
    def is_consistent(self): ...
