# Source code for pypdevsbbl.extra.equations

    #  Copyright 2020 Modelling, Simulation and Design Lab (MSDL) at
    #  McGill University and the University of Antwerp (http://msdl.cs.mcgill.ca/)
    #
    #  Licensed under the Apache License, Version 2.0 (the "License");
    #  you may not use this file except in compliance with the License.
    #  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    #  Unless required by applicable law or agreed to in writing, software
    #  distributed under the License is distributed on an "AS IS" BASIS,
    #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #  See the License for the specific language governing permissions and
    #  limitations under the License.

    """This file contains a set of mathematical equations as functions.

    These equations can be used as an input for the :class:`pypdevsbbl.generic.math.Equation`
    block for simplicity.

    Note:
        The described functions were written with the idea of numerical values as
        inputs. While it is advised to refrain from using non-numerical arguments,
        it is allowed within *Python*. There are no guarantees on what might happen
        if you decide to use non-numeric input.
    """

    def SUBTRACT(x, y):
        """Subtracts two values.

        Args:
            x (numeric):    The value to subtract from.
            y (numeric):    The value that subtracts.

        Returns:
            :math:`x - y`
        """
        return x - y

    def DIVIDE(x, y):
        """Divides two values.

        Args:
            x (numeric):    The numerator.
            y (numeric):    The denominator.

        Returns:
            :math:`\\dfrac{x}{y}`
        """
        return x / y

    def IDIVIDE(x, y):
        """Integer divides two values.

        Args:
            x (numeric):    The numerator.
            y (numeric):    The denominator.

        Returns:
            :math:`\\left\\lfloor\\dfrac{x}{y}\\right\\rfloor`
        """
        return x // y

    def MODULO(x, y):
        """Modulo divides two values.

        Args:
            x (numeric):    The numerator.
            y (numeric):    The denominator.

        Returns:
            :math:`x \\textrm{ mod } y`
        """
        return x % y

    def NEGATE(x):
        """Negates a value.

        Args:
            x (numeric):    The value to negate.

        Returns:
            :math:`- x`
        """
        return -x

    def INVERT(x):
        """Inverts a value.

        Args:
            x (numeric):    The value to invert.

        Returns:
            :math:`\\dfrac{1}{x}`
        """
        return 1.0 / x

    def POWER(x, y):
        """Raises x to the power of y.

        Args:
            x (numeric):    The base.
            y (numeric):    The power.

        Returns:
            :math:`x^y`
        """
        return x ** y

    def AND(x, y):
        """Boolean AND gate between x and y.

        Args:
            x (numeric):    The left hand side of the gate.
            y (numeric):    The right hand side of the gate.

        Returns:
            :math:`x \\textrm{ AND } y`
        """
        return x and y

    def OR(x, y):
        """Boolean OR gate between x and y.

        Args:
            x (numeric):    The left hand side of the gate.
            y (numeric):    The right hand side of the gate.

        Returns:
            :math:`x \\textrm{ OR } y`
        """
        return x or y

    def BAND(x, y):
        """Bitwise AND gate between x and y.

        Args:
            x (numeric):    The left hand side of the gate.
            y (numeric):    The right hand side of the gate.

        Returns:
            :math:`x \\textrm{ & } y`
        """
        return x & y

    def BOR(x, y):
        """Bitwise OR gate between x and y.

        Args:
            x (numeric):    The left hand side of the gate.
            y (numeric):    The right hand side of the gate.

        Returns:
            :math:`x \\textrm{ | } y`
        """
        return x | y

    def NOT(x):
        """Boolean NOT gate of x.

        Args:
            x (numeric):    The value to invert.

        Returns:
            :math:`\\textrm{NOT } x`
        """
        return not x

    def XOR(x, y):
        """The XOR gate between x and y.

        Args:
            x (numeric):    The left hand side of the gate.
            y (numeric):    The right hand side of the gate.

        Returns:
            :math:`x \\textrm{ XOR } y`
        """
        return x ^ y

    def NOR(x, y):
        """The NOR gate between x and y.

        Args:
            x (numeric):    The left hand side of the gate.
            y (numeric):    The right hand side of the gate.

        Returns:
            :math:`x \\textrm{ NOR } y`
        """
        return not (x or y)

    def XNOR(x, y):
        """The XNOR or XAND gate between x and y.

        Args:
            x (numeric):    The left hand side of the gate.
            y (numeric):    The right hand side of the gate.

        Returns:
            :math:`x \\textrm{ XNOR } y`
        """
        return not (x ^ y)

    def LT(x, y):
        """Checks if x is less than y.

        Args:
            x (numeric):    The smaller value.
            y (numeric):    The larger value.

        Returns:
            :math:`x < y`
        """
        return x < y

    def LE(x, y):
        """Checks if x is less than or equal to y.

        Args:
            x (numeric):    The smaller value.
            y (numeric):    The larger value.

        Returns:
            :math:`x \\leq y`
        """
        return x <= y

    #  Copyright 2020 Modelling, Simulation and Design Lab (MSDL) at
    #  McGill University and the University of Antwerp (http://msdl.cs.mcgill.ca/)
    #
    #  Licensed under the Apache License, Version 2.0 (the "License");
    #  you may not use this file except in compliance with the License.
    #  You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    #  Unless required by applicable law or agreed to in writing, software
    #  distributed under the License is distributed on an "AS IS" BASIS,
    #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #  See the License for the specific language governing permissions and
    #  limitations under the License.

    LEQ = LE
    """Synonym of :meth:`LE`."""

    def GT(x, y):
        """Checks if x is greater than y.

        Args:
            x (numeric):    The larger value.
            y (numeric):    The smaller value.

        Returns:
            :math:`x > y`
        """
        return x > y

    def GE(x, y):
        """Checks if x is greater than or equal to y.

        Args:
            x (numeric):    The larger value.
            y (numeric):    The smaller value.

        Returns:
            :math:`x \\geq y`
        """
        return x >= y

    GEQ = GE
    """Synonym of :meth:`GE`."""

    def EQ(x, y):
        """Checks if x equals y.

        Args:
            x (numeric):    The left hand side.
            y (numeric):    The right hand side.

        Returns:
            :math:`x == y`
        """
        return x == y

    EQUALS = EQ
    """Synonym of :meth:`EQ`."""

    def IDENTICAL(x, y):
        """Checks if x is identical to y.

        Args:
            x (numeric):    The left hand side.
            y (numeric):    The right hand side.

        Returns:
            :math:`x \\textrm{ is } y`
        """
        return x is y