[rules-users] Planner 5.3.Final - "presumedScore is corrupted" when using "update" on the rules working memory => shadow proxies problems?

Geoffrey De Smet ge0ffrey.spam at gmail.com
Wed Dec 7 03:43:55 EST 2011



Op 07-12-11 02:18, Patrik Dufresne schreef:
> I'm still experimenting with Drools Planner and I also have the exact 
> same issue :
>
>     java.lang.IllegalStateException: The presumedScore (0hard/-1soft)
>     is corrupted because it is not the realScore  (0hard/0soft).
>     Presumed workingMemory:
>       Score rule (soft-ReduceNullAssignment) has count (1) and weight
>     total (1).
>     Real workingMemory:
>     at
>     org.drools.planner.core.solution.director.DefaultSolutionDirector.assertWorkingScore(DefaultSolutionDirector.java:157)
>     at
>     org.drools.planner.core.solver.DefaultSolverScope.assertWorkingScore(DefaultSolverScope.java:105)
>     at
>     org.drools.planner.core.phase.AbstractSolverPhaseScope.assertWorkingScore(AbstractSolverPhaseScope.java:132)
>     at
>     org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:69)
>     at
>     org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:166)
>     at
>     org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:138)
>     ...
>
> I've read this (https://issues.jboss.org/browse/JBRULES-3301), but it 
> didn't help :
>
>     * I'm using IntConstraintOccurrence
>     * I double check the soft constraint named
>       "soft-ReduceNullAssignment" -- it's include all the cause.
>     * I'm using Drools 5.3
>
> After more digging, I think something is missing in 
> DefaultSolutionDirector.java:153. The facts are added, but the 
> planningEntity are not added.
They are added:

          for (Object fact : getWorkingFacts()) {
             tmpWorkingMemory.insert(fact);
         }

     public Collection<Object> getWorkingFacts() {
         return solutionDescriptor.getAllFacts(workingSolution); // 
returns the problem facts + the initiliazed planningEntity's
     }

> So when the score calculation is running, there is two different 
> result. I'v place a breakpoint at DefaultSolutionDirector.java:157 and 
> looking 
> in tmpWorkingMemory->defaultEntryPoint->objectStore->identifyMap->table, 
> I don't see the planningEntity.
That's weird.

Could you try this with the latest drools-planner-core 5.4.0.SNAPSHOT 
from the jboss nexus repository too?
You'll have to branch and upgrade your local code:
    
https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-distribution/src/main/assembly/filtered-resources/UpgradeFromPreviousVersionRecipe.txt

As a side affect, you'll notice that the exception message will be much 
much clearer too, which will help in discovering the problem.
>
> Here is the my rule :
>
>     rule "soft-ReduceNullAssignment"
>     when
>     $planif : PlanifEventAssignment( employee == null )
>     then
>             insertLogical(new
>     IntConstraintOccurrence("soft-ReduceNullAssignment",
>     ConstraintType.NEGATIVE_SOFT,
>                     1,
>                     $planif));
>     end
>
>
> Thanks
>
> On Tue, Dec 6, 2011 at 11:12 AM, Geoffrey De Smet 
> <ge0ffrey.spam at gmail.com <mailto:ge0ffrey.spam at gmail.com>> wrote:
>
>
>
>     Op 06-12-11 05:38, guyramirez schreef:
>     > Still the same issue, starting with the construction heuristic
>     phase. Please
>     > let me know if you need more explanations in what I am trying to do.
>     >
>     > Here is the error. Please note that there is only one planning
>     entity
>     > (ShiftAssignment) object instance in this test.
>     >
>     > Total Staffing required: 8
>     > 2011-12-05 22:21:49,627 [main] INFO  Solver started: time spend
>     (0), score
>     > (null), new best score (null), random seed (0).
>     > ShiftAssignment: emp. id: 10 [st: 100, dur: 3]
>     > ShiftAssignment: emp. id: 10 [st: 100, dur: 2]
>     > ShiftAssignment: emp. id: 10 [st: 100, dur: 4]
>     > ShiftAssignment: emp. id: 10 [st: 100, dur: 1]
>     > 2011-12-05 22:21:49,678 [main] TRACE Building
>     ConstraintOccurrence summary
>     > 2011-12-05 22:21:49,678 [main] TRACE     Adding ConstraintOccurrence
>     > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
>     interval:
>     > 101, position id: 1, staffingRequired: 2, [ShiftAssignment: emp.
>     id: 10 [st:
>     > 100, dur: 1]]]=1)
>     > 2011-12-05 22:21:49,678 [main] TRACE     Adding ConstraintOccurrence
>     > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
>     interval:
>     > 103, position id: 1, staffingRequired: 2, []]=2)
>     > 2011-12-05 22:21:49,678 [main] TRACE     Adding ConstraintOccurrence
>     > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
>     interval:
>     > 102, position id: 1, staffingRequired: 2, []]=2)
>     > 2011-12-05 22:21:49,678 [main] TRACE     Adding ConstraintOccurrence
>     > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
>     interval:
>     > 100, position id: 1, staffingRequired: 2, [ShiftAssignment: emp.
>     id: 10 [st:
>     > 100, dur: 1], ShiftAssignment: emp. id: 10 [st: 100, dur: 1]]]=0)
>     > 2011-12-05 22:21:49,678 [main] TRACE Building
>     ConstraintOccurrence summary
>     > 2011-12-05 22:21:49,678 [main] TRACE     Adding ConstraintOccurrence
>     > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
>     interval:
>     > 101, position id: 1, staffingRequired: 2, []]=2)
>     > 2011-12-05 22:21:49,678 [main] TRACE     Adding ConstraintOccurrence
>     > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
>     interval:
>     > 103, position id: 1, staffingRequired: 2, []]=2)
>     > 2011-12-05 22:21:49,678 [main] TRACE     Adding ConstraintOccurrence
>     > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
>     interval:
>     > 100, position id: 1, staffingRequired: 2, [ShiftAssignment: emp.
>     id: 10 [st:
>     > 100, dur: 1]]]=1)
>     > 2011-12-05 22:21:49,678 [main] TRACE     Adding ConstraintOccurrence
>     > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
>     interval:
>     > 102, position id: 1, staffingRequired: 2, []]=2)
>     > Exception in thread "main" java.lang.IllegalStateException: The
>     > presumedScore (-5hard/-1soft) is corrupted because it is not the
>     realScore
>     > (-7hard/-1soft).
>     > Presumed workingMemory:
>     >    Score rule (intervalRequirementCovered) has count (4) and
>     weight total
>     > (5).
>     > Real workingMemory:
>     >    Score rule (intervalRequirementCovered) has count (4) and
>     weight total
>     > (7).
>     So the score rule intervalRequirementCovered is to blame.
>     >       at
>     >
>     org.drools.planner.core.solution.director.DefaultSolutionDirector.assertWorkingScore(DefaultSolutionDirector.java:157)
>     >       at
>     >
>     org.drools.planner.core.solver.DefaultSolverScope.assertWorkingScore(DefaultSolverScope.java:105)
>     >       at
>     >
>     org.drools.planner.core.phase.AbstractSolverPhaseScope.assertWorkingScore(AbstractSolverPhaseScope.java:132)
>     >       at
>     >
>     org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.decideNextStep(DefaultGreedyDecider.java:65)
>     >       at
>     >
>     org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:62)
>     >       at
>     >
>     org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:166)
>     >       at
>     >
>     org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:138)
>     >       at
>     com.lfsoscience.planner.LfsoPlannerMain.execute(LfsoPlannerMain.java:36)
>     >       at
>     com.lfsoscience.planner.LfsoPlannerMain.main(LfsoPlannerMain.java:27)
>     >
>     >
>     >
>     > The drl:
>     > rule "intervalRequirementCovered"
>     Let's take a look
>     >       when
>     >               $intervalReq : IntervalRequirement($interval :
>     interval, $position :
>     > position, $staffingRequired : staffingRequired)
>     >          $matchingShiftAssignments : ArrayList( size<=
>     $staffingRequired )
>     >                                                                
>           from collect ( ShiftAssignment(shiftStartTime<= $interval,
>     > shiftEndTime>  $interval, position == $position) )
>     I never used "from collect" in my examples yet.
>     You probably stumbled upon a "statefull memory corruption bug" in
>     drools.
>
>     First try this alternative way:
>
>            $intervalReq : IntervalRequirement($interval : interval,
>     $position : position, $staffingRequired : staffingRequired)
>             $matchingShiftAssignmentSize : Number(intValue <=
>     $staffingRequired) from accumulate(
>                 $x : ShiftAssignment(shiftStartTime <= $interval,
>     shiftEndTime > $interval, position == $position),
>                 count($x)
>             )
>
>     If that works, file a ticket in issues.jboss.org
>     <http://issues.jboss.org> for the project JBRULES
>     about "statefull working memory corruption by using collect"
>     and include that rule and - if possible - testdata how to
>     reproduce it.
>     >       then
>     >               #actions
>     >               insertLogical(new
>     IntConstraintOccurrence("intervalRequirementCovered",
>     > ConstraintType.NEGATIVE_HARD,
>     >                                       $staffingRequired -
>     $matchingShiftAssignments.size(),
>     >                                       $intervalReq,
>     $matchingShiftAssignments));
>     > end
>     > rule "hardConstraintsBroken"
>     >          salience -1 // Do the other rules first (optional, for
>     performance)
>     >      when
>     >          $hardTotal : Number() from accumulate(
>     >              IntConstraintOccurrence(constraintType ==
>     > ConstraintType.NEGATIVE_HARD, $weight : weight), sum($weight)
>     >          )
>     >      then
>     >        
>      scoreCalculator.setHardConstraintsBroken($hardTotal.intValue());
>     > end
>     > rule "softConstraintsBroken"
>     >      when
>     >          eval(true)
>     >      then
>     >          scoreCalculator.setSoftConstraintsBroken(1);
>     > end
>     >
>     >
>     >
>     > The Planning Entity:
>     >
>     > @PlanningEntity
>     > public class ShiftAssignment implements Cloneable {
>     >       private Employee employee;
>     >       private int day;
>     >       private Position position;
>     >       private TimeLengthPair timeLengthPair = null;
>     >       // Immutable object. Does not need to be cloned when
>     calling clone
>     >       private List<TimeLengthPair>
>      possibleShiftStartTimeLengthPairList;
>     >       private Set<TimeLengthPair>
>      possibleShiftStartTimeLengthPairSet;
>     >
>     >
>     >       public ShiftAssignment(Employee employee, int day,
>     Position position,
>     > Set<TimeLengthPair>  shiftStartTimeLengthPairs) {
>     >               this.employee = employee;
>     >               this.day = day;
>     >               this.position = position;
>     >               this.possibleShiftStartTimeLengthPairSet = new
>     > HashSet<TimeLengthPair>(shiftStartTimeLengthPairs);
>     >       }
>     >
>     >       public int getShiftStartTime() {
>     >               return this.timeLengthPair != null ?
>     this.timeLengthPair.getStartTime() :
>     > -1;
>     >       }
>     >
>     >       public int getShiftEndTime() {
>     >               return this.timeLengthPair != null ?
>     this.timeLengthPair.getStartTime() +
>     > this.timeLengthPair.getLength() : -1;
>     >       }
>     >
>     >       public void setShiftStartTimeLengthPair(TimeLengthPair
>     timeLengthPair) {
>     >               this.timeLengthPair = timeLengthPair;
>     >               System.out.println(this);
>     >       }
>     looks good
>     >
>     >       public void addPossibleShiftStartTimeLengthPair(TimeLengthPair
>     > timeLengthPair) {
>     >              
>     this.possibleShiftStartTimeLengthPairSet.add(timeLengthPair);
>     >               // Clear the list since the Set has changed. The
>     list will be recreated
>     > from the set when needed (see
>     getPossibleShiftStartTimeLengthPairs())
>     >               this.possibleShiftStartTimeLengthPairList = null;
>     >       }
>     this isn't called during planning I presume?
>     >       @PlanningVariable
>     >       @ValueRangeFromPlanningEntityProperty(propertyName =
>     > "possibleShiftStartTimeLengthPairs")
>     >       public TimeLengthPair getShiftStartTimeLengthPair() {
>     >               return this.timeLengthPair;
>     >       }
>     looks good
>     >       public List<TimeLengthPair>
>      getPossibleShiftStartTimeLengthPairs() {
>     >               if (this.possibleShiftStartTimeLengthPairList ==
>     null) {
>     >                       this.possibleShiftStartTimeLengthPairList
>     =  new
>     > ArrayList<TimeLengthPair>(this.possibleShiftStartTimeLengthPairSet);
>     >               }
>     >               return this.possibleShiftStartTimeLengthPairList;
>     >       }
>     >
>     >       public Employee getEmployee() {
>     >               return this.employee;
>     >       }
>     >
>     >       public int getDay() {
>     >               return this.day;
>     >       }
>     >
>     >       public Position getPosition() {
>     >               return this.position;
>     >       }
>     >
>     >       public boolean solutionEquals(Object o) {
>     >          if (this == o) {
>     >              return true;
>     >          } else if (o instanceof ShiftAssignment) {
>     >               ShiftAssignment other = (ShiftAssignment) o;
>     >              return new EqualsBuilder()
>     >                      .append(this.employee, other.employee)
>     >                      .append(this.position, other.position)
>     >                      .append(this.timeLengthPair,
>     other.timeLengthPair)
>     >                      .isEquals();
>     >          } else {
>     >              return false;
>     >          }
>     >      }
>     >
>     >       public int solutionHashCode() {
>     >               HashCodeBuilder hashCodeBuilder = new
>     HashCodeBuilder();
>     >               hashCodeBuilder.append(getClass())
>     >                  .append(this.employee)
>     >                  .append(this.position)
>     >                  .append(this.timeLengthPair);
>     >               return hashCodeBuilder.toHashCode();
>     >      }
>     >
>     >       @Override
>     >       public Object clone() throws CloneNotSupportedException {
>     >               return super.clone();
>     >       }
>     >
>     >       @Override
>     >       public String toString() {
>     >               StringBuilder sb = new StringBuilder();
>     >               sb.append("ShiftAssignment: ")
>     >                       .append("emp. id:
>     ").append(this.employee.getId())
>     >                       .append(" ")
>     >                       .append(this.timeLengthPair != null ?
>     this.timeLengthPair.toString() :
>     > "Not Initialized");
>     >               return sb.toString();
>     >       }
>     >
>     >       @Override
>     >       public int hashCode() {
>     >               return solutionHashCode();
>     > //            return super.hashCode();
>     >       }
>     >
>     >       @Override
>     >       public boolean equals(Object obj) {
>     >               return solutionEquals(obj);
>     > //            return super.equals(obj);
>     >       }
>     > }
>     >
>     >
>     > --
>     > View this message in context:
>     http://drools.46999.n3.nabble.com/Planner-5-3-Final-presumedScore-is-corrupted-when-using-update-on-the-rules-working-memory-tp3546932p3563446.html
>     > Sent from the Drools: User forum mailing list archive at Nabble.com.
>     > _______________________________________________
>     > rules-users mailing list
>     > rules-users at lists.jboss.org <mailto:rules-users at lists.jboss.org>
>     > https://lists.jboss.org/mailman/listinfo/rules-users
>     >
>
>     --
>     With kind regards,
>     Geoffrey De Smet
>
>
>     _______________________________________________
>     rules-users mailing list
>     rules-users at lists.jboss.org <mailto:rules-users at lists.jboss.org>
>     https://lists.jboss.org/mailman/listinfo/rules-users
>
>
>
>
> -- 
> Patrik Dufresne
>
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users

-- 
With kind regards,
Geoffrey De Smet

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20111207/eadea10b/attachment.html 


More information about the rules-users mailing list