-
Notifications
You must be signed in to change notification settings - Fork 5
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
Support removal of constraints #9
Comments
@funkey I think this is why we didn't originally add divisions to the quickstart guide (#56). We already set the Some options for dealing with this include:
|
MaxChildren.instantiate returning This works, by the way, because when the solver adds constraints here, it passes each member of the
that seems good to me. In terms of python types |
actually... that raises one question for me: Do you want to model In [16]: constraints = ilpy.Constraints()
In [17]: c = ilpy.Constraint()
In [18]: len(constraints)
Out[18]: 0
In [19]: constraints.add(c)
In [20]: len(constraints)
Out[20]: 1
In [21]: constraints.add(c)
In [22]: len(constraints)
Out[22]: 2 I suspect that the practical impact of that is negligible in terms of the solver... but that's the current state of things. So, inasmuch as we are reviewing |
We can see in my original comment the source of my confusion :) I thought |
Aha! Indeed! Yeah the name overloading can definitely be confusing |
Maybe we make an internal convention to never use the ilpy types without the full "ilpy.Thing" namespace? |
This actually is relevant if we are talking about removing all |
I'm not sure if there is a situation where different |
yeah, I agree we need to define "sameness" here. If the ilpy constraints are "equivalent" (for example, they both express |
let's discuss the slightly higher level of desired outcome before getting too in the weeds about how to implement it in ilpy. I have a question about:
What syntax exactly would we want here?
let's say we want to update One option is to say no in-place updating of constraints. You can only add and remove constraints, and you must remove them by pointer. This is explicit and would be very easy to implement. max_children = MaxChildren(1)
solver.add_constraints(max_children)
# then later:
solver.remove_constraints(max_children)
solver.add_constraints(MaxChildren(2)) Another option that is somewhat nice syntactically, but far more difficult to implement and wades into magical territory: solver.add_constraints(MaxChildren(1))
# then simply
solver.add_constraints(MaxChildren(2)) This could conceivably be done in at least two:
As a middle ground that doesn't require the user to retain pointers, class Solver:
def remove_constraints(self, constraints: type[Constraint] | Constraint) -> None:
"""Remove all constraints of type `constraints`, or a specific instance.""" which would be used as: solver.add_constraints(MaxChildren(1))
# then one more step in the middle:
solver.remove_constraints(MaxChildren)
# before adding
solver.add_constraints(MaxChildren(2)) thoughts @cmalinmayor , @funkey ? |
I like option 3. The other use case we had in mind was removing PinConstraints, and I can imagine retaining pointers to different PinConstraints and removing specific ones that are affiliated with specific variables, especially in an interative visualization situation. And if we have the functionality you outlined in the example, it is a short jump to:
that behind the scenes does exactly the same thing (removes all MaxChildren and adds the new one after). The update function removing all prior instances of that type might be more confusing for the PinConstraint where having more than one potentially does make sense... but for MaxParents and MaxChildren it is a very convenient wrapper. |
Useful to pin and unpin variables.
The text was updated successfully, but these errors were encountered: