Source code for donuts.var

"""Routines for variables."""

from __future__ import annotations

import functools
from typing import TYPE_CHECKING, Any, Union, overload

from .jvm import jvm

if TYPE_CHECKING:
    from .poly import Polynomial
    from .rat import RationalFunction

_RawVariable = jvm.find_class("com.github.tueda.donuts.Variable")
_JavaError = jvm.java_error_class


@functools.lru_cache(maxsize=1024)
def _raw_variable_from_str(name: str) -> Any:
    return _RawVariable(name)


[docs]class Variable: """Variable.""" __slots__ = ("_name", "_raw") __NONE = "[__PRIVATE_NONE__]" @overload def __init__(self, name: str) -> None: """Construct a variable.""" ... @overload def __init__(self, variable: Variable) -> None: """Construct a variable.""" ... def __init__(self, variable: Union[Variable, str]) -> None: # type: ignore[misc] """Construct a variable.""" if variable == Variable.__NONE: # Called from `_new`. return if isinstance(variable, Variable): self._name: str = variable._name self._raw: Any = variable._raw return if not isinstance(variable, str): raise TypeError(f"invalid argument for variable: `{variable}`") try: self._raw = _raw_variable_from_str(variable) except _JavaError as e: raise ValueError(f"invalid string for variable: `{variable}'") from e self._name = variable @staticmethod def _new(raw: Any) -> Variable: """Construct a variable from a raw object.""" obj = Variable(Variable.__NONE) obj._raw = raw obj._name = str(raw.getName()) return obj def __getstate__(self) -> Any: """Get the object state.""" return self._name def __setstate__(self, state: Any) -> None: """Set the object state.""" self._name = state self._raw = _raw_variable_from_str(state) def __str__(self) -> str: """Return the string representation.""" return self._name def __repr__(self) -> str: """Return the "official" string representation.""" return f"Variable('{self._name}')" def __hash__(self) -> int: """Return the hash code.""" return hash(self._name) def __pos__(self) -> Polynomial: """Return ``+ self``.""" from .poly import Polynomial return Polynomial(self) def __neg__(self) -> Polynomial: """Return ``- self``.""" from .poly import Polynomial return -Polynomial(self) def __add__(self, other: Union[Variable, int]) -> Polynomial: """Return ``self + other``.""" from .poly import Polynomial if isinstance(other, (Variable, int)): return Polynomial(self) + Polynomial(other) return NotImplemented # type: ignore[unreachable] def __radd__(self, other: int) -> Polynomial: """Return ``other + self.""" from .poly import Polynomial if isinstance(other, int): return Polynomial(other) + Polynomial(self) return NotImplemented # type: ignore[unreachable] def __sub__(self, other: Union[Variable, int]) -> Polynomial: """Return ``self - other``.""" from .poly import Polynomial if isinstance(other, (Variable, int)): return Polynomial(self) - Polynomial(other) return NotImplemented # type: ignore[unreachable] def __rsub__(self, other: int) -> Polynomial: """Return ``other - self.""" from .poly import Polynomial if isinstance(other, int): return Polynomial(other) - Polynomial(self) return NotImplemented # type: ignore[unreachable] def __mul__(self, other: Union[Variable, int]) -> Polynomial: """Return ``self * other``.""" from .poly import Polynomial if isinstance(other, (Variable, int)): return Polynomial(self) * Polynomial(other) return NotImplemented # type: ignore[unreachable] def __rmul__(self, other: int) -> Polynomial: """Return ``other * self.""" from .poly import Polynomial if isinstance(other, int): return Polynomial(other) * Polynomial(self) return NotImplemented # type: ignore[unreachable] def __truediv__(self, other: Union[Variable, int]) -> RationalFunction: """Return ``self / other``.""" from .rat import RationalFunction if isinstance(other, (Variable, int)): return RationalFunction(self, other) return NotImplemented # type: ignore[unreachable] def __rtruediv__(self, other: int) -> RationalFunction: """Return ``other / self``.""" from .rat import RationalFunction if isinstance(other, int): return RationalFunction(other, self) return NotImplemented # type: ignore[unreachable] def __pow__(self, other: int) -> Polynomial: """Return ``self ** other``.""" from .poly import Polynomial if isinstance(other, int): return Polynomial(self) ** other return NotImplemented # type: ignore[unreachable] def __eq__(self, other: object) -> bool: """Return ``self == other``.""" if isinstance(other, Variable): return self._name == other._name return NotImplemented def __le__(self, other: object) -> bool: """Return `self <= other`.""" if isinstance(other, Variable): return self._raw.compareTo(other._raw) <= 0 # type: ignore[no-any-return] return NotImplemented def __lt__(self, other: object) -> bool: """Return `self < other`.""" if isinstance(other, Variable): return self._raw.compareTo(other._raw) < 0 # type: ignore[no-any-return] return NotImplemented
# For static typing. VariableLike = Union[Variable, str]