Conversation
# Conflicts: # crates/huub/src/actions.rs # crates/huub/src/constraints.rs # crates/huub/src/constraints/cumulative.rs # crates/huub/src/constraints/int_abs.rs # crates/huub/src/constraints/int_div.rs # crates/huub/src/constraints/int_pow.rs # crates/huub/src/constraints/int_times.rs # crates/huub/src/flatzinc.rs # crates/huub/src/helpers/linear_transform.rs # crates/huub/src/lib.rs
Dekker1
left a comment
There was a problem hiding this comment.
I'm finally preparing the pull request for difference logic. In the difference logic component itself, there are a few points to consider:
* A few open TODOs, mostly regarding potential efficiency gains, future extension points or extra tests. * Check documentation (and level of detail) * Check logging (frequency and relevance)
Amazing work! In general, it looks great, so I'm looking forward to merging this. I'll add a full review, but I'd be happy to handle making some of the changes. Please let me know when you are happy for me to take over.
* I noticed that some of the (existing) test instances run into the debug assert that a literal used in a reason is unknown (it is known but not propagated yet). Depending on how these tests are executed, I'm not sure if this is an issue for the automated testing.
This would suggest that you are propagating in the wrong order. (The debug assert takes the order into account). Note that this would also suggest a problem for the SAT solver, since it means that the trailing order would be incorrect. The literal in the reason must be propagated before the literal that the reason implies.
* I am currently running some experiments to determine the best default parameters for the internal difference logic settings.
I'm looking forward to seeing the results. It would be great to reduce the number of options that we expose in the configuration and on the command line. For example, we haven't exposed any priority levels in the configuration before.
Further, I have introduced a few global changes to review / discuss:
* to_solver has gained an extra argument, which is the model_trail (allows access to trailed values in the model for transformation)
I think the capability that you've exposed is fine, but I might fine-tune it before we merge (or separately). Ideally, I would want to avoid having the extra argument as we fit all the other capabilities into the reformulation actions. However, this also seems like a good opportunity to investigate whether TrailedInt shouldn't be split between the Model and Solver layer, as you can currently request the value from somewhere where you didn't create it.
* In from_fzn, I have given post_constraints access to the config
I don't have a big issue with this, but it goes a little against the idea that a model is just a declaration of the decisions and constraints. Depending on what configuration options we are left with after parameter tuning, we might want to see whether this can be solved another way. Are the options relevant before we start solving?
* Using advisors at model level, I found that they might not be triggered as they were only called at the end of propagate, but the first propagation might rely on the advisors getting triggered beforehand. I separated the propagate and notify_advisors methods in Model, and added a notify_advisors call before the first propagate call. This seems to work, but please check.
I'll have a look! 👍
* I have made resolve_alias available via the SimplificationActions, as I would like to have only one node per underlying variable instead of duplicates for aliases.
This seems okay to me.
* I have introduced assert_num_solutions to combine a solution checker with a solution count (as I sometimes had bugs where all returned solutions were correct, but not all correct solutions were returned).
I'm not sure whether this is required. Are there that many solutions that expect_solutions doesn't work?
I've added some initial comments, but I probably need to inspect a little closer when I have some time. (That might take me a little while).
| /// Whether the vivification heuristic is enabled | ||
| vivification: bool, | ||
|
|
||
| /// Difference logic mode. |
There was a problem hiding this comment.
If we keep these options, then I would prefer to create descriptive enum types for their values, rather than using u8.
There was a problem hiding this comment.
Yes, we can reduce parameter options and make their values more explicit once we settle on the final parameters to expose or fix.
| (overwritten by --vsids-only) | ||
| --vsids-only Only use the activity-based search heuristic provided by the SAT | ||
| solver. Ignore the user-specific search heuristic. | ||
| --diff-logic Mode to use for diff logic: 0 for off, 1 (default) for global, |
There was a problem hiding this comment.
Similarly, I would prefer to use descriptive strings rather than numbers here. (Although I understand that this would be easy now for parameter tuning testing).
| } | ||
|
|
||
| /// Parse a priority level from the given integer. | ||
| fn parse_priority_level(level: u8) -> PriorityLevel { |
There was a problem hiding this comment.
Unless required for some bit-fiddling. We should probably never store a PriorityLevel as a u8.
| IntDecision: ModelIntView<E>, | ||
| BoolDecision: ModelBoolView<E>, | ||
| { | ||
| trace!("Starting Johnson's"); |
There was a problem hiding this comment.
Instead of "start" and "stop" trace statements, this should use the span capability of tracing.
Thanks. I will have another look through my TODOs, documentation, logging, and some of the issues you mentioned, but feel free to start working on changes you would like to do, especially regarding the other solver parts that I touched. Our working times will not have a lot of overlap anyway.
I think the main thing is that I collect all relevant constraints if difference logic is active, otherwise they are individually posted to the solver (so the on/off switch for difference logic as a whole)
Well I have a test with 85 solutions. Initially I just checked their validity, but during development I had bugs that cut off a few of them. I could also list all results or reduce the domains, but adding the count felt more convienent without restricting the test case. |
I looked again at this one, and I'm not really sure what goes wrong:
|
But it looked that it doesn't happen in this order. What I glance from the log, is that first, Maybe I don't really understand how this is supposed to work. What is are the literals that you're requesting with |
|
Looking at the logs, my conjecture is that this is caused by an out-of-order propagation issue. In the propagation algorithm, Conceptually, the propagator “thinks” the trail (growing to the right) in the CP engine looks like: However, in the actual implementation, the bound literals implied by So the real trail in the CP engine becomes: When This unassigns As a hot fix, enabling eager explanation avoids resuming the trail in |
|
Thanks for the details. It seems unexpected to me that when I give the same reason as an eager explanation the order is fine ( Still, I can just activate eager mode in difference logic (this was one of the options for the experiments anyway). It also didn't seem to cause any follow-up issues when running in release mode where the assert is not triggered. |
|
Okay, I now understand the problem. These issues with the channelling between the SAT and Engine stack remain annoying. I think it's just I'll have to think about a solution. We might be able to better maintain the order, but I might have to play around a little to find a solution that is performant. |
# Conflicts: # crates/huub/src/actions.rs # crates/huub/src/constraints.rs # crates/huub/src/constraints/bool_array_element.rs # crates/huub/src/constraints/cumulative.rs # crates/huub/src/constraints/disjunctive.rs # crates/huub/src/constraints/int_abs.rs # crates/huub/src/constraints/int_array_element.rs # crates/huub/src/constraints/int_array_minimum.rs # crates/huub/src/constraints/int_div.rs # crates/huub/src/constraints/int_linear.rs # crates/huub/src/constraints/int_pow.rs # crates/huub/src/constraints/int_set_contains.rs # crates/huub/src/constraints/int_table.rs # crates/huub/src/constraints/int_times.rs # crates/huub/src/constraints/int_unique.rs # crates/huub/src/constraints/int_value_precede.rs # crates/huub/src/helpers.rs # crates/huub/src/lib.rs # crates/huub/src/model/deserialize/flatzinc.rs # crates/huub/src/reformulate.rs # crates/huub/src/solver.rs
I'm finally preparing the pull request for difference logic. In the difference logic component itself, there are a few points to consider:
Further, I have introduced a few global changes to review / discuss: