Source code for constraints.OXSpecialConstraints

"""
Special Constraints Module for OptiX Optimization Framework
============================================================

This module provides specialized constraint classes for handling non-linear and
complex mathematical relationships in optimization problems. These constraints
extend beyond standard linear programming to support constraint programming
and mixed-integer programming scenarios.

The module implements various types of special constraints that cannot be expressed
as simple linear relationships, including multiplicative operations, division,
modulo arithmetic, summation operations, and conditional logic.

Classes:
    OXSpecialConstraint: Base class for all special constraint types
    OXNonLinearEqualityConstraint: Base class for non-linear equality constraints
    OXMultiplicativeEqualityConstraint: Constraint for variable multiplication operations
    OXDivisionEqualityConstraint: Constraint for integer division operations
    OXModuloEqualityConstraint: Constraint for modulo arithmetic operations
    OXSummationEqualityConstraint: Constraint for variable summation operations
    OXConditionalConstraint: Constraint for conditional logic and implications

Key Features:
    - Support for non-linear mathematical operations
    - UUID-based variable referencing for serialization compatibility
    - Integration with constraint programming solvers
    - Conditional logic and implication modeling
    - Type-safe constraint definitions with dataclass structure

Module Dependencies:
    - dataclasses: For structured constraint definitions
    - uuid: For variable identification and referencing
    - base: For core OptiX object system integration

Example:
    Creating and using special constraints for complex relationships:

    .. code-block:: python

        from constraints import (
            OXMultiplicativeEqualityConstraint,
            OXDivisionEqualityConstraint,
            OXConditionalConstraint
        )
        from variables import OXVariable
        
        # Create variables
        x = OXVariable(name="x", lower_bound=0, upper_bound=100)
        y = OXVariable(name="y", lower_bound=0, upper_bound=100)
        z = OXVariable(name="z", lower_bound=0, upper_bound=10000)
        quotient = OXVariable(name="quotient", lower_bound=0, upper_bound=50)
        
        # Create multiplication constraint: z = x * y
        mult_constraint = OXMultiplicativeEqualityConstraint(
            input_variables=[x.id, y.id],
            output_variable=z.id
        )
        
        # Create division constraint: quotient = x // 2
        div_constraint = OXDivisionEqualityConstraint(
            input_variable=x.id,
            denominator=2,
            output_variable=quotient.id
        )
        
        # These constraints would be added to a constraint programming problem
        # for solving with appropriate solvers like OR-Tools CP-SAT
"""

from dataclasses import dataclass, field
from uuid import UUID

from base import OXObject


[docs] @dataclass class OXSpecialConstraint(OXObject): """Base class for special constraints in optimization problems. Special constraints are non-linear constraints that cannot be expressed as simple linear relationships. They require special handling by solvers and often involve complex relationships between variables. This class serves as a base for all special constraint types including multiplicative, division, modulo, summation, and conditional constraints. See Also: :class:`OXNonLinearEqualityConstraint` :class:`OXMultiplicativeEqualityConstraint` :class:`OXDivisionEqualityConstraint` :class:`OXModuloEqualityConstraint` :class:`OXSummationEqualityConstraint` :class:`OXConditionalConstraint` """ pass
[docs] @dataclass class OXNonLinearEqualityConstraint(OXSpecialConstraint): """Base class for non-linear equality constraints. Non-linear equality constraints represent relationships that cannot be expressed as linear combinations of variables. They typically have the form f(x1, x2, ..., xn) = output_variable, where f is a non-linear function. Attributes: output_variable (UUID): The UUID of the variable that stores the result of the non-linear operation. Examples: This is a base class and should not be instantiated directly. Use specific subclasses like OXMultiplicativeEqualityConstraint. See Also: :class:`OXMultiplicativeEqualityConstraint` :class:`OXDivisionEqualityConstraint` :class:`OXModuloEqualityConstraint` """ output_variable: UUID = field(default_factory=UUID)
[docs] @dataclass class OXMultiplicativeEqualityConstraint(OXNonLinearEqualityConstraint): """A constraint representing multiplication of variables. This constraint enforces that the output variable equals the product of all input variables: output_variable = input_variable_1 * input_variable_2 * ... * input_variable_n Attributes: input_variables (list[UUID]): The list of variable UUIDs to multiply. output_variable (UUID): The UUID of the variable that stores the product. Inherited from OXNonLinearEqualityConstraint. Examples: >>> # Create a constraint: z = x * y >>> constraint = OXMultiplicativeEqualityConstraint( ... input_variables=[x.id, y.id], ... output_variable=z.id ... ) Note: This constraint is typically handled by constraint programming solvers that support non-linear operations. """ input_variables: list[UUID] = field(default_factory=list)
[docs] @dataclass class OXDivisionEqualityConstraint(OXNonLinearEqualityConstraint): """A constraint representing integer division of a variable. This constraint enforces that the output variable equals the integer division of the input variable by the denominator: output_variable = input_variable // denominator Attributes: input_variable (UUID): The UUID of the variable to divide. denominator (int): The divisor for the division operation. output_variable (UUID): The UUID of the variable that stores the quotient. Inherited from OXNonLinearEqualityConstraint. Examples: >>> # Create a constraint: z = x // 3 >>> constraint = OXDivisionEqualityConstraint( ... input_variable=x.id, ... denominator=3, ... output_variable=z.id ... ) Note: This constraint performs integer division (floor division), not floating-point division. """ input_variable: UUID = field(default_factory=UUID) denominator: int = 1
[docs] @dataclass class OXModuloEqualityConstraint(OXNonLinearEqualityConstraint): """A constraint representing modulo operation on a variable. This constraint enforces that the output variable equals the remainder of the input variable divided by the denominator: output_variable = input_variable % denominator Attributes: input_variable (UUID): The UUID of the variable to apply modulo to. denominator (int): The divisor for the modulo operation. output_variable (UUID): The UUID of the variable that stores the remainder. Inherited from OXNonLinearEqualityConstraint. Examples: >>> # Create a constraint: z = x % 5 >>> constraint = OXModuloEqualityConstraint( ... input_variable=x.id, ... denominator=5, ... output_variable=z.id ... ) Note: The result is always non-negative and less than the denominator. """ input_variable: UUID = field(default_factory=UUID) denominator: int = 1
[docs] @dataclass class OXSummationEqualityConstraint(OXSpecialConstraint): """A constraint representing summation of variables. This constraint enforces that the output variable equals the sum of all input variables: output_variable = input_variable_1 + input_variable_2 + ... + input_variable_n Attributes: input_variables (list[UUID]): The list of variable UUIDs to sum. output_variable (UUID): The UUID of the variable that stores the sum. Examples: >>> # Create a constraint: z = x + y + w >>> constraint = OXSummationEqualityConstraint( ... input_variables=[x.id, y.id, w.id], ... output_variable=z.id ... ) Note: While this could be expressed as a linear constraint, it's included as a special constraint for consistency and solver optimization. """ input_variables: list[UUID] = field(default_factory=list) output_variable: UUID = field(default_factory=UUID)
[docs] @dataclass class OXConditionalConstraint(OXSpecialConstraint): """A constraint representing conditional logic. This constraint enforces different constraints based on the value of an indicator variable. If the indicator variable is true, constraint_if_true is enforced; otherwise, constraint_if_false is enforced. Attributes: indicator_variable (UUID): The UUID of the boolean variable that determines which constraint to enforce. input_constraint (UUID): The UUID of the base constraint to evaluate. constraint_if_true (UUID): The UUID of the constraint to enforce if the indicator variable is true. constraint_if_false (UUID): The UUID of the constraint to enforce if the indicator variable is false. Examples: >>> # Create a conditional constraint: if flag then x >= 5 else x <= 3 >>> constraint = OXConditionalConstraint( ... indicator_variable=flag.id, ... input_constraint=base_constraint.id, ... constraint_if_true=upper_bound_constraint.id, ... constraint_if_false=lower_bound_constraint.id ... ) Note: This constraint is used for modeling logical implications and conditional relationships in optimization problems. """ indicator_variable: UUID = field(default_factory=UUID) input_constraint: UUID = field(default_factory=UUID) constraint_if_true: UUID = field(default_factory=UUID) constraint_if_false: UUID = field(default_factory=UUID)