During my debugging, I notice the call to getWorkingFacts() doesn&#39;t include the planning entities. To make sure, I&#39;ve run the NQueens example (that use the same construction heuristic) : the call to getWorkingFacts() include the planning entities.<div>

<br></div><div>After more debugging, I figure out the problem. The ValueRange of my PlanningEntity include &#39;null&#39;. I use null for un-assigned shift. In PlanningVariableDescriptor.java:149, the check for initialized variable return False if the value is null. Then my planning entity is wrongly identify as not initialized and the SolutionDescriptor.java:135 doesn&#39;t include it in the facts list.</div>

<div><br></div><div>So how do I fix it ?</div><div><br><div class="gmail_quote">2011/12/7 Geoffrey De Smet <span dir="ltr">&lt;<a href="mailto:ge0ffrey.spam@gmail.com" target="_blank">ge0ffrey.spam@gmail.com</a>&gt;</span><br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<u></u><div text="#000000" bgcolor="#ffffff">
    <br>
    <br>Op 07-12-11 02:18, Patrik Dufresne schreef:<div><blockquote type="cite">I&#39;m still experimenting with Drools Planner and I also
have the exact same issue :<blockquote style="margin:0pt 0pt 0pt 40px;border:medium none;padding:0px">
        <div>
          <div>
            <div>
              <div>java.lang.IllegalStateException: The presumedScore
(0hard/-1soft) is corrupted because it is not the
realScore  (0hard/0soft).</div>
            </div>
          </div>
        </div>
        <div>
          <div>
            <div>
              <div>Presumed workingMemory:</div>
            </div>
          </div>
        </div>
        <div>
          <div>
            <div>
              <div>  Score rule (soft-ReduceNullAssignment) has count
(1) and weight total (1).</div>
            </div>
          </div>
        </div>
        <div>
          <div>
            <div>
              <div>Real workingMemory:</div>
            </div>
          </div>
        </div>
        <div>
          <div>at
org.drools.planner.core.solution.director.DefaultSolutionDirector.assertWorkingScore(DefaultSolutionDirector.java:157)</div>
        </div>
        <div>
          <div>at
org.drools.planner.core.solver.DefaultSolverScope.assertWorkingScore(DefaultSolverScope.java:105)</div>
        </div>
        <div>
          <div>at
org.drools.planner.core.phase.AbstractSolverPhaseScope.assertWorkingScore(AbstractSolverPhaseScope.java:132)</div>
        </div>
        <div>
          <div>at
org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:69)</div>
        </div>
        <div>
          <div>at
org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:166)</div>
        </div>
        <div>
          <div>at
org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:138)</div>
        </div>
        <div>
          <div>
            <div>...</div>
          </div>
        </div>
        <div><br>
        </div>
      </blockquote>
      <div>I&#39;ve read this (<a href="https://issues.jboss.org/browse/JBRULES-3301" target="_blank">https://issues.jboss.org/browse/JBRULES-3301</a>),
but it didn&#39;t help :</div>
      <ul>
        <li>I&#39;m using IntConstraintOccurrence</li>
        <li>I double check the soft constraint named
&quot;soft-ReduceNullAssignment&quot; -- it&#39;s include all the cause.</li>
        <li>I&#39;m using Drools 5.3</li>
      </ul>
      <div>After more digging, I think something is missing in
DefaultSolutionDirector.java:153. The facts are added, but the
planningEntity are not added.</div>
    </blockquote></div>They are added:<br>
    <br>         for (Object fact : getWorkingFacts()) {<br>            tmpWorkingMemory.insert(fact);<br>        }<br>
    <br>    public Collection&lt;Object&gt; getWorkingFacts() {<br>        return solutionDescriptor.getAllFacts(workingSolution); //
returns the problem facts + the initiliazed planningEntity&#39;s<div><br>    }<br>
    <br>
    <blockquote type="cite">
      <div>So when the score calculation is running, there is two
different result. I&#39;v place a breakpoint
at DefaultSolutionDirector.java:157 and looking
in tmpWorkingMemory-&gt;defaultEntryPoint-&gt;objectStore-&gt;identifyMap-&gt;table,
I don&#39;t see the planningEntity.</div>
    </blockquote></div>That&#39;s weird.<br>
    <br>Could you try this with the latest drools-planner-core
5.4.0.SNAPSHOT from the jboss nexus repository too?<br>You&#39;ll have to branch and upgrade your local code:<br>  
<a href="https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-distribution/src/main/assembly/filtered-resources/UpgradeFromPreviousVersionRecipe.txt" target="_blank">https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-distribution/src/main/assembly/filtered-resources/UpgradeFromPreviousVersionRecipe.txt</a><br>



    <br>As a side affect, you&#39;ll notice that the exception message will be
much much clearer too, which will help in discovering the problem.<div><div><br>
    <blockquote type="cite">
      <div><br>
      </div>
      <div>Here is the my rule :</div>
      <blockquote style="margin:0pt 0pt 0pt 40px;border:medium none;padding:0px">
        <div>
          <div>rule &quot;soft-ReduceNullAssignment&quot;</div>
        </div>
        <div>when</div>
        <div>$planif : PlanifEventAssignment( employee == null )</div>
        <div>then</div>
        <div>
          <div>        insertLogical(new
IntConstraintOccurrence(&quot;soft-ReduceNullAssignment&quot;,</div>
        </div>
        <div>
          <div>        <span style="white-space:pre-wrap"> </span>ConstraintType.NEGATIVE_SOFT,</div>
        </div>
        <div>
          <div>                1,</div>
        </div>
        <div>
          <div>                $planif));</div>
        </div>
        <div>
          <div>end</div>
        </div>
      </blockquote>
      <div><br>
      </div>
      <div>Thanks</div>
      <div><br>
        <div class="gmail_quote">On Tue, Dec 6, 2011 at 11:12 AM,
Geoffrey De Smet <span dir="ltr">&lt;<a href="mailto:ge0ffrey.spam@gmail.com" target="_blank">ge0ffrey.spam@gmail.com</a>&gt;</span>
wrote:<br>
          <blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
            <br>Op 06-12-11 05:38, guyramirez schreef:<br>
            <div>
              <div>&gt; Still the same issue, starting with
the construction heuristic phase. Please<br>&gt; let me know if you need more explanations in what I
am trying to do.<br>&gt;<br>&gt; Here is the error. Please note that there is only
one planning entity<br>&gt; (ShiftAssignment) object instance in this test.<br>&gt;<br>&gt; Total Staffing required: 8<br>&gt; 2011-12-05 22:21:49,627 [main] INFO  Solver
started: time spend (0), score<br>&gt; (null), new best score (null), random seed (0).<br>&gt; ShiftAssignment: emp. id: 10 [st: 100, dur: 3]<br>&gt; ShiftAssignment: emp. id: 10 [st: 100, dur: 2]<br>&gt; ShiftAssignment: emp. id: 10 [st: 100, dur: 4]<br>

&gt; ShiftAssignment: emp. id: 10 [st: 100, dur: 1]<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE Building
ConstraintOccurrence summary<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE     Adding
ConstraintOccurrence<br>&gt;
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>&gt; 101, position id: 1, staffingRequired: 2,
[ShiftAssignment: emp. id: 10 [st:<br>&gt; 100, dur: 1]]]=1)<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE     Adding
ConstraintOccurrence<br>&gt;
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>&gt; 103, position id: 1, staffingRequired: 2, []]=2)<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE     Adding
ConstraintOccurrence<br>&gt;
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>&gt; 102, position id: 1, staffingRequired: 2, []]=2)<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE     Adding
ConstraintOccurrence<br>&gt;
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>&gt; 100, position id: 1, staffingRequired: 2,
[ShiftAssignment: emp. id: 10 [st:<br>&gt; 100, dur: 1], ShiftAssignment: emp. id: 10 [st:
100, dur: 1]]]=0)<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE Building
ConstraintOccurrence summary<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE     Adding
ConstraintOccurrence<br>&gt;
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>&gt; 101, position id: 1, staffingRequired: 2, []]=2)<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE     Adding
ConstraintOccurrence<br>&gt;
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>&gt; 103, position id: 1, staffingRequired: 2, []]=2)<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE     Adding
ConstraintOccurrence<br>&gt;
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>&gt; 100, position id: 1, staffingRequired: 2,
[ShiftAssignment: emp. id: 10 [st:<br>&gt; 100, dur: 1]]]=1)<br>&gt; 2011-12-05 22:21:49,678 [main] TRACE     Adding
ConstraintOccurrence<br>&gt;
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>&gt; 102, position id: 1, staffingRequired: 2, []]=2)<br>&gt; Exception in thread &quot;main&quot;
java.lang.IllegalStateException: The<br>&gt; presumedScore (-5hard/-1soft) is corrupted because
it is not the realScore<br>&gt; (-7hard/-1soft).<br>&gt; Presumed workingMemory:<br>&gt;    Score rule (intervalRequirementCovered) has
count (4) and weight total<br>&gt; (5).<br>&gt; Real workingMemory:<br>&gt;    Score rule (intervalRequirementCovered) has
count (4) and weight total<br>&gt; (7).<br>
              </div>
            </div>So the score rule intervalRequirementCovered is to blame.<br>
            <div>&gt;       at<br>&gt;
org.drools.planner.core.solution.director.DefaultSolutionDirector.assertWorkingScore(DefaultSolutionDirector.java:157)<br>&gt;       at<br>&gt;
org.drools.planner.core.solver.DefaultSolverScope.assertWorkingScore(DefaultSolverScope.java:105)<br>&gt;       at<br>&gt;
org.drools.planner.core.phase.AbstractSolverPhaseScope.assertWorkingScore(AbstractSolverPhaseScope.java:132)<br>&gt;       at<br>&gt;
org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.decideNextStep(DefaultGreedyDecider.java:65)<br>&gt;       at<br>&gt;
org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:62)<br>&gt;       at<br>&gt;
org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:166)<br>&gt;       at<br>&gt;
org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:138)<br>&gt;       at
com.lfsoscience.planner.LfsoPlannerMain.execute(LfsoPlannerMain.java:36)<br>&gt;       at
com.lfsoscience.planner.LfsoPlannerMain.main(LfsoPlannerMain.java:27)<br>&gt;<br>&gt;<br>&gt;<br>&gt; The drl:<br>&gt; rule &quot;intervalRequirementCovered&quot;<br>
            </div>Let&#39;s take a look<br>
            <div>&gt;       when<br>&gt;               $intervalReq :
IntervalRequirement($interval : interval, $position :<br>&gt; position, $staffingRequired : staffingRequired)<br>&gt;          $matchingShiftAssignments : ArrayList(
size&lt;= $staffingRequired )<br>&gt;                                                      
                from collect (
ShiftAssignment(shiftStartTime&lt;= $interval,<br>&gt; shiftEndTime&gt;  $interval, position == $position) )<br>
            </div>I never used &quot;from collect&quot; in my examples yet.<br>You probably stumbled upon a &quot;statefull memory corruption
bug&quot; in drools.<br>
            <br>First try this alternative way:<br>
            <div><br>       $intervalReq : IntervalRequirement($interval :
interval,<br>$position : position, $staffingRequired :
staffingRequired)<br>
            </div>        $matchingShiftAssignmentSize : Number(intValue &lt;=<br>$staffingRequired) from accumulate(<br>            $x : ShiftAssignment(shiftStartTime &lt;=
$interval,<br>shiftEndTime &gt; $interval, position == $position),<br>            count($x)<br>        )<br>
            <br>If that works, file a ticket in <a href="http://issues.jboss.org" target="_blank">issues.jboss.org</a>
for the project JBRULES<br>about &quot;statefull working memory corruption by using collect&quot;<br>and include that rule and - if possible - testdata how to
reproduce it.<br>
            <div>
              <div>&gt;       then<br>&gt;               #actions<br>&gt;               insertLogical(new
IntConstraintOccurrence(&quot;intervalRequirementCovered&quot;,<br>&gt; ConstraintType.NEGATIVE_HARD,<br>&gt;                                      
$staffingRequired - $matchingShiftAssignments.size(),<br>&gt;                                       $intervalReq,
$matchingShiftAssignments));<br>&gt; end<br>&gt; rule &quot;hardConstraintsBroken&quot;<br>&gt;          salience -1 // Do the other rules first
(optional, for performance)<br>&gt;      when<br>&gt;          $hardTotal : Number() from accumulate(<br>&gt;              IntConstraintOccurrence(constraintType
==<br>&gt; ConstraintType.NEGATIVE_HARD, $weight : weight),
sum($weight)<br>&gt;          )<br>&gt;      then<br>&gt;        
 scoreCalculator.setHardConstraintsBroken($hardTotal.intValue());<br>&gt; end<br>&gt; rule &quot;softConstraintsBroken&quot;<br>&gt;      when<br>&gt;          eval(true)<br>&gt;      then<br>&gt;        
 scoreCalculator.setSoftConstraintsBroken(1);<br>&gt; end<br>&gt;<br>&gt;<br>&gt;<br>&gt; The Planning Entity:<br>&gt;<br>&gt; @PlanningEntity<br>&gt; public class ShiftAssignment implements Cloneable {<br>&gt;       private Employee employee;<br>

&gt;       private int day;<br>&gt;       private Position position;<br>&gt;       private TimeLengthPair timeLengthPair = null;<br>&gt;       // Immutable object. Does not need to be
cloned when calling clone<br>&gt;       private List&lt;TimeLengthPair&gt;
 possibleShiftStartTimeLengthPairList;<br>&gt;       private Set&lt;TimeLengthPair&gt;
 possibleShiftStartTimeLengthPairSet;<br>&gt;<br>&gt;<br>&gt;       public ShiftAssignment(Employee employee, int
day, Position position,<br>&gt; Set&lt;TimeLengthPair&gt;
 shiftStartTimeLengthPairs) {<br>&gt;               this.employee = employee;<br>&gt;               this.day = day;<br>&gt;               this.position = position;<br>&gt;              
this.possibleShiftStartTimeLengthPairSet = new<br>&gt;
HashSet&lt;TimeLengthPair&gt;(shiftStartTimeLengthPairs);<br>&gt;       }<br>&gt;<br>&gt;       public int getShiftStartTime() {<br>&gt;               return this.timeLengthPair != null ?
this.timeLengthPair.getStartTime() :<br>&gt; -1;<br>&gt;       }<br>&gt;<br>&gt;       public int getShiftEndTime() {<br>&gt;               return this.timeLengthPair != null ?
this.timeLengthPair.getStartTime() +<br>&gt; this.timeLengthPair.getLength() : -1;<br>&gt;       }<br>&gt;<br>&gt;       public void
setShiftStartTimeLengthPair(TimeLengthPair
timeLengthPair) {<br>&gt;               this.timeLengthPair = timeLengthPair;<br>&gt;               System.out.println(this);<br>&gt;       }<br>
              </div>
            </div>looks good<br>
            <div>&gt;<br>&gt;       public void
addPossibleShiftStartTimeLengthPair(TimeLengthPair<br>&gt; timeLengthPair) {<br>&gt;              
this.possibleShiftStartTimeLengthPairSet.add(timeLengthPair);<br>&gt;               // Clear the list since the Set has
changed. The list will be recreated<br>&gt; from the set when needed (see
getPossibleShiftStartTimeLengthPairs())<br>&gt;              
this.possibleShiftStartTimeLengthPairList = null;<br>&gt;       }<br>
            </div>this isn&#39;t called during planning I presume?<br>
            <div>&gt;       @PlanningVariable<br>&gt;      
@ValueRangeFromPlanningEntityProperty(propertyName =<br>&gt; &quot;possibleShiftStartTimeLengthPairs&quot;)<br>&gt;       public TimeLengthPair
getShiftStartTimeLengthPair() {<br>&gt;               return this.timeLengthPair;<br>&gt;       }<br>
            </div>looks good<br>
            <div>
              <div>&gt;       public
List&lt;TimeLengthPair&gt;
 getPossibleShiftStartTimeLengthPairs() {<br>&gt;               if
(this.possibleShiftStartTimeLengthPairList == null) {<br>&gt;                      
this.possibleShiftStartTimeLengthPairList =  new<br>&gt;
ArrayList&lt;TimeLengthPair&gt;(this.possibleShiftStartTimeLengthPairSet);<br>&gt;               }<br>&gt;               return
this.possibleShiftStartTimeLengthPairList;<br>&gt;       }<br>&gt;<br>&gt;       public Employee getEmployee() {<br>&gt;               return this.employee;<br>&gt;       }<br>&gt;<br>&gt;       public int getDay() {<br>

&gt;               return this.day;<br>&gt;       }<br>&gt;<br>&gt;       public Position getPosition() {<br>&gt;               return this.position;<br>&gt;       }<br>&gt;<br>&gt;       public boolean solutionEquals(Object o) {<br>

&gt;          if (this == o) {<br>&gt;              return true;<br>&gt;          } else if (o instanceof ShiftAssignment) {<br>&gt;               ShiftAssignment other =
(ShiftAssignment) o;<br>&gt;              return new EqualsBuilder()<br>&gt;                      .append(this.employee,
other.employee)<br>&gt;                      .append(this.position,
other.position)<br>&gt;                      .append(this.timeLengthPair,
other.timeLengthPair)<br>&gt;                      .isEquals();<br>&gt;          } else {<br>&gt;              return false;<br>&gt;          }<br>&gt;      }<br>&gt;<br>&gt;       public int solutionHashCode() {<br>&gt;               HashCodeBuilder hashCodeBuilder = new
HashCodeBuilder();<br>&gt;               hashCodeBuilder.append(getClass())<br>&gt;                  .append(this.employee)<br>&gt;                  .append(this.position)<br>&gt;                  .append(this.timeLengthPair);<br>

&gt;               return hashCodeBuilder.toHashCode();<br>&gt;      }<br>&gt;<br>&gt;       @Override<br>&gt;       public Object clone() throws
CloneNotSupportedException {<br>&gt;               return super.clone();<br>&gt;       }<br>&gt;<br>&gt;       @Override<br>&gt;       public String toString() {<br>&gt;               StringBuilder sb = new
StringBuilder();<br>&gt;               sb.append(&quot;ShiftAssignment: &quot;)<br>&gt;                       .append(&quot;emp. id:
&quot;).append(this.employee.getId())<br>&gt;                       .append(&quot; &quot;)<br>&gt;                       .append(this.timeLengthPair
!= null ? this.timeLengthPair.toString() :<br>&gt; &quot;Not Initialized&quot;);<br>&gt;               return sb.toString();<br>&gt;       }<br>&gt;<br>&gt;       @Override<br>&gt;       public int hashCode() {<br>&gt;               return solutionHashCode();<br>

&gt; //            return super.hashCode();<br>&gt;       }<br>&gt;<br>&gt;       @Override<br>&gt;       public boolean equals(Object obj) {<br>&gt;               return solutionEquals(obj);<br>&gt; //            return super.equals(obj);<br>

&gt;       }<br>&gt; }<br>&gt;<br>&gt;<br>&gt; --<br>&gt; View this message in context: <a href="http://drools.46999.n3.nabble.com/Planner-5-3-Final-presumedScore-is-corrupted-when-using-update-on-the-rules-working-memory-tp3546932p3563446.html" target="_blank">http://drools.46999.n3.nabble.com/Planner-5-3-Final-presumedScore-is-corrupted-when-using-update-on-the-rules-working-memory-tp3546932p3563446.html</a><br>

&gt; Sent from the Drools: User forum mailing list
archive at Nabble.com.<br>&gt; _______________________________________________<br>&gt; rules-users mailing list<br>&gt; <a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>&gt; <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>

&gt;<br>
                <br>
              </div>
            </div>
            <div>--<br>With kind regards,<br>Geoffrey De Smet<br>
              <br>
              <br>
            </div>
            <div>
              <div>_______________________________________________<br>rules-users mailing list<br>
                <a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
                <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
        <br clear="all">
        <div><br>
        </div>-- <br>Patrik Dufresne<br>
      </div>
      <pre><fieldset></fieldset>
_______________________________________________
rules-users mailing list
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a>
</pre>
    </blockquote>
    <br>
    <pre cols="72">-- 
With kind regards,
Geoffrey De Smet</pre>
  </div></div></div>

<br>_______________________________________________<br>rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>Patrik Dufresne<br>
</div>