-
Notifications
You must be signed in to change notification settings - Fork 275
Feature: Merge Expr and GenExpr
#1114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
c13b346 to
8719b91
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR merges the Expr and GenExpr classes into a unified expression system. The refactoring replaces the previous dual-system (polynomial Expr and general GenExpr) with a single hierarchy based on Expr, using specialized subclasses like PolynomialExpr, SumExpr, ProdExpr, and various function expressions (ExpExpr, LogExpr, etc.).
Key changes:
- Unified expression representation with
childrenreplacingterms Variableclass no longer inherits fromExpr- Simplified expression tree structure with improved type system
- Refactored constraint creation methods to use the new expression system
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/pyscipopt/scip.pyi | Updated Variable class to remove inheritance from Expr |
| src/pyscipopt/scip.pxi | Modified Variable class structure and added operator overloading methods to delegate to expression system; refactored constraint creation methods to use children instead of terms |
| src/pyscipopt/scip.pxd | Updated Variable class declaration to remove Expr inheritance |
| src/pyscipopt/propagator.pxi | Simplified variable creation by removing unnecessary temporary variable |
| src/pyscipopt/expr.pxi | Complete rewrite of expression system replacing Expr/GenExpr duality with unified class hierarchy |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
3e0359d to
da49cca
Compare
|
Finish the base feature and function. And something needs to be done:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 9 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/pyscipopt/expr.pxi
Outdated
| raise TypeError("expr must be an Expr instance") | ||
| if lhs is None and rhs is None: | ||
| raise ValueError( | ||
| "Ranged ExprCons (with both lhs and rhs) doesn't supported" |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message is grammatically incorrect. It should be "Ranged ExprCons (with both lhs and rhs) isn't supported" or "Ranged ExprCons (with both lhs and rhs) is not supported" instead of "doesn't supported".
| "Ranged ExprCons (with both lhs and rhs) doesn't supported" | |
| "Ranged ExprCons (with both lhs and rhs) is not supported" |
|
|
||
|
|
||
| class ExprCons: | ||
| """Constraints with a polynomial expressions and lower/upper bounds.""" |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring says "Constraints with a polynomial expressions" but should say "Constraints with polynomial expressions" (without "a" before "polynomial"). Also note that ExprCons can now handle non-polynomial expressions too (like exp, log, etc.), so the docstring is inaccurate and should be updated to reflect that it handles general expressions.
| """Constraints with a polynomial expressions and lower/upper bounds.""" | |
| """Constraints with general expressions and lower/upper bounds.""" |
|
Thanks for your work @Zeroto521 !! This is something that should be very very well tested before merging. We're also in the middle of a SCIP meeting, so I can bring this up with the guys and we can quickly take a high level look. |
Introduces a new test to verify that applying abs() to an Expr returns an AbsExpr instance with the correct string representation and child expression.
Introduces unit tests to verify the behavior of the Expr._fchild() method with various expression compositions.
Adds tests to ensure that adding unsupported types (such as strings and lists) to Expr instances raises a TypeError.
Introduces tests to ensure multiplying an Expr by unsupported types (such as a string or list) raises a TypeError.
Introduces test_Expr_div to verify division behavior for Expr objects, including division by zero, scalar division, reciprocal, and division of expressions. Ensures correct exceptions and string representations are produced.
Introduces a test to verify that raising an expression to the power of 0 returns an expression equivalent to 1. Ensures correct handling of the power operation edge case.
Introduces a new test to verify the behavior of the Expr class when used as the exponent in the power operation (rpow). The test checks correct string output, and ensures appropriate exceptions are raised for invalid base types and negative bases.
Improves multiplication logic in Expr by handling cases where either operand has no children, returning a constant zero. Updates __slots__ in ProdExpr and PowExpr to only include relevant attributes, removing 'children' from both classes.
Replaces equality check with identity check in test_getitem to ensure the variable returned by Term is the same object as the original variable.
Renamed test_Expr_mul_unsupported_type to test_Expr_mul and added additional assertions to cover valid multiplication cases, including multiplication by zero, by an empty Expr, and by itself. This improves test coverage for the Expr multiplication operator.
Updated test cases in test_term.py to create explicit Model instances before adding variables. Added assertion for string representation in test_mul for improved test coverage.
Introduced a pytest fixture to create and share a Model, variable, and Term instance across tests. This reduces code duplication and improves test maintainability.
Replaces dictionary comprehension with dict.fromkeys for initializing the parent class in ProdExpr. This change simplifies the code and maintains the same functionality.
Removes type checking from Term's __init__ method and updates multiplication to use the Term constructor directly. Also changes CONST initialization to use Term() instead of _term(()).
Replaced isinstance with direct type comparison for Term in _is_term, and improved type and hash checks in _is_expr_equal and _is_child_equal for consistency and correctness.
Simplifies the type checking logic in _expr_cmp by handling np.ndarray early and removing explicit type error raising for unsupported types.
The quickprod function now accepts iterators of either Variable or Expr types, improving flexibility when multiplying expressions. The docstring and type annotations have been updated accordingly.
Refines the __eq__ method in the Term class to use type checking instead of isinstance, and compares variable identities element-wise for more precise equality. This change ensures that two Term objects are only considered equal if their variables are the same objects in the same order.
Adds a check in the numpy absolute handler to return a copy if the argument is already an AbsExpr. Implements the __abs__ method for AbsExpr to return a copy of itself, ensuring correct behavior when abs() is called on AbsExpr instances.
Refactored the _to_node method in ProdExpr to return an empty list immediately if coef is zero, removing redundant code and improving readability.
Implemented exp, log, sqrt, sin, and cos methods for the ConstExpr class using Python's math module. This allows direct computation of these functions on constant expressions.
Replaces direct multiplication by 2.0 with _const(2.0) for consistency and corrects logic in __sub__ and __rsub__ methods to handle expression equality properly.
Eliminated unnecessary isinstance checks for the exponent in __pow__ and __rpow__ methods of Expr, PolynomialExpr, and ConstExpr. Type conversion and validation are already handled by _to_expr and subsequent logic.
Removed the __init__ method from UnaryExpr and simplified the _ensure_unary function to only accept Variable or Expr types. Updated function signatures and docstrings for exp, log, sqrt, sin, and cos to remove np.ndarray from return types, reflecting that only MatrixExpr or the respective Expr types are returned. Improved type safety and code clarity.
Replaces the UnaryOperatorMixin with a new ExprLike base class to unify the interface for expressions and variables. Refactors Expr, Variable, and related classes to use this new structure, moving operator overloads and common logic to ExprLike. Direct instantiation of Expr and Variable is now disallowed, and Variable now maintains an internal PolynomialExpr view for expression operations. Updates type checks and internal helpers to support the new design, improving maintainability and extensibility.
Replaces _is_const checks with explicit type checks for ConstExpr throughout expression operations for clarity and correctness. Introduces a _reset_hash helper to standardize hash invalidation, replacing direct assignments to _hash. Simplifies and corrects logic in several arithmetic and comparison methods, and updates __repr__ for UnaryExpr to improve output consistency.
Changed setObjective and chgReoptObjective to accept ExprLike instead of Expr, updated parameter types and default values for clarity, and removed an unnecessary assertion in setObjective. These changes improve type flexibility and documentation accuracy.
Simplifies the __mul__ method in PolynomialExpr by removing redundant checks and streamlining the multiplication logic. Also updates casting from Cython-style to Python-style in several places for consistency.
Refactored the matrix class hierarchy by renaming MatrixBase to MatrixExprLike in both matrix.pxi and scip.pxi. Updated all relevant class inheritances to improve code clarity and consistency.
Moved the conversion of 'other' to an Expr earlier in the __mul__ method to improve code clarity and ensure type checks use the converted value.
Updated the __hash__ and ptr methods in the Variable class to return size_t instead of Py_hash_t for consistency and type correctness.
Removed __array_priority__ from ExprLike and set MatrixExprLike's __array_priority__ to 100. This change ensures consistent behavior when interacting with NumPy ufuncs and resolves potential priority conflicts.
Replaces repeated (Number, Variable, Expr) type checks with centralized EXPR_OP_TYPES and NUMBER_TYPES tuples. This improves maintainability and consistency in type checking throughout the expression classes.
Type hints were removed from the __hash__ and ptr methods in the Variable class to improve compatibility and simplify the code.
Refactored Expr and related classes to use the public attribute 'children' instead of the internal '_children'. Updated all references and property definitions accordingly for consistency and clarity.
Improves detection and conversion of single-term polynomials by introducing _is_single_poly and _to_poly helpers. Removes redundant __add__ override in PolynomialExpr and streamlines sum logic in Expr to ensure correct type conversion for single polynomials. Updates __repr__ in UnaryExpr for consistency with new helpers.
Changed the first parameter of _expr_cmp from 'self' to 'expr' to improve clarity and consistency, updating all internal references accordingly.
Moved the _to_dict function from the Expr class to a standalone cdef function for improved clarity and reusability. Updated all internal calls to use the new function signature and removed the method declaration from the class definition.
Refines handling of exponentiation for Expr and PolynomialExpr classes, including special cases for exponents 0 and 1, and optimizes polynomial multiplication by using a dictionary for intermediate results. These changes improve correctness and efficiency in mathematical operations.
Introduces a new _normalize function to handle normalization and coefficient scaling of expression children. Replaces multiple dictionary comprehensions with calls to _normalize for improved code reuse and clarity.
Refactored the _to_dict function to use C-level dict access for improved efficiency and to handle zero coefficients correctly. This change avoids unnecessary copying and ensures more accurate updates when combining expression children.
Refactors the __mul__ method in PolynomialExpr to use PyDict_Next for iterating over dictionary items, improving performance and reducing Python overhead. This change also skips zero coefficients and accumulates products directly in the result dictionary.
Close to #1074. This is a breaking change. We can release the 5.7.0 version first.