Skip to content

Constraints Refactor 4: Introduce DiscreteLinearConstraint and Align with Conti Counterpart - #883

Draft
Scienfitz wants to merge 42 commits into
refactor/constraints/degeneracyfrom
refactor/constraints/linear
Draft

Constraints Refactor 4: Introduce DiscreteLinearConstraint and Align with Conti Counterpart#883
Scienfitz wants to merge 42 commits into
refactor/constraints/degeneracyfrom
refactor/constraints/linear

Conversation

@Scienfitz

Copy link
Copy Markdown
Collaborator

Closes #875
Based on #881

@Scienfitz Scienfitz self-assigned this Aug 5, 2026
Scienfitz and others added 28 commits August 6, 2026 11:20
DiscreteBatchConstraint._get_invalid was never reached: batch constraints
are excluded from search-space filtering, the only caller of get_invalid.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Replace DiscreteSumConstraint with DiscreteLinearConstraint using operator/rhs/
coefficients/tolerance interface that mirrors ContinuousLinearConstraint.

Rework DiscreteProductConstraint to use operator/rhs/tolerance instead of
condition, with a transitional deprecated condition field resolved in
__attrs_post_init__.

Deprecate DiscreteSumConstraint as a factory function that warns and returns
DiscreteLinearConstraint. Add serialization redirects for both legacy
DiscreteSumConstraint type and legacy DiscreteProductConstraint condition
payload.
@Scienfitz
Scienfitz force-pushed the refactor/constraints/linear branch from 5a8e668 to 46d2b91 Compare August 6, 2026 09:28
@Scienfitz
Scienfitz marked this pull request as ready for review August 7, 2026 15:21
Copilot AI lite review requested due to automatic review settings August 7, 2026 15:21
@Scienfitz
Scienfitz marked this pull request as draft August 7, 2026 15:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 continues the constraints refactor to unify discrete and continuous linear constraints behind a consistent operator/rhs/coefficients interface, while also formalizing “pruning” semantics for discrete constraints via a common DiscretePruningConstraint base and an exclude inversion flag.

Changes:

  • Introduces DiscretePruningConstraint and refactors discrete constraints to implement “matching rows” logic with centralized exclude inversion; adds/renames discrete constraint types (DiscreteFilteringConstraint, DiscreteDegeneracyConstraint, DiscreteLinearConstraint) and provides deprecation wrappers/redirects.
  • Updates search space construction and constraint application to work with pruning constraints and the renamed pruning-order constant.
  • Updates tests, Hypothesis strategies, docs, examples, and changelog to reflect the new APIs and deprecations.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/validation/test_constraint_validation.py Updates validation tests to use DiscreteLinearConstraint(operator/rhs) instead of DiscreteSumConstraint(condition=...).
tests/test_searchspace.py Updates SearchSpace tests to use the new discrete linear constraint API.
tests/test_deprecations.py Adds deprecation and legacy-deserialization coverage for renamed/merged discrete constraints.
tests/test_campaign.py Updates campaign tests to use DiscreteFilteringConstraint(exclude=True) instead of DiscreteExcludeConstraint.
tests/serialization/test_constraint_serialization.py Updates constraint roundtrip tests to new discrete constraint strategy generators and names.
tests/hypothesis_strategies/constraints.py Refactors Hypothesis strategies to generate new discrete pruning constraint types and new linear interface.
tests/hypothesis_strategies/alternative_creation/test_searchspace.py Updates alternative creation tests to use DiscreteLinearConstraint(operator/rhs).
tests/constraints/test_constraints_polars.py Updates Polars/Pandas parity tests to use DiscreteLinearConstraint and DiscreteDegeneracyConstraint.
tests/constraints/test_constraints_discrete.py Updates discrete constraint tests for the new linear interface.
tests/constraints/test_constrained_cartesian_product.py Updates constrained cartesian product scenarios and ordering constant rename.
tests/constraints/test_batch_constraint.py Updates batch-constraint tests to the new filtering constraint semantics (exclude=True).
tests/conftest.py Updates shared fixtures to new constraint names and parameters (exclude, rhs, etc.).
examples/Mixtures/slot_based.py Updates mixture example to use DiscreteDegeneracyConstraint and DiscreteLinearConstraint.
examples/Constraints_Discrete/prodsum_constraints.py Updates prodsum example to use DiscreteLinearConstraint(operator/rhs) and updated product constraint API.
examples/Constraints_Discrete/filtering_constraints.py Renames/updates the discrete filtering example to use DiscreteFilteringConstraint(exclude=True).
examples/Constraints_Continuous/hybrid_space.py Updates hybrid example to use DiscreteLinearConstraint(operator/rhs) alongside continuous constraints.
docs/concepts/getting_recommendations.md Updates docs snippet to use DiscreteFilteringConstraint(exclude=True).
docs/components/constraints.md Reworks discrete constraints docs to introduce pruning semantics and updated constraint types/names.
CHANGELOG.md Documents the new/renamed discrete constraints, pruning semantics, and deprecations.
baybe/searchspace/utils.py Refactors constraint application paths to operate on DiscretePruningConstraint and renamed order constant.
baybe/searchspace/discrete.py Updates constraint ordering logic to the renamed pruning-order list and handles unknown constraint classes.
baybe/constraints/discrete.py Implements new discrete pruning constraints, deprecation wrappers, and legacy (de)serialization redirects.
baybe/constraints/base.py Adds DiscretePruningConstraint abstraction and centralizes exclude inversion behavior for pruning constraints.
baybe/constraints/init.py Re-exports new constraint names and the renamed pruning-order constant.
baybe/campaign.py Updates candidate toggling to accept DiscretePruningConstraint collections (instead of all DiscreteConstraint).
Suppressed comments (1)

baybe/constraints/discrete.py:73

  • DiscreteFilteringConstraint does not validate that conditions has the same length as parameters. This can silently ignore trailing parameters in the Pandas path (because zip(parameters, conditions) truncates) and can raise IndexError in the Polars path (it indexes self.parameters[k] for each condition). Enforce a 1:1 mapping to avoid inconsistent behavior.
    conditions: list[Condition] = field(validator=min_len(1))
    """List of individual conditions."""

    combiner: str = field(default="AND", validator=in_(_valid_logic_combiners))
    """Operator encoding how to combine the individual conditions."""

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Scienfitz
Scienfitz force-pushed the refactor/constraints/linear branch from 46d2b91 to 355c024 Compare August 7, 2026 15:49
@Scienfitz
Scienfitz requested a balanced review from Copilot August 7, 2026 15:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 26 out of 26 changed files in this pull request and generated no new comments.

Suppressed comments (4)

baybe/constraints/discrete.py:304

  • The new direct product-constraint interface accepts NaN or infinite tolerances because neither branch checks finiteness. Such an object is constructed successfully and then fails only when filtering builds the internal ThresholdCondition; reject non-finite values during construction.
        # Validate tolerance
        if (
            self.operator not in _valid_tolerance_operators
            and self.tolerance is not None
        ):

baybe/constraints/discrete.py:922

  • Legacy redirects are registered only for DiscretePruningConstraint, but real search-space payloads deserialize constraint fields as DiscreteConstraint (baybe/searchspace/discrete.py:103,765,810). A nested legacy type: "DiscreteSumConstraint" therefore bypasses this hook and the generic base lookup fails because that name is now a function rather than a subclass. Route DiscreteConstraint deserialization through these redirects while retaining DiscreteBatchConstraint support.
converter.register_structure_hook(
    DiscretePruningConstraint, _structure_pruning_constraint
)

baybe/constraints/discrete.py:245

  • The deprecated product interface is not backward-compatible for positional calls. Previously DiscreteProductConstraint(parameters, condition) was valid; now the condition binds to operator, whose string validator raises before __attrs_post_init__ can translate it. Preserve detection of a positional ThresholdCondition (or use a wrapper/custom initializer) so existing calls receive the promised deprecation path.
    operator: str = field(default="", validator=instance_of(str))
    """The comparison operator (e.g. ``"="``, ``">="``, ``"<"``)."""

baybe/constraints/discrete.py:192

  • This validator accepts non-finite tolerances: both NaN and infinity pass the comparisons, leaving an invalid constraint that fails only later when _build_condition() constructs a ThresholdCondition. Validate finiteness eagerly, consistent with the previous condition-based interface.

This issue also appears on line 300 of the same file.

    @tolerance.validator
    def _validate_tolerance(  # noqa: DOC101, DOC103
        self, attribute: Any, value: float | None
    ) -> None:

@Scienfitz
Scienfitz changed the base branch from main to refactor/constraints/degeneracy August 18, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unify DiscreteSum And ContinuousLinear Constraints

2 participants