Source code for phantom.predicates.numeric
from typing import TypeVar
from phantom._utils.types import SupportsGe
from phantom._utils.types import SupportsGt
from phantom._utils.types import SupportsLe
from phantom._utils.types import SupportsLt
from phantom._utils.types import SupportsMod
from ._base import Predicate
from ._utils import bind_name
from .boolean import negate
from .generic import equal
T = TypeVar("T")
U = TypeVar("U")
[docs]def less(n: T) -> Predicate[SupportsLt[T]]:
"""
Create a new predicate that succeeds when its argument is strictly less than ``n``.
"""
@bind_name(less, n)
def check(value: SupportsLt[T]) -> bool:
return value < n
return check
[docs]def le(n: T) -> Predicate[SupportsLe[T]]:
"""
Create a new predicate that succeeds when its argument is less than or equal to
``n``.
"""
@bind_name(le, n)
def check(value: SupportsLe[T]) -> bool:
return value <= n
return check
[docs]def greater(n: T) -> Predicate[SupportsGt[T]]:
"""
Create a new predicate that succeeds when its argument is strictly greater than
``n``.
"""
@bind_name(greater, n)
def check(value: SupportsGt[T]) -> bool:
return value > n
return check
[docs]def ge(n: T) -> Predicate[SupportsGe[T]]:
"""
Create a new predicate that succeeds when its argument is greater than or equal to
``n``.
"""
@bind_name(ge, n)
def check(value: SupportsGe[T]) -> bool:
return value >= n
return check
[docs]def positive(n: SupportsGt[int]) -> bool:
"""Return :py:const:`True` when ``n`` is strictly greater than zero."""
return greater(0)(n)
[docs]def non_positive(n: SupportsLe[int]) -> bool:
"""Return :py:const:`True` when ``n`` is less than or equal to zero."""
return le(0)(n)
[docs]def negative(n: SupportsLt[int]) -> bool:
"""Return :py:const:`True` when ``n`` is strictly less than zero."""
return less(0)(n)
[docs]def non_negative(n: SupportsGe[int]) -> bool:
"""Return :py:const:`True` when ``n`` is greater than or equal to zero."""
return ge(0)(n)
[docs]def modulo(n: T, p: Predicate[U]) -> Predicate[SupportsMod[T, U]]:
"""
Create a new predicate that succeeds when its argument modulo ``n`` satisfies the
given predicate ``p``.
"""
@bind_name(modulo, n, p)
def check(value: SupportsMod[T, U]) -> bool:
return p(value % n)
return check
[docs]def even(n: int) -> bool:
"""Return :py:const:`True` when ``n`` is even."""
return modulo(2, equal(0))(n)
[docs]def odd(n: int) -> bool:
"""Return :py:const:`True` when ``n`` is odd."""
return negate(even)(n)