"""Numeric types and methods."""
# ruff: noqa: E501
# mypy: disable-error-code="empty-body, misc, override, valid-type, no-untyped-def, has-type"
from __future__ import annotations
from typing import no_type_check
import hugr.std.int
from guppylang_internals.decorator import custom_function, extend_type, hugr_op
from guppylang_internals.definition.custom import BoolOpCompiler, NoopCompiler
from guppylang_internals.std._internal.checker import DunderChecker, ReversingChecker
from guppylang_internals.std._internal.compiler.prelude import UnwrapOpCompiler
from guppylang_internals.std._internal.util import (
external_op,
float_op,
int_op,
unsupported_op,
)
from guppylang_internals.tys.builtin import float_type_def, int_type_def, nat_type_def
from guppylang import guppy
from guppylang.std.platform import panic
[docs]
@extend_type(nat_type_def)
class nat:
"""A 64-bit unsigned integer."""
[docs]
@custom_function(NoopCompiler())
def __abs__(self: nat) -> nat: ...
[docs]
@hugr_op(int_op("iadd"))
def __add__(self: nat, other: nat) -> nat: ...
[docs]
@hugr_op(int_op("iand"))
def __and__(self: nat, other: nat) -> nat: ...
[docs]
@guppy
@no_type_check
def __bool__(self: nat) -> bool:
return self != 0
[docs]
@custom_function(NoopCompiler())
def __ceil__(self: nat) -> nat: ...
[docs]
@hugr_op(int_op("idivmod_u", n_vars=2))
def __divmod__(self: nat, other: nat) -> tuple[nat, nat]: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ieq")))
def __eq__(self: nat, other: nat) -> bool: ...
[docs]
@hugr_op(int_op("convert_u", hugr.std.int.CONVERSIONS_EXTENSION))
def __float__(self: nat) -> float: ...
[docs]
@custom_function(NoopCompiler())
def __floor__(self: nat) -> nat: ...
[docs]
@hugr_op(int_op("idiv_u"))
def __floordiv__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ige_u")))
def __ge__(self: nat, other: nat) -> bool: ...
[docs]
@custom_function(BoolOpCompiler(int_op("igt_u")))
def __gt__(self: nat, other: nat) -> bool: ...
# TODO: Use "iu_to_s" once we have lowering:
# https://github.com/CQCL/hugr/issues/1806
[docs]
@custom_function(NoopCompiler())
def __int__(self: nat) -> int: ...
[docs]
@hugr_op(int_op("inot"))
def __invert__(self: nat) -> nat: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ile_u")))
def __le__(self: nat, other: nat) -> bool: ...
[docs]
@hugr_op(int_op("ishl"))
def __lshift__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ilt_u")))
def __lt__(self: nat, other: nat) -> bool: ...
[docs]
@hugr_op(int_op("imod_u", n_vars=2))
def __mod__(self: nat, other: nat) -> int: ...
[docs]
@hugr_op(int_op("imul"))
def __mul__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(NoopCompiler())
def __nat__(self: nat) -> nat: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ine")))
def __ne__(self: nat, other: nat) -> bool: ...
[docs]
@custom_function(checker=DunderChecker("__nat__"), higher_order_value=False)
def __new__(x): ...
[docs]
@hugr_op(int_op("ior"))
def __or__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(NoopCompiler())
def __pos__(self: nat) -> nat: ...
[docs]
@hugr_op(int_op("ipow"))
def __pow__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __radd__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rand__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rdivmod__(self: nat, other: nat) -> tuple[nat, nat]: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rfloordiv__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rlshift__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rmod__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rmul__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __ror__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(NoopCompiler())
def __round__(self: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rpow__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rrshift__(self: nat, other: nat) -> nat: ...
[docs]
@hugr_op(int_op("ishr"))
def __rshift__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rsub__(self: nat, other: nat) -> nat: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rtruediv__(self: nat, other: nat) -> float: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rxor__(self: nat, other: nat) -> nat: ...
[docs]
@hugr_op(int_op("isub"))
def __sub__(self: nat, other: nat) -> nat: ...
[docs]
@guppy
@no_type_check
def __truediv__(self: nat, other: nat) -> float:
return float(self) / float(other)
[docs]
@custom_function(NoopCompiler())
def __trunc__(self: nat) -> nat: ...
[docs]
@hugr_op(int_op("ixor"))
def __xor__(self: nat, other: nat) -> nat: ...
[docs]
@extend_type(int_type_def)
class int:
"""A 64-bit signed integer."""
[docs]
@hugr_op(int_op("iabs")) # TODO: Maybe wrong? (signed vs unsigned!)
def __abs__(self: int) -> int: ...
[docs]
@hugr_op(int_op("iadd"))
def __add__(self: int, other: int) -> int: ...
[docs]
@hugr_op(int_op("iand"))
def __and__(self: int, other: int) -> int: ...
[docs]
@guppy
@no_type_check
def __bool__(self: int) -> bool:
return self != 0
[docs]
@custom_function(NoopCompiler())
def __ceil__(self: int) -> int: ...
[docs]
@hugr_op(int_op("idivmod_s"))
def __divmod__(self: int, other: int) -> tuple[int, int]: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ieq")))
def __eq__(self: int, other: int) -> bool: ...
[docs]
@hugr_op(int_op("convert_s", hugr.std.int.CONVERSIONS_EXTENSION))
def __float__(self: int) -> float: ...
[docs]
@custom_function(NoopCompiler())
def __floor__(self: int) -> int: ...
[docs]
@hugr_op(int_op("idiv_s"))
def __floordiv__(self: int, other: int) -> int: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ige_s")))
def __ge__(self: int, other: int) -> bool: ...
[docs]
@custom_function(BoolOpCompiler(int_op("igt_s")))
def __gt__(self: int, other: int) -> bool: ...
[docs]
@custom_function(NoopCompiler())
def __int__(self: int) -> int: ...
[docs]
@hugr_op(int_op("inot"))
def __invert__(self: int) -> int: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ile_s")))
def __le__(self: int, other: int) -> bool: ...
[docs]
@hugr_op(int_op("ishl")) # TODO: RHS is unsigned
def __lshift__(self: int, other: int) -> int: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ilt_s")))
def __lt__(self: int, other: int) -> bool: ...
[docs]
@hugr_op(int_op("imod_s"))
def __mod__(self: int, other: int) -> int: ...
[docs]
@hugr_op(int_op("imul"))
def __mul__(self: int, other: int) -> int: ...
[docs]
@hugr_op(int_op("is_to_u")) # TODO
def __nat__(self: int) -> nat: ...
[docs]
@custom_function(BoolOpCompiler(int_op("ine")))
def __ne__(self: int, other: int) -> bool: ...
[docs]
@hugr_op(int_op("ineg"))
def __neg__(self: int) -> int: ...
[docs]
@custom_function(checker=DunderChecker("__int__"), higher_order_value=False)
def __new__(x): ...
[docs]
@hugr_op(int_op("ior"))
def __or__(self: int, other: int) -> int: ...
[docs]
@custom_function(NoopCompiler())
def __pos__(self: int) -> int: ...
[docs]
@guppy
@no_type_check
def __pow__(self: int, exponent: int) -> int:
if exponent < 0:
panic(
"Negative exponent not supported in"
"__pow__ with int type base. Try casting the base to float."
)
return self.__pow_impl(exponent)
@hugr_op(int_op("ipow"))
def __pow_impl(self: int, exponent: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker())
def __radd__(self: int, other: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rand__(self: int, other: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rdivmod__(self: int, other: int) -> tuple[int, int]: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rfloordiv__(self: int, other: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker()) # TODO: RHS is unsigned
def __rlshift__(self: int, other: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rmod__(self: int, other: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rmul__(self: int, other: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker())
def __ror__(self: int, other: int) -> int: ...
[docs]
@custom_function(NoopCompiler())
def __round__(self: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rpow__(self: int, other: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker()) # TODO: RHS is unsigned
def __rrshift__(self: int, other: int) -> int: ...
[docs]
@hugr_op(int_op("ishr")) # TODO: RHS is unsigned
def __rshift__(self: int, other: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rsub__(self: int, other: int) -> int: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rtruediv__(self: int, other: int) -> float: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rxor__(self: int, other: int) -> int: ...
[docs]
@hugr_op(int_op("isub"))
def __sub__(self: int, other: int) -> int: ...
[docs]
@guppy
@no_type_check
def __truediv__(self: int, other: int) -> float:
return float(self) / float(other)
[docs]
@custom_function(NoopCompiler())
def __trunc__(self: int) -> int: ...
[docs]
@hugr_op(int_op("ixor"))
def __xor__(self: int, other: int) -> int: ...
[docs]
@extend_type(float_type_def)
class float:
"""An IEEE754 double-precision floating point value."""
[docs]
@hugr_op(float_op("fabs"))
def __abs__(self: float) -> float: ...
[docs]
@hugr_op(float_op("fadd"))
def __add__(self: float, other: float) -> float: ...
[docs]
@guppy
@no_type_check
def __bool__(self: float) -> bool:
return self != 0.0
[docs]
@hugr_op(float_op("fceil"))
def __ceil__(self: float) -> float: ...
[docs]
@guppy
@no_type_check
def __divmod__(self: float, other: float) -> tuple[float, float]:
return self // other, self.__mod__(other)
[docs]
@custom_function(BoolOpCompiler(float_op("feq")))
def __eq__(self: float, other: float) -> bool: ...
[docs]
@custom_function(NoopCompiler())
def __float__(self: float) -> float: ...
[docs]
@hugr_op(float_op("ffloor"))
def __floor__(self: float) -> float: ...
[docs]
@guppy
@no_type_check
def __floordiv__(self: float, other: float) -> float:
return (self / other).__floor__()
[docs]
@custom_function(BoolOpCompiler(float_op("fge")))
def __ge__(self: float, other: float) -> bool: ...
[docs]
@custom_function(BoolOpCompiler(float_op("fgt")))
def __gt__(self: float, other: float) -> bool: ...
[docs]
@custom_function(
UnwrapOpCompiler(
# Use `int_op` to instantiate type arg with 64-bit integer.
int_op("trunc_s", hugr.std.int.CONVERSIONS_EXTENSION),
)
)
def __int__(self: float) -> int: ...
[docs]
@custom_function(BoolOpCompiler(float_op("fle")))
def __le__(self: float, other: float) -> bool: ...
[docs]
@custom_function(BoolOpCompiler(float_op("flt")))
def __lt__(self: float, other: float) -> bool: ...
[docs]
@guppy
@no_type_check
def __mod__(self: float, other: float) -> float:
return self - (self // other) * other
[docs]
@hugr_op(float_op("fmul"))
def __mul__(self: float, other: float) -> float: ...
[docs]
@custom_function(
UnwrapOpCompiler(
# Use `int_op` to instantiate type arg with 64-bit integer.
int_op("trunc_u", hugr.std.int.CONVERSIONS_EXTENSION),
)
)
def __nat__(self: float) -> nat: ...
[docs]
@custom_function(BoolOpCompiler(float_op("fne")))
def __ne__(self: float, other: float) -> bool: ...
[docs]
@hugr_op(float_op("fneg"))
def __neg__(self: float) -> float: ...
[docs]
@custom_function(checker=DunderChecker("__float__"), higher_order_value=False)
def __new__(x): ...
[docs]
@custom_function(NoopCompiler())
def __pos__(self: float) -> float: ...
[docs]
@hugr_op(float_op("fpow")) # TODO
def __pow__(self: float, other: float) -> float: ...
[docs]
@custom_function(checker=ReversingChecker())
def __radd__(self: float, other: float) -> float: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rdivmod__(self: float, other: float) -> tuple[float, float]: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rfloordiv__(self: float, other: float) -> float: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rmod__(self: float, other: float) -> float: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rmul__(self: float, other: float) -> float: ...
[docs]
@hugr_op(float_op("fround")) # TODO
def __round__(self: float) -> float: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rpow__(self: float, other: float) -> float: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rsub__(self: float, other: float) -> float: ...
[docs]
@custom_function(checker=ReversingChecker())
def __rtruediv__(self: float, other: float) -> float: ...
[docs]
@hugr_op(float_op("fsub"))
def __sub__(self: float, other: float) -> float: ...
[docs]
@hugr_op(float_op("fdiv"))
def __truediv__(self: float, other: float) -> float: ...
[docs]
@hugr_op(unsupported_op("trunc_s")) # TODO `trunc_s` returns an option
def __trunc__(self: float) -> float: ...
[docs]
@custom_function(checker=DunderChecker("__abs__"), higher_order_value=False)
def abs(x): ...
# These should work equally well for signed integers if the need should arise
[docs]
@hugr_op(
external_op(
"bytecast_int64_to_float64", args=[], ext=hugr.std.int.CONVERSIONS_EXTENSION
)
)
def bytecast_nat_to_float(n: nat) -> float: ...
[docs]
@hugr_op(
external_op(
"bytecast_float64_to_int64", args=[], ext=hugr.std.int.CONVERSIONS_EXTENSION
)
)
def bytecast_float_to_nat(f: float) -> nat: ...
[docs]
@custom_function(
checker=DunderChecker("__divmod__", num_args=2), higher_order_value=False
)
def divmod(x, y): ...
[docs]
@custom_function(checker=DunderChecker("__len__"), higher_order_value=False)
def len(x): ...
[docs]
@custom_function(checker=DunderChecker("__pow__", num_args=2), higher_order_value=False)
def pow(x, y): ...
[docs]
@custom_function(checker=DunderChecker("__round__"), higher_order_value=False)
def round(x): ...