-
Notifications
You must be signed in to change notification settings - Fork 33
Rc2 maxsat solver #729
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?
Rc2 maxsat solver #729
Conversation
hbierlee
left a comment
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.
Ok, looks good to me!
The transform_objective should become part of the int2bool encode_expr (as it just encodes a linear sum, which is implemented that as part of encoding a linear constraint). This can wait until we need it for other optimization-compatible Boolean solvers.
|
as discussed in the meeting, more important than the above review questions, is that we should consider whether we can add RC2 as a subsolver? Just from a user perspective, should "Pysat" and "RC2" seen side by side, or RC2 as part/subsolver of Pysat? If subsolver, I can try to refactor that. If not, probably I can still remove some duplication by perhaps subclassing. |
|
Currently working on this, my idea is:
|
|
@tias since you made the original draft, could you review? Two executive decisions are needed:
|
|
I've added a PR for the missing interrupt feature (required for timeouts) in RC2 pysathq/pysat#211. As above, the question is whether we wait for that to merge this PR, or if we merge RC2 w/o time limits |
|
Seems good to wait for the upstream PR, since the release is not imminent. On the other hand, one outstanding TODO is supporting atmost constraints. Working on that now. |
|
Ready for review! I've added native support for AtMostK constraints for RC2 (in case the solver supports it - otherwise these AtMostK are encoded in One other (arguable) change is that I replaced the RC2 solver arguments which are added explicitly in One side note is that RC2 does not allow the user currently to pass arguments for its oracle sub-solver. That might be worth an issue. For instance, currently, even though Cadical has native AtMostK support, we cannot actually enable it when using RC2. This might be worth a PySAT issue. |
|
Currently, two small issues preventing merge when implementing timeouts:
|
tias
left a comment
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 native handling seems to create technical debt, not a fan... to discuss
| atmosts = [] | ||
| if isinstance(cnf, list): | ||
| clauses = cnf | ||
| elif isinstance(cnf, tuple): |
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.
euh... what?
so somebody will use 'append_formula' somewhere, and it will give it a tuple, and they will know what this tuple should be, and elsewhere we should know that any tuples is an atmost?
this is is too implicit...
in pysat itself we do not support native atmostk? then I find it weird that we hack it in here, and especially in this way...
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 reason that it's more complicated here with the overriding of
append_formulais that we collect the encoding in WCNFPlus and then instantiate the solver insolvefrom the WCNFPlus. This is so that we can give the solver args there as in most solvers (Exact being the only exception). The implementation may be simplified if we do require the RC2 solve args to be given to init so we don't have thisWCNFPlusin-between. - in pysat, we do support native atmost k's (https://github.com/CPMpy/cpmpy/blob/master/cpmpy/solvers/pysat.py#L547)
- Side note: nobody is supposed to use
append_formula, it's a method of a "private" field (although I suppose they could get it through thenative_model).
| if time_limit is not None: | ||
| raise NotImplementedError("CPM_rc2: time limit not yet supported") | ||
|
|
||
| # hack to support decision problems |
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.
I don't think we should? we can just raise that the solver is not for that?
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.
I'm also fine with that, it just seemed a very easy extension + allows us to more easily test RC2
|
|
||
| # determine subsolver | ||
| default_kwargs = {"solver": "glucose3", "adapt": True, "exhaust": True, "minz": True} | ||
| stratified = kwargs.get("stratified", True) |
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.
why handle stratified differently? Can just be in default_kwargs as true too?
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.
Because stratified is not an RC2 argument, you use it by using the different class. I can add it to default_kwargs, but then I need to remove it again when I pass the args to compute
cpmpy/solvers/rc2.py
Outdated
| if sub_solver and not Solver(name=sub_solver).supports_atmost(): | ||
| # encode AtMostK constraints since they are unsupported by sub-solver oracle | ||
| atmosts = self.pysat_solver.atms | ||
| self.pysat_solver.__class__ = WCNF |
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.
a line like this is black magic and to be avoided
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.
yeah.. there's no official way to convert WCNFPlus to WCNF, and this avoids copying. I've made a change which avoids the downclass though.
|
Small comments are resolved, I think there are two knots to cut:
|
|
Fixed the new failing test, and have a pretty good workaround for the time limit issue. [edit; the workaround is the intended method] I think all that remains are the two points above, if @tias can decide between the options then this PR should still be made mergeable in pretty short order. The CI is taking a bit long recently, not sure why (although adding RC2 as another solver probably doesn't help of course). [edit: seems that's just 8 more minutes from adding RC2] |
|
@tias I still can't add you as reviewer since you're the author of the PR, but if you could make some executive decisions on #729 (comment), and have a look at whatever comments are unresolved, then that'd be great |
this needs more extensive testing...
(but its small test-case works)
also, there was a tricky aspect of using direct encoding (with weight 0 literals) in the objective... henk could you have a look?