diff --git a/src/flint/flint_base/flint_base.pyi b/src/flint/flint_base/flint_base.pyi index 0aea4f6e..760baa41 100644 --- a/src/flint/flint_base/flint_base.pyi +++ b/src/flint/flint_base/flint_base.pyi @@ -58,25 +58,22 @@ class flint_poly(flint_elem, Generic[Telem]): def length(self) -> int: ... def degree(self) -> int: ... def coeffs(self) -> list[Telem]: ... - @overload def __call__(self, other: Telem | int, /) -> Telem: ... - @overload - def __call__(self, other: Self, /) -> Self: ... def __pos__(self) -> Self: ... def __neg__(self) -> Self: ... - def __add__(self, other: Telem | int | Self, /) -> Self: ... + def __add__(self, other: Telem | int, /) -> Self: ... def __radd__(self, other: Telem | int, /) -> Self: ... - def __sub__(self, other: Telem | int | Self, /) -> Self: ... + def __sub__(self, other: Telem | int, /) -> Self: ... def __rsub__(self, other: Telem | int, /) -> Self: ... - def __mul__(self, other: Telem | int | Self, /) -> Self: ... + def __mul__(self, other: Telem | int, /) -> Self: ... def __rmul__(self, other: Telem | int, /) -> Self: ... - def __truediv__(self, other: Telem | int | Self, /) -> Self: ... + def __truediv__(self, other: Telem | int, /) -> Self: ... def __rtruediv__(self, other: Telem | int, /) -> Self: ... - def __floordiv__(self, other: Telem | int | Self, /) -> Self: ... + def __floordiv__(self, other: Telem | int, /) -> Self: ... def __rfloordiv__(self, other: Telem | int, /) -> Self: ... - def __mod__(self, other: Telem | int | Self, /) -> Self: ... + def __mod__(self, other: Telem | int, /) -> Self: ... def __rmod__(self, other: Telem | int, /) -> Self: ... - def __divmod__(self, other: Telem | int | Self, /) -> tuple[Self, Self]: ... + def __divmod__(self, other: Telem | int, /) -> tuple[Self, Self]: ... def __rdivmod__(self, other: Telem | int, /) -> tuple[Self, Self]: ... def __pow__(self, other: int, /) -> Self: ... def is_zero(self) -> bool: ... @@ -130,20 +127,20 @@ class flint_mpoly(flint_elem, Generic[Tctx, Telem, Telem_coerce]): def coeffs(self) -> list[Telem]: ... def __pos__(self) -> Self: ... def __neg__(self) -> Self: ... - def __add__(self, other: Self | Telem | Telem_coerce | int) -> Self: ... + def __add__(self, other: Telem | Telem_coerce | int) -> Self: ... def __radd__(self, other: Telem | Telem_coerce | int) -> Self: ... - def __sub__(self, other: Self | Telem | Telem_coerce | int) -> Self: ... + def __sub__(self, other: Telem | Telem_coerce | int) -> Self: ... def __rsub__(self, other: Telem | Telem_coerce | int) -> Self: ... - def __mul__(self, other: Self | Telem | Telem_coerce | int) -> Self: ... + def __mul__(self, other: Telem | Telem_coerce | int) -> Self: ... def __rmul__(self, other: Telem | Telem_coerce | int) -> Self: ... - def __truediv__(self, other: Self | Telem | Telem_coerce | int) -> Self: ... + def __truediv__(self, other: Telem | Telem_coerce | int) -> Self: ... def __rtruediv__(self, other: Telem | Telem_coerce | int) -> Self: ... - def __floordiv__(self, other: Self | Telem | Telem_coerce | int) -> Self: ... + def __floordiv__(self, other: Telem | Telem_coerce | int) -> Self: ... def __rfloordiv__(self, other: Telem | Telem_coerce | int) -> Self: ... - def __mod__(self, other: Self | Telem | Telem_coerce | int) -> Self: ... + def __mod__(self, other: Telem | Telem_coerce | int) -> Self: ... def __rmod__(self, other: Telem | Telem_coerce | int) -> Self: ... def __divmod__( - self, other: Self | Telem | Telem_coerce | int + self, other: Telem | Telem_coerce | int ) -> tuple[Self, Self]: ... def __rdivmod__(self, other: Telem | Telem_coerce | int) -> tuple[Self, Self]: ... def __pow__(self, other: Telem | Telem_coerce | int) -> Self: ... @@ -151,12 +148,10 @@ class flint_mpoly(flint_elem, Generic[Tctx, Telem, Telem_coerce]): def iadd(self, other: Telem | Telem_coerce | int) -> None: ... def isub(self, other: Telem | Telem_coerce | int) -> None: ... def imul(self, other: Telem | Telem_coerce | int) -> None: ... - def gcd(self, other: Self) -> Self: ... def term_content(self) -> Self: ... def factor(self) -> tuple[Telem, Sequence[tuple[Self, int]]]: ... def factor_squarefree(self) -> tuple[Telem, Sequence[tuple[Self, int]]]: ... def sqrt(self) -> Self: ... - def resultant(self, other: Self, var: _str | int) -> Self: ... def discriminant(self, var: _str | int) -> Self: ... def deflation_index(self) -> tuple[list[int], list[int]]: ... def deflation(self) -> tuple[Self, list[int]]: ... @@ -164,7 +159,6 @@ class flint_mpoly(flint_elem, Generic[Tctx, Telem, Telem_coerce]): def inflate(self, N: list[int]) -> Self: ... def deflate(self, N: list[int]) -> Self: ... def subs(self, mapping: dict[_str | int, Telem | Telem_coerce | int]) -> Self: ... - def compose(self, *args: Self, ctx: Tctx | None = None) -> Self: ... def __call__(self, *args: Telem | Telem_coerce) -> Telem: ... def derivative(self, var: _str | int) -> Self: ... def unused_gens(self) -> tuple[_str, ...]: ... @@ -193,14 +187,14 @@ class flint_mpoly_context(flint_elem, Generic[Tmpoly, Telem, Telem_coerce]): @classmethod def from_context( cls, - ctx: Sctx, + ctx: flint_mpoly_context, names: str | Iterable[str | tuple[str, int]] | tuple[str, int] | None = None, ordering: Ordering | str = Ordering.lex, - ) -> Sctx: ... + ) -> Self: ... class flint_mod_mpoly_context(flint_mpoly_context[Tmpoly, Telem, Telem_coerce]): @abstractmethod - def modulus(self) -> int: ... + def modulus(self): ... class flint_series(flint_elem, Generic[Telem]): """Base class for power series.""" diff --git a/src/flint/test/test_all.py b/src/flint/test/test_all.py index 8325b8ab..06ee65f6 100644 --- a/src/flint/test/test_all.py +++ b/src/flint/test/test_all.py @@ -32,7 +32,9 @@ def raises(f, exception) -> bool: Tscalar = TypeVar('Tscalar', bound=flint_base.flint_scalar) Tscalar_co = TypeVar('Tscalar_co', bound=flint_base.flint_scalar, covariant=True) Tmpoly = TypeVar('Tmpoly', bound=flint_base.flint_mpoly) +Tmpoly_p = TypeVar('Tmpoly_p', bound=typ.mpoly_p) Tmpolyctx_co = TypeVar('Tmpolyctx_co', bound=flint_base.flint_mpoly_context, covariant=True) +Tmpolyctx_p_co = TypeVar('Tmpolyctx_p_co', bound=typ.mpoly_context_p, covariant=True) _default_ctx_string = """\ @@ -2620,7 +2622,7 @@ def _all_polys() -> list[tuple[Any, Any, bool, flint.fmpz]]: Tpoly = TypeVar("Tpoly", bound=typ.epoly_p) -Tc = TypeVar("Tc", bound=flint_base.flint_scalar) +Tc = TypeVar("Tc", bound=typ.scalar_p) TS = Callable[[Tc | int], Tc] TP = Callable[[Tpoly | Sequence[Tc | int] | Tc | int], Tpoly] _PolyTestCase = tuple[TP[Tpoly,Tc], TS[Tc], bool, flint.fmpz] @@ -3093,17 +3095,17 @@ def _all_mpolys(): # -> _all_mpolys_type: ) -class _GetMPolyCtx(Protocol[Tmpolyctx_co]): +class _GetMPolyCtx(Protocol[Tmpolyctx_p_co]): def __call__(self, names: Iterable[str | tuple[str, int]] | tuple[str, int], ordering: str | flint.Ordering = "lex" - ) -> Tmpolyctx_co: + ) -> Tmpolyctx_p_co: ... _MPolyTestCase = tuple[ - type[Tmpoly], - _GetMPolyCtx['flint_base.flint_mpoly_context[Tmpoly, Tscalar, int]'], + type[Tmpoly_p], + _GetMPolyCtx[typ.mpoly_context_p[Tmpoly_p, Tscalar]], Callable[[int], Tscalar], bool, flint.fmpz @@ -3176,7 +3178,7 @@ def wrapper(): @all_mpolys -def test_mpolys_constructor(args: _MPolyTestCase[Tmpoly, Tscalar]) -> None: +def test_mpolys_constructor(args: _MPolyTestCase[Tmpoly_p, Tscalar]) -> None: P, get_context, S, _, _ = args ctx = get_context(("x", 2)) @@ -3301,7 +3303,7 @@ def quick_poly(): @all_mpolys -def test_mpolys_properties(args: _MPolyTestCase[Tmpoly, Tscalar]) -> None: +def test_mpolys_properties(args: _MPolyTestCase[Tmpoly_p, Tscalar]) -> None: P, get_context, S, is_field, characteristic = args diff --git a/src/flint/types/fmpq_mpoly.pyi b/src/flint/types/fmpq_mpoly.pyi index 833ba9c7..58b388b1 100644 --- a/src/flint/types/fmpq_mpoly.pyi +++ b/src/flint/types/fmpq_mpoly.pyi @@ -1,4 +1,4 @@ -from typing import Iterable, Mapping +from typing import Iterable, Mapping, Any from ..flint_base.flint_base import flint_mpoly, flint_mpoly_context, Ordering from .fmpz import fmpz from .fmpq import fmpq @@ -20,15 +20,32 @@ class fmpq_mpoly_ctx(flint_mpoly_context[fmpq_mpoly, fmpq, ifmpq]): def nvars(self) -> int: ... def ordering(self) -> Ordering: ... - - def gen(self, i: int) -> fmpq_mpoly: ... - def from_dict(self, d: Mapping[tuple[int, ...], ifmpq]) -> fmpq_mpoly: ... - def constant(self, z: ifmpq) -> fmpq_mpoly: ... - + def gen(self, i: int, /) -> fmpq_mpoly: ... + def from_dict(self, d: Mapping[tuple[int, ...], ifmpq], /) -> fmpq_mpoly: ... + def constant(self, q: ifmpq, /) -> fmpq_mpoly: ... + def name(self, i: int, /) -> str: ... + def names(self) -> tuple[str]: ... + def gens(self) -> tuple[fmpq_mpoly, ...]: ... + def variable_to_index(self, var: str, /) -> int: ... + def term( + self, coeff: ifmpq | None = None, exp_vec: Iterable[int] | None = None + ) -> fmpq_mpoly: ... + def drop_gens(self, gens: Iterable[str | int], /) -> fmpq_mpoly_ctx: ... + def append_gens(self, gens: Iterable[str | int], /) -> fmpq_mpoly_ctx: ... + def infer_generator_mapping( + self, ctx: flint_mpoly_context, / + ) -> dict[int, int]: ... + @classmethod + def from_context( + cls, + ctx: flint_mpoly_context[Any, Any, Any], + names: str | Iterable[str | tuple[str, int]] | tuple[str, int] | None = None, + ordering: Ordering | str = Ordering.lex, + ) -> fmpq_mpoly_ctx: ... class fmpq_mpoly(flint_mpoly[fmpq_mpoly_ctx, fmpq, ifmpq]): def __init__(self, - val: fmpq_mpoly | fmpz_mpoly | ifmpq | dict[tuple[int, ...], ifmpq] | _str = 0, + val: fmpq_mpoly | fmpz_mpoly | ifmpq | Mapping[tuple[int, ...], ifmpq] | _str = 0, ctx: fmpq_mpoly_ctx | None = None ) -> None: ... @@ -53,7 +70,7 @@ class fmpq_mpoly(flint_mpoly[fmpq_mpoly_ctx, fmpq, ifmpq]): def __getitem__(self, index: tuple[int, ...]) -> fmpq: ... def __setitem__(self, index: tuple[int, ...], coeff: ifmpq) -> None: ... - def subs(self, mapping: dict[_str | int, ifmpq]) -> fmpq_mpoly: ... + def subs(self, mapping: Mapping[_str | int, ifmpq]) -> fmpq_mpoly: ... def compose(self, *args: fmpq_mpoly, ctx: fmpq_mpoly_ctx | None = None) -> fmpq_mpoly: ... def __call__(self, *args: ifmpq) -> fmpq: ... diff --git a/src/flint/types/fmpz_mod_mpoly.pyi b/src/flint/types/fmpz_mod_mpoly.pyi index 02db61fd..17080081 100644 --- a/src/flint/types/fmpz_mod_mpoly.pyi +++ b/src/flint/types/fmpz_mod_mpoly.pyi @@ -1,5 +1,10 @@ -from typing import Iterable, Mapping -from ..flint_base.flint_base import flint_mpoly, flint_mod_mpoly_context, Ordering +from typing import Iterable, Mapping, Any +from ..flint_base.flint_base import ( + flint_mpoly, + flint_mpoly_context, + flint_mod_mpoly_context, + Ordering, +) from .fmpz import fmpz from .fmpz_mod import fmpz_mod from .fmpz_mpoly import fmpz_mpoly @@ -17,21 +22,43 @@ class fmpz_mod_mpoly_ctx(flint_mod_mpoly_context[fmpz_mod_mpoly, fmpz_mod, ifmpz names: _str | Iterable[_str | tuple[_str, int]] | tuple[_str, int], ordering: Ordering | _str = Ordering.lex, *, - modulus: ifmpz, + modulus: int, ) -> fmpz_mod_mpoly_ctx: ... + def modulus(self) -> fmpz: ... + def nvars(self) -> int: ... def ordering(self) -> Ordering: ... - def modulus(self) -> int: ... - def gen(self, i: int, /) -> fmpz_mod_mpoly: ... - def constant(self, z: ifmpz_mod) -> fmpz_mod_mpoly: ... + + def gen(self, i: int) -> fmpz_mod_mpoly: ... def from_dict(self, d: Mapping[tuple[int, ...], ifmpz_mod]) -> fmpz_mod_mpoly: ... + def constant(self, z: ifmpz_mod) -> fmpz_mod_mpoly: ... + + def name(self, i: int, /) -> str: ... + def names(self) -> tuple[str]: ... + def gens(self) -> tuple[fmpz_mod_mpoly, ...]: ... + def variable_to_index(self, var: str, /) -> int: ... + def term( + self, coeff: ifmpz_mod | None = None, exp_vec: Iterable[int] | None = None + ) -> fmpz_mod_mpoly: ... + def drop_gens(self, gens: Iterable[str | int], /) -> fmpz_mod_mpoly_ctx: ... + def append_gens(self, gens: Iterable[str | int], /) -> fmpz_mod_mpoly_ctx: ... + def infer_generator_mapping( + self, ctx: flint_mpoly_context, / + ) -> dict[int, int]: ... + @classmethod + def from_context( + cls, + ctx: flint_mpoly_context[Any, Any, Any], + names: str | Iterable[str | tuple[str, int]] | tuple[str, int] | None = None, + ordering: Ordering | str = Ordering.lex, + ) -> fmpz_mod_mpoly_ctx: ... class fmpz_mod_mpoly(flint_mpoly[fmpz_mod_mpoly_ctx, fmpz_mod, ifmpz_mod]): def __init__(self, - val: fmpz_mod_mpoly | fmpz_mpoly | ifmpz_mod | dict[tuple[int, ...], ifmpz_mod] | _str = 0, + val: fmpz_mod_mpoly | fmpz_mpoly | ifmpz_mod | Mapping[tuple[int, ...], ifmpz_mod] | _str = 0, ctx: fmpz_mod_mpoly_ctx | None = None ) -> None: ... @@ -56,7 +83,7 @@ class fmpz_mod_mpoly(flint_mpoly[fmpz_mod_mpoly_ctx, fmpz_mod, ifmpz_mod]): def __getitem__(self, index: tuple[int, ...]) -> fmpz_mod: ... def __setitem__(self, index: tuple[int, ...], coeff: ifmpz_mod) -> None: ... - def subs(self, mapping: dict[_str | int, ifmpz_mod]) -> fmpz_mod_mpoly: ... + def subs(self, mapping: Mapping[_str | int, ifmpz_mod]) -> fmpz_mod_mpoly: ... def compose(self, *args: fmpz_mod_mpoly, ctx: fmpz_mod_mpoly_ctx | None = None) -> fmpz_mod_mpoly: ... def __call__(self, *args: ifmpz_mod) -> fmpz_mod: ... diff --git a/src/flint/types/fmpz_mpoly.pyi b/src/flint/types/fmpz_mpoly.pyi index 1ec15c31..91d2a2c7 100644 --- a/src/flint/types/fmpz_mpoly.pyi +++ b/src/flint/types/fmpz_mpoly.pyi @@ -1,4 +1,4 @@ -from typing import Iterable, Iterator, Mapping +from typing import Iterable, Iterator, Mapping, Any from ..flint_base.flint_base import flint_mpoly, flint_mpoly_context, Ordering from .fmpz import fmpz @@ -18,16 +18,33 @@ class fmpz_mpoly_ctx(flint_mpoly_context[fmpz_mpoly, fmpz, ifmpz]): def nvars(self) -> int: ... def ordering(self) -> Ordering: ... - - def gen(self, i: int) -> fmpz_mpoly: ... - def from_dict(self, d: Mapping[tuple[int, ...], ifmpz]) -> fmpz_mpoly: ... - def constant(self, z: ifmpz) -> fmpz_mpoly: ... - + def gen(self, i: int, /) -> fmpz_mpoly: ... + def from_dict(self, d: Mapping[tuple[int, ...], ifmpz], /) -> fmpz_mpoly: ... + def constant(self, z: ifmpz, /) -> fmpz_mpoly: ... + def name(self, i: int, /) -> str: ... + def names(self) -> tuple[str]: ... + def gens(self) -> tuple[fmpz_mpoly, ...]: ... + def variable_to_index(self, var: str, /) -> int: ... + def term( + self, coeff: ifmpz | None = None, exp_vec: Iterable[int] | None = None + ) -> fmpz_mpoly: ... + def drop_gens(self, gens: Iterable[str | int], /) -> fmpz_mpoly_ctx: ... + def append_gens(self, gens: Iterable[str | int], /) -> fmpz_mpoly_ctx: ... + def infer_generator_mapping( + self, ctx: flint_mpoly_context, / + ) -> dict[int, int]: ... + @classmethod + def from_context( + cls, + ctx: flint_mpoly_context[Any, Any, Any], + names: str | Iterable[str | tuple[str, int]] | tuple[str, int] | None = None, + ordering: Ordering | str = Ordering.lex, + ) -> fmpz_mpoly_ctx: ... class fmpz_mpoly(flint_mpoly[fmpz_mpoly_ctx, fmpz, ifmpz]): def __init__(self, - val: fmpz_mpoly | ifmpz | dict[tuple[int, ...], ifmpz] | _str = 0, + val: fmpz_mpoly | ifmpz | Mapping[tuple[int, ...], ifmpz] | _str = 0, ctx: fmpz_mpoly_ctx | None = None ) -> None: ... @@ -52,7 +69,7 @@ class fmpz_mpoly(flint_mpoly[fmpz_mpoly_ctx, fmpz, ifmpz]): def __getitem__(self, index: tuple[int, ...]) -> fmpz: ... def __setitem__(self, index: tuple[int, ...], coeff: ifmpz) -> None: ... - def subs(self, mapping: dict[_str | int, ifmpz]) -> fmpz_mpoly: ... + def subs(self, mapping: Mapping[_str | int, ifmpz]) -> fmpz_mpoly: ... def compose(self, *args: fmpz_mpoly, ctx: fmpz_mpoly_ctx | None = None) -> fmpz_mpoly: ... def __call__(self, *args: ifmpz) -> fmpz: ... diff --git a/src/flint/types/nmod_mpoly.pyi b/src/flint/types/nmod_mpoly.pyi index b2eed49b..43ea7d74 100644 --- a/src/flint/types/nmod_mpoly.pyi +++ b/src/flint/types/nmod_mpoly.pyi @@ -1,5 +1,10 @@ -from typing import Iterable, Mapping, Self -from ..flint_base.flint_base import flint_mpoly, flint_mpoly_context, Ordering +from typing import Iterable, Mapping, Self, Any +from ..flint_base.flint_base import ( + flint_mpoly, + flint_mpoly_context, + flint_mod_mpoly_context, + Ordering, +) from .fmpz import fmpz from .fmpq import fmpq from .nmod import nmod @@ -11,7 +16,7 @@ ifmpz = int | fmpz inmod = int | fmpz | fmpq | nmod -class nmod_mpoly_ctx(flint_mpoly_context[nmod_mpoly, nmod, inmod]): +class nmod_mpoly_ctx(flint_mod_mpoly_context[nmod_mpoly, nmod, inmod]): @classmethod def get(cls, @@ -22,6 +27,8 @@ class nmod_mpoly_ctx(flint_mpoly_context[nmod_mpoly, nmod, inmod]): ) -> nmod_mpoly_ctx: ... + def modulus(self) -> int: ... + def nvars(self) -> int: ... def ordering(self) -> Ordering: ... @@ -29,10 +36,30 @@ class nmod_mpoly_ctx(flint_mpoly_context[nmod_mpoly, nmod, inmod]): def from_dict(self, d: Mapping[tuple[int, ...], inmod]) -> nmod_mpoly: ... def constant(self, z: inmod) -> nmod_mpoly: ... + def name(self, i: int, /) -> str: ... + def names(self) -> tuple[str]: ... + def gens(self) -> tuple[nmod_mpoly, ...]: ... + def variable_to_index(self, var: str, /) -> int: ... + def term( + self, coeff: inmod | None = None, exp_vec: Iterable[int] | None = None + ) -> nmod_mpoly: ... + def drop_gens(self, gens: Iterable[str | int], /) -> nmod_mpoly_ctx: ... + def append_gens(self, gens: Iterable[str | int], /) -> nmod_mpoly_ctx: ... + def infer_generator_mapping( + self, ctx: flint_mpoly_context, / + ) -> dict[int, int]: ... + @classmethod + def from_context( + cls, + ctx: flint_mpoly_context[Any, Any, Any], + names: str | Iterable[str | tuple[str, int]] | tuple[str, int] | None = None, + ordering: Ordering | str = Ordering.lex, + ) -> nmod_mpoly_ctx: ... + class nmod_mpoly(flint_mpoly[nmod_mpoly_ctx, nmod, inmod]): def __init__(self, - val: nmod_mpoly | fmpz_mpoly | inmod | dict[tuple[int, ...], inmod] | _str = 0, + val: nmod_mpoly | fmpz_mpoly | inmod | Mapping[tuple[int, ...], inmod] | _str = 0, ctx: nmod_mpoly_ctx | None = None ) -> None: ... @@ -57,7 +84,7 @@ class nmod_mpoly(flint_mpoly[nmod_mpoly_ctx, nmod, inmod]): def __getitem__(self, index: tuple[int, ...]) -> nmod: ... def __setitem__(self, index: tuple[int, ...], coeff: inmod) -> None: ... - def subs(self, mapping: dict[_str | int, inmod]) -> nmod_mpoly: ... + def subs(self, mapping: Mapping[_str | int, inmod]) -> nmod_mpoly: ... def compose(self, *args: nmod_mpoly, ctx: nmod_mpoly_ctx | None = None) -> nmod_mpoly: ... def __call__(self, *args: inmod) -> nmod: ... diff --git a/src/flint/typing.py b/src/flint/typing.py index 76c71358..795a8a89 100644 --- a/src/flint/typing.py +++ b/src/flint/typing.py @@ -1,6 +1,8 @@ # # # +from __future__ import annotations + from typing import ( TYPE_CHECKING, Protocol, @@ -39,9 +41,9 @@ "elem_p", "scalar_p", "poly_p", - # "mpoly_p", - # "mpoly_context_p", # "series_p", + "mpoly_p", + "mpoly_context_p", # Types "Ordering", @@ -50,18 +52,6 @@ ] -if TYPE_CHECKING: - import flint as _flint - - -_Telem = TypeVar("_Telem", bound=flint_scalar) -_Telem_co = TypeVar("_Telem_co", bound=flint_scalar, covariant=True) -_Telem_coerce = TypeVar("_Telem_coerce") -_Telem_coerce_contra = TypeVar("_Telem_coerce_contra", contravariant=True) -_Tmpoly = TypeVar("_Tmpoly", bound=flint_mpoly, covariant=True) -_Tctx = TypeVar("_Tctx", bound=flint_mpoly_context) -_Sctx = TypeVar("_Sctx", bound=flint_mpoly_context) - _str = str @@ -92,6 +82,7 @@ def __rpow__(self, other: int, /) -> Self: ... _Tscalar = TypeVar("_Tscalar", bound=scalar_p) +_Tscalar_contra = TypeVar("_Tscalar_contra", bound=scalar_p, contravariant=True) class poly_p(elem_p, Protocol[_Tscalar]): @@ -149,140 +140,174 @@ def factor_squarefree(self) -> tuple[_Tscalar, list[tuple[Self, int]]]: ... def deflation(self) -> tuple[Self, int]: ... -class _mpoly_p(elem_p, Protocol[_Tctx, _Telem, _Telem_coerce]): - """FLINT multivariate polynomial Protocol.""" - def __init__( - self, - val: Self - | _Telem - | _Telem_coerce - | int - | dict[tuple[int, ...], _Telem | _Telem_coerce | int] - | str = 0, - ctx: _Tctx | None = None, - ) -> None: ... - def str(self) -> _str: ... - def repr(self) -> _str: ... - def context(self) -> _Tctx: ... - def degrees(self) -> tuple[int, ...]: ... - def total_degree(self) -> int: ... - def leading_coefficient(self) -> _Telem: ... - def to_dict(self) -> dict[tuple[int, ...], _Telem]: ... - def is_one(self) -> bool: ... - def is_zero(self) -> bool: ... - def is_constant(self) -> bool: ... - def __len__(self) -> int: ... - def __getitem__(self, index: tuple[int, ...]) -> _Telem: ... - def __setitem__( - self, index: tuple[int, ...], coeff: _Telem | _Telem_coerce | int - ) -> None: ... - def __iter__(self) -> Iterable[tuple[int, ...]]: ... - def __contains__(self, index: tuple[int, ...]) -> bool: ... - def coefficient(self, i: int) -> _Telem: ... - def monomial(self, i: int) -> tuple[int, ...]: ... - def terms(self) -> Iterable[tuple[tuple[int, ...], _Telem]]: ... - def monoms(self) -> list[tuple[int, ...]]: ... - def coeffs(self) -> list[_Telem]: ... - def __pos__(self) -> Self: ... - def __neg__(self) -> Self: ... - def __add__(self, other: Self | _Telem | _Telem_coerce | int) -> Self: ... - def __radd__(self, other: _Telem | _Telem_coerce | int) -> Self: ... - def __sub__(self, other: Self | _Telem | _Telem_coerce | int) -> Self: ... - def __rsub__(self, other: _Telem | _Telem_coerce | int) -> Self: ... - def __mul__(self, other: Self | _Telem | _Telem_coerce | int) -> Self: ... - def __rmul__(self, other: _Telem | _Telem_coerce | int) -> Self: ... - def __truediv__(self, other: Self | _Telem | _Telem_coerce | int) -> Self: ... - def __rtruediv__(self, other: _Telem | _Telem_coerce | int) -> Self: ... - def __floordiv__(self, other: Self | _Telem | _Telem_coerce | int) -> Self: ... - def __rfloordiv__(self, other: _Telem | _Telem_coerce | int) -> Self: ... - def __mod__(self, other: Self | _Telem | _Telem_coerce | int) -> Self: ... - def __rmod__(self, other: _Telem | _Telem_coerce | int) -> Self: ... - def __divmod__( - self, other: Self | _Telem | _Telem_coerce | int - ) -> tuple[Self, Self]: ... - def __rdivmod__(self, other: _Telem | _Telem_coerce | int) -> tuple[Self, Self]: ... - def __pow__(self, other: _Telem | _Telem_coerce | int) -> Self: ... - def __rpow__(self, other: _Telem | _Telem_coerce | int) -> Self: ... - def iadd(self, other: _Telem | _Telem_coerce | int) -> None: ... - def isub(self, other: _Telem | _Telem_coerce | int) -> None: ... - def imul(self, other: _Telem | _Telem_coerce | int) -> None: ... - def gcd(self, other: Self) -> Self: ... - def term_content(self) -> Self: ... - def factor(self) -> tuple[_Telem, Sequence[tuple[Self, int]]]: ... - def factor_squarefree(self) -> tuple[_Telem, Sequence[tuple[Self, int]]]: ... - def sqrt(self) -> Self: ... - def resultant(self, other: Self, var: _str | int) -> Self: ... - def discriminant(self, var: _str | int) -> Self: ... - def deflation_index(self) -> tuple[list[int], list[int]]: ... - def deflation(self) -> tuple[Self, list[int]]: ... - def deflation_monom(self) -> tuple[Self, list[int], Self]: ... - def inflate(self, N: list[int]) -> Self: ... - def deflate(self, N: list[int]) -> Self: ... - def subs(self, mapping: dict[_str | int, _Telem | _Telem_coerce | int]) -> Self: ... - def compose(self, *args: Self, ctx: _Tctx | None = None) -> Self: ... - def __call__(self, *args: _Telem | _Telem_coerce) -> _Telem: ... - def derivative(self, var: _str | int) -> Self: ... - def unused_gens(self) -> tuple[_str, ...]: ... - def project_to_context( - self, other_ctx: _Tctx, mapping: dict[_str | int, _str | int] | None = None - ) -> Self: ... +class _series_p(elem_p, Protocol[_Tscalar]): + """FLINT univariate power series.""" + + def __iter__(self) -> Iterator[_Tscalar]: ... + def coeffs(self) -> list[_Tscalar]: ... -class _mpoly_context_p( - elem_p, Protocol[_Tmpoly, _Telem_co, _Telem_coerce_contra] -): - """FLINT multivariate polynomial context protocol.""" +class mpoly_p(elem_p, Protocol[_Tscalar]): + def __init__( + self, + val: Self + | _Tscalar + | int + | Mapping[tuple[int, ...], _Tscalar | int] + | str = 0, + ctx: Any | None = None, + ) -> None: ... + def str(self) -> _str: ... + def repr(self) -> _str: ... + def context(self) -> mpoly_context_p[Self, _Tscalar]: ... + def degrees(self) -> tuple[int, ...]: ... + def total_degree(self) -> int: ... + def leading_coefficient(self) -> _Tscalar: ... + def to_dict(self) -> dict[tuple[int, ...], _Tscalar]: ... + def is_one(self) -> bool: ... + def is_zero(self) -> bool: ... + def is_constant(self) -> bool: ... + def __len__(self) -> int: ... + def __getitem__(self, index: tuple[int, ...]) -> _Tscalar: ... + def __setitem__( + self, index: tuple[int, ...], coeff: _Tscalar | int + ) -> None: ... + def __iter__(self) -> Iterable[tuple[int, ...]]: ... + def __contains__(self, index: tuple[int, ...]) -> bool: ... + def coefficient(self, i: int) -> _Tscalar: ... + def monomial(self, i: int) -> tuple[int, ...]: ... + def terms(self) -> Iterable[tuple[tuple[int, ...], _Tscalar]]: ... + def monoms(self) -> list[tuple[int, ...]]: ... + def coeffs(self) -> list[_Tscalar]: ... + def __pos__(self) -> Self: ... + def __neg__(self) -> Self: ... + def __add__(self, other: Self | _Tscalar | int) -> Self: ... + def __radd__(self, other: _Tscalar | int) -> Self: ... + def __sub__(self, other: Self | _Tscalar | int) -> Self: ... + def __rsub__(self, other: _Tscalar | int) -> Self: ... + def __mul__(self, other: Self | _Tscalar | int) -> Self: ... + def __rmul__(self, other: _Tscalar | int) -> Self: ... + def __truediv__(self, other: Self | _Tscalar | int) -> Self: ... + def __rtruediv__(self, other: _Tscalar | int) -> Self: ... + def __floordiv__(self, other: Self | _Tscalar | int) -> Self: ... + def __rfloordiv__(self, other: _Tscalar | int) -> Self: ... + def __mod__(self, other: Self | _Tscalar | int) -> Self: ... + def __rmod__(self, other: _Tscalar | int) -> Self: ... + def __divmod__( + self, other: Self | _Tscalar | int + ) -> tuple[Self, Self]: ... + def __rdivmod__(self, other: _Tscalar | int) -> tuple[Self, Self]: ... + def __pow__(self, other: _Tscalar | int) -> Self: ... + def __rpow__(self, other: _Tscalar | int) -> Self: ... + def iadd(self, other: _Tscalar | int) -> None: ... + def isub(self, other: _Tscalar | int) -> None: ... + def imul(self, other: _Tscalar | int) -> None: ... + def gcd(self, other: Self) -> Self: ... + def term_content(self) -> Self: ... + def factor(self) -> tuple[_Tscalar, Sequence[tuple[Self, int]]]: ... + def factor_squarefree(self) -> tuple[_Tscalar, Sequence[tuple[Self, int]]]: ... + def sqrt(self) -> Self: ... + def resultant(self, other: Self, var: _str | int) -> Self: ... + def discriminant(self, var: _str | int) -> Self: ... + def deflation_index(self) -> tuple[list[int], list[int]]: ... + def deflation(self) -> tuple[Self, list[int]]: ... + def deflation_monom(self) -> tuple[Self, list[int], Self]: ... + def inflate(self, N: list[int]) -> Self: ... + def deflate(self, N: list[int]) -> Self: ... + def subs(self, mapping: Mapping[_str | int, _Tscalar | int]) -> Self: ... + def compose(self, *args: Self, ctx: Any | None = None) -> Self: ... + def __call__(self, *args: _Tscalar) -> _Tscalar: ... + def derivative(self, var: _str | int) -> Self: ... + def unused_gens(self) -> tuple[_str, ...]: ... + def project_to_context( + self, other_ctx: Any, mapping: dict[_str | int, _str | int] | None = None + ) -> Self: ... + + +_Tmpoly_p = TypeVar("_Tmpoly_p", bound=mpoly_p, covariant=True) + + +class mpoly_context_p(elem_p, Protocol[_Tmpoly_p, _Tscalar_contra]): def nvars(self) -> int: ... def ordering(self) -> Ordering: ... - def gen(self, i: int, /) -> _Tmpoly: ... - def from_dict(self, d: Mapping[tuple[int, ...], _Telem_coerce_contra], /) -> _Tmpoly: ... - def constant(self, z: _Telem_coerce_contra, /) -> _Tmpoly: ... + def gen(self, i: int, /) -> _Tmpoly_p: ... + def from_dict(self, d: Mapping[tuple[int, ...], _Tscalar_contra | int], /) -> _Tmpoly_p: ... + def constant(self, z: _Tscalar_contra | int, /) -> _Tmpoly_p: ... def name(self, i: int, /) -> str: ... def names(self) -> tuple[str]: ... - def gens(self) -> tuple[_Tmpoly, ...]: ... + def gens(self) -> tuple[_Tmpoly_p, ...]: ... def variable_to_index(self, var: str, /) -> int: ... def term( - self, coeff: _Telem_coerce_contra | None = None, exp_vec: Iterable[int] | None = None - ) -> _Tmpoly: ... + self, coeff: _Tscalar_contra | None = None, exp_vec: Iterable[int] | None = None + ) -> _Tmpoly_p: ... def drop_gens(self, gens: Iterable[str | int], /) -> Self: ... def append_gens(self, gens: Iterable[str | int], /) -> Self: ... def infer_generator_mapping( - self, ctx: flint_mpoly_context, / + self, ctx: Self, / ) -> dict[int, int]: ... @classmethod def from_context( cls, - ctx: _Sctx, + ctx: flint_mpoly_context, # make a protocol for this? names: str | Iterable[str | tuple[str, int]] | tuple[str, int] | None = None, ordering: Ordering | str = Ordering.lex, - ) -> _Sctx: ... + ) -> Self: ... -class _series_p(elem_p, Protocol[_Telem]): - """FLINT univariate power series.""" +if TYPE_CHECKING: - def __iter__(self) -> Iterator[_Telem]: ... - def coeffs(self) -> list[_Telem]: ... + import flint as _f + _x1: scalar_p = _f.fmpz(1) + _x2: scalar_p = _f.fmpq(1, 2) + _x3: scalar_p = _f.nmod(1, 2) + _x4: scalar_p = _f.fmpz_mod(1, _f.fmpz_mod_ctx(2)) + _x5: scalar_p = _f.fq_default(1, _f.fq_default_ctx(2)) + # XXX: Add arf, acf, arb, acb, ... -if TYPE_CHECKING: + _Tscalar0 = TypeVar("_Tscalar0", bound=scalar_p) - _x1: scalar_p = _flint.fmpz(1) - _x2: scalar_p = _flint.fmpq(1, 2) - _x3: scalar_p = _flint.nmod(1, 2) - _x4: scalar_p = _flint.fmpz_mod(1, _flint.fmpz_mod_ctx(2)) - _x5: scalar_p = _flint.fq_default(1, _flint.fq_default_ctx(2)) - # XXX: Add arf, acf, arb, acb, ... + def _scalar(x: _Tscalar0, y: _Tscalar0) -> _Tscalar0: + z = x + y + 1 + z = z / z + x**2 + z = 1 / z + 1**z + return z - _y1: poly_p[_flint.fmpz] = _flint.fmpz_poly([1, 2]) - _y2: poly_p[_flint.fmpq] = _flint.fmpq_poly([1, 2]) - _y3: poly_p[_flint.nmod] = _flint.nmod_poly(1, 2) - _y4: poly_p[_flint.fmpz_mod] = _flint.fmpz_mod_poly(1, _flint.fmpz_mod_poly_ctx(2)) - _y5: poly_p[_flint.fq_default] = _flint.fq_default_poly(1, _flint.fq_default_poly_ctx(2)) + _y1: poly_p[_f.fmpz] = _f.fmpz_poly([1, 2]) + _y2: poly_p[_f.fmpq] = _f.fmpq_poly([1, 2]) + _y3: poly_p[_f.nmod] = _f.nmod_poly(1, 2) + _y4: poly_p[_f.fmpz_mod] = _f.fmpz_mod_poly(1, _f.fmpz_mod_poly_ctx(2)) + _y5: poly_p[_f.fq_default] = _f.fq_default_poly(1, _f.fq_default_poly_ctx(2)) # XXX: Add arb_poly, acb_poly, ... - _z1: epoly_p[_flint.fmpz] = _flint.fmpz_poly([1, 2]) - _z2: epoly_p[_flint.fmpq] = _flint.fmpq_poly([1, 2]) - _z3: epoly_p[_flint.nmod] = _flint.nmod_poly(1, 2) - _z4: epoly_p[_flint.fmpz_mod] = _flint.fmpz_mod_poly(1, _flint.fmpz_mod_poly_ctx(2)) - _z5: epoly_p[_flint.fq_default] = _flint.fq_default_poly(1, _flint.fq_default_poly_ctx(2)) + def _poly(x: epoly_p[_Tscalar0], y: epoly_p[_Tscalar0]) -> epoly_p[_Tscalar0]: + z = x + y + 1 + z = z / z + x**2 + z = 1 / z + z.coeffs()[0] + return z + + _z1: epoly_p[_f.fmpz] = _f.fmpz_poly([1, 2]) + _z2: epoly_p[_f.fmpq] = _f.fmpq_poly([1, 2]) + _z3: epoly_p[_f.nmod] = _f.nmod_poly(1, 2) + _z4: epoly_p[_f.fmpz_mod] = _f.fmpz_mod_poly(1, _f.fmpz_mod_poly_ctx(2)) + _z5: epoly_p[_f.fq_default] = _f.fq_default_poly(1, _f.fq_default_poly_ctx(2)) + + def _epoly(x: epoly_p[_Tscalar0], y: epoly_p[_Tscalar0]) -> epoly_p[_Tscalar0]: + return x.gcd(y).factor()[1][0][0] + + _ctx1: mpoly_context_p[_f.fmpz_mpoly, _f.fmpz] = _f.fmpz_mpoly_ctx.get(['x', 'y']) + _ctx2: mpoly_context_p[_f.fmpq_mpoly, _f.fmpq] = _f.fmpq_mpoly_ctx.get(['x', 'y']) + _ctx3: mpoly_context_p[_f.nmod_mpoly, _f.nmod] = _f.nmod_mpoly_ctx.get(['x', 'y'], modulus=7) + _ctx4: mpoly_context_p[_f.fmpz_mod_mpoly, _f.fmpz_mod] = _f.fmpz_mod_mpoly_ctx.get(['x', 'y'], modulus=7) + + _p1: mpoly_p[_f.fmpz] = _ctx1.gens()[0] + _p2: mpoly_p[_f.fmpq] = _ctx2.gens()[0] + _p3: mpoly_p[_f.nmod] = _ctx3.gens()[0] + _p4: mpoly_p[_f.fmpz_mod] = _ctx4.gens()[0] + + _Tmpoly0 = TypeVar("_Tmpoly0", bound=mpoly_p) + + def _mpoly(x: mpoly_p[_Tscalar], y: mpoly_p[_Tscalar], ctx: mpoly_context_p[_Tmpoly0, _Tscalar]) -> mpoly_p[_Tscalar]: + z = x.gcd(y).factor()[1][0][0] + ctx.gens()[0] + t = z.compose(z, ctx=ctx) + z.context().gens()[0] + return t