feat: Semantic Minimisation during Conflict Analysis - #406
feat: Semantic Minimisation during Conflict Analysis#406ImkoMarijnissen wants to merge 103 commits into
Conversation
… in semantic minimiser
This reverts commit b99b962.
…ciates preivous level
| reason_buffer: Default::default(), | ||
| lbd_helper: Default::default(), | ||
| recursive_minimiser: Default::default(), | ||
| semantic_minimiser: Default::default(), |
There was a problem hiding this comment.
Do we still need semantic minimisation if we have this?
There was a problem hiding this comment.
After adding some additional checks, I think that they are only used to merge and unmerge the disequalities. We can do this manually, what do you think?
There was a problem hiding this comment.
I think that would be better. Now it is a bit confusing why we would have both
There was a problem hiding this comment.
I have implemented this, but I am not sure whether this is exactly clearer, since it is quite a lot of case differentiation...
…additional cleanup
maartenflippo
left a comment
There was a problem hiding this comment.
I still have some minor comments, but overall looks good enough to merge if we have exhausted the good will to work on this feature.
| /// Returns true if the provided [`Predicate`] was redundant and false otherwise. | ||
| /// | ||
| /// Note that this method also adjusts internal data structures | ||
| pub(crate) fn is_redundant( |
There was a problem hiding this comment.
I think this can just be private?
| /// [`AnalysisMode::should_continue_resolving`] returned false (e.g., when finding the 1UIP, the | ||
| /// `to_process_heap` will contain the asserting predicate) and returns the number of | ||
| /// elements which were left in the `to_process_heap`. |
There was a problem hiding this comment.
to_process_heap is unknown in this context now
| while working_nogood.num_current_checkpoint() > 0 { | ||
| let predicate = working_nogood.pop_max_predicate(predicate_id_generator, *self); | ||
|
|
||
| pumpkin_assert_eq_simple!( | ||
| previous_predicate.unwrap_or(predicate).get_domain(), | ||
| predicate.get_domain() | ||
| ); | ||
| previous_predicate = Some(predicate); | ||
|
|
||
| working_nogood.add_asserting_predicate( | ||
| predicate, | ||
| context, | ||
| predicate_id_generator, | ||
| *self, | ||
| ); | ||
| pumpkin_assert_simple!(predicate.get_domain() == propagating_domain); | ||
| processed_nogood_predicates.push(predicate); | ||
| } | ||
| } |
There was a problem hiding this comment.
It feels like this logic should also be encapsulated in the drain_predicates function. At this point in the interface of WorkingNogood it is not clear what the difference is between add_asserting_predicate and add_predicate. I get the impression this is still an artifact from before this abstraction, but perhaps I am wrong.
There was a problem hiding this comment.
I have moved this method to be part of the drain_predicates function; this also makes the add_asserting_predicate a private function. The main difference with other methods is that it does not perform a redundancy check for asserting predicates.
Closes #397.
After discussing with @maartenflippo, I implemented a very simple implementation of the
conjoinfunction from "Semantic Learning for Lazy Clause Generation - Feydy et al.".Some anecdotal examples of the effect:
For an RCPSP instance (
01.dzn), the number of failures goes from 3,711 to 3,376 and for another instance (J120_60_5), the number of failures to get to a solution of 108 is reduced from 28,303 to 27,855. Forfoxgeesecorn, the number of failures to get to an objective of 32 goes from 114,811 to 81,268.There are a few things which are not entirely clear to me:
conjoinfunction is underspecified, and it is somewhat unclear what exactly it does; for now, we assume that the elements in the working nogood are in the left side of the rewrite rules, and the added propagation reasons are on the right side of the rewrite rules. It was unclear to us what the reason for this is, but it appears to create incorrect nogoods otherwise.TODOs
Experimentation
Overall Results
mainnewmain-freenew-freemain-no-recursivenew-no-recursiveMiniZinc Score
Average Primal Integral