[jboss-jira] [JBoss JIRA] (JBRULES-3719) Broken accumulate function - possible WM corruption
Geoffrey De Smet (JIRA)
jira-events at lists.jboss.org
Mon Jan 21 08:52:22 EST 2013
[ https://issues.jboss.org/browse/JBRULES-3719?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Geoffrey De Smet moved PLANNER-8 to JBRULES-3719:
-------------------------------------------------
Project: JBRULES (was: OptaPlanner)
Key: JBRULES-3719 (was: PLANNER-8)
Component/s: (was: optaplanner-core)
(was: optaplanner-benchmark)
Security: Public
Fix Version/s: 5.4.0.Final
(was: 5.4.0.Final)
> Broken accumulate function - possible WM corruption
> ---------------------------------------------------
>
> Key: JBRULES-3719
> URL: https://issues.jboss.org/browse/JBRULES-3719
> Project: JBRULES
> Issue Type: Bug
> Security Level: Public(Everyone can see)
> Environment: Linux x86_64, Oracle JDK 7
> Reporter: Martin Vecera
> Assignee: Geoffrey De Smet
> Priority: Critical
> Fix For: 5.4.0.Final
>
> Attachments: Drooling-Tournaments-bug.tar.gz
>
>
> Using Drools Planner, I created a planning solution for planning matches on tournaments. When I created a score calculating rule using the accumulate function, I realized that it behaves very strange. This is possibly because of Working Memory corruption. I think so, because I need to performa several changes in WM to recreate the problem. When I use only the last state of WM and put it in a freshly instantiated WM, it works fine.
> Attached is an reproducer application. You can just unzip and run 'mvn test'. The test does not fail, but you can see the corruption in its output.
> First, I would like to describe the solution. There are the following entities - Team, Group (a group of teams, usually only teams in the same group play together), Court, Match (between teams), and Slot (Slot connects a numbered time slot on a particular Court). A Match can be assigned to a Slot to denote which teams are supposed to play a match at the given court in the given time.
> All of the teams, groups, courts, and maches appear in the WM at the beginning. Planner then adds slots and tries to assign Matches to the slots.
> The test executed by 'mvn test', fills a WM with specific facts. Then it adds a Slot with some assignment and fires all rules. After that, different match is assigned to the slot and all rules are fired again. The last step is repeated several times.
> The problematic rule is the following one:
> {noformat}
> rule "Get overhead per team"
> when
> $t: Team()
> accumulate(
> $s: Slot($num: number, match != null, $ts: teams, teams contains $t),
> $min: min($num),
> $max: max($num),
> $slist: collectList($s),
> $sset: collectSet($s),
> $tslist: collectList($ts), // this collects all team sets, each set
> $count: count($s)
> )
> then
> System.out.println("= START = rule Get overhead per team");
> System.out.println("Working with team " + $t.toString() + ", it must appear in each subset of the following set: " + Arrays.toString($tslist.toArray()));
> System.out.println("The same team must appear in the match associated with each of the following slots:");
> System.out.println(Arrays.toString($slist.toArray()));
> System.out.println("Each slot should be considered only once, we should not have duplicates in the previous list.");
> System.out.println("= END = rule Get overhead per team");
> // ((max - min + 1) / min_slots_per_match) - count
> insertLogical(
> new IntConstraintOccurrence("teamOverhead", ConstraintType.NEGATIVE_SOFT,
> $sset.size() < 2 ? 0 :
> Math.max(0, (($max.intValue() - $min.intValue() + 1) / 2 - $sset.size())), $t, $slist)
> );
> end
> {noformat}
> Its main goal is for each team to collect all slots that has a match assigned in which this team has to play (Slot -> Match -> Teams_in_match contains Team).
> Some data is collected for each Slot - most of these are just to show the bug. As you can see, only Slots that fulfills the condition 'teams contains $t' can be taken into account.
> $ts refers to the set teams in this Slot. A list of these sets is collected ($tslist). On the RHS, this rule contains some debug output. It mainly prints out the team ($t) and the list of team sets (list of all $ts). According to the rule condition, each set in $tslist must contain the team $t. However, this is not true as you can see from the test output after 4th rules firing:
> {noformat}
> = START = rule Get overhead per team
> Working with team Team X0, it must appear in each subset of the following set: [[Team X1, Team X2]]
> The same team must appear in the match associated with each of the following slots:
> [Slot [Court A, 0, match=Match [teamsInMatch=[Team X1, Team X2]]]]
> Each slot should be considered only once, we should not have duplicates in the previous list.
> = END = rule Get overhead per team
> {noformat}
> Team X0 does not appear in [Team X1, Team X2]. Because of that, wrong Slots are taken into account and the rule breaks the score.
> Another problem is that the list of collected slots ($slist) and the set of collected slots ($sset) differ in size. The list simply contains some duplicates and this means that some Slots were considered multiple times. This can be seen after 3nd rules firing:
> {noformat}
> = START = rule Get overhead per team
> Working with team Team X0, it must appear in each subset of the following set: [[Team X0, Team X2], [Team X0, Team X3]]
> The same team must appear in the match associated with each of the following slots:
> [Slot [Court A, 0, match=Match [teamsInMatch=[Team X0, Team X3]]], Slot [Court A, 0, match=Match [teamsInMatch=[Team X0, Team X3]]]]
> Each slot should be considered only once, we should not have duplicates in the previous list.
> = END = rule Get overhead per team
> {noformat}
> You can see the duplicate Slot in the list. I tried running equals() on them and they are equal. On the other hand, a Slot with teams X0 and X2 must have been considered because it appears in the list of $ts sets ([[Team X0, Team X2], [Team X0, Team X3]]). How is this possible? We no longer have a Slot assigned with the match between team X0 and X2.
> Each step of rules firing produces an output in the following format:
> {noformat}
> = Run no. X ============================================
> = START = rule Get overhead per team
> ...
> = END = rule Get overhead per team
> ... several executions of the rule ...
> X) ... content of WM after firing the rules...
> X) ...
> {noformat}
> In the output you can see all constraints that were created base on the WM content.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the jboss-jira
mailing list