[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