@@ -51,20 +51,23 @@ public ScoreDirectorFactory<Solution_, Score_> getScoreDirectorFactory() {
5151 @ Override
5252 public Score_ update (Solution_ solution , SolutionUpdatePolicy solutionUpdatePolicy ) {
5353 if (solutionUpdatePolicy == SolutionUpdatePolicy .NO_UPDATE ) {
54- throw new IllegalArgumentException ("Can not call " + this .getClass ().getSimpleName ()
55- + ".update() with this solutionUpdatePolicy (" + solutionUpdatePolicy + ")." );
54+ throw new IllegalArgumentException (
55+ "Can not call %s.update() with this solutionUpdatePolicy (%s)."
56+ .formatted (this .getClass ().getSimpleName (), solutionUpdatePolicy ));
5657 }
57- return callScoreDirector (solution , solutionUpdatePolicy ,
58+ return callScoreDirector ("Solution update" , solution , solutionUpdatePolicy ,
5859 s -> s .getSolutionDescriptor ().getScore (s .getWorkingSolution ()), ConstraintMatchPolicy .DISABLED , false );
5960 }
6061
61- private <Result_ > Result_ callScoreDirector (Solution_ solution , SolutionUpdatePolicy solutionUpdatePolicy ,
62+ private <Result_ > Result_ callScoreDirector (String feature , Solution_ solution , SolutionUpdatePolicy solutionUpdatePolicy ,
6263 Function <InnerScoreDirector <Solution_ , Score_ >, Result_ > function , ConstraintMatchPolicy constraintMatchPolicy ,
6364 boolean cloneSolution ) {
6465 var isShadowVariableUpdateEnabled = solutionUpdatePolicy .isShadowVariableUpdateEnabled ();
6566 var nonNullSolution = Objects .requireNonNull (solution );
67+ var allowsInconsistent = getScoreDirectorFactory ().getSolutionDescriptor ().hasAnyShadowVariablesInconsistentMember ();
6668 try (var scoreDirector = getScoreDirectorFactory ().createScoreDirectorBuilder ().withLookUpEnabled (cloneSolution )
6769 .withConstraintMatchPolicy (constraintMatchPolicy )
70+ .withIgnoreInconsistentSolutions (!allowsInconsistent )
6871 .withExpectShadowVariablesInCorrectState (!isShadowVariableUpdateEnabled ).build ()) {
6972 nonNullSolution = cloneSolution ? scoreDirector .cloneSolution (nonNullSolution ) : nonNullSolution ;
7073 if (isShadowVariableUpdateEnabled ) {
@@ -82,7 +85,16 @@ private <Result_> Result_ callScoreDirector(Solution_ solution, SolutionUpdatePo
8285 Maybe use Constraint Streams instead of Easy or Incremental score calculator?""" );
8386 }
8487 if (solutionUpdatePolicy .isScoreUpdateEnabled ()) {
85- scoreDirector .calculateScore ();
88+ var score = scoreDirector .calculateScore ();
89+ if (score .isInvalid ()) {
90+ throw new IllegalArgumentException ("""
91+ The solution (%s) is inconsistent. %s requires a consistent solution to be passed.
92+ """ .formatted (solution , feature ));
93+ }
94+ } else if (!scoreDirector .isLastVariableUpdateWasSuccessful ()) {
95+ throw new IllegalArgumentException ("""
96+ The solution (%s) is inconsistent. %s requires a consistent solution to be passed.
97+ """ .formatted (solution , feature ));
8698 }
8799 return function .apply (scoreDirector );
88100 }
@@ -112,7 +124,7 @@ public ScoreAnalysis<Score_> analyze(Solution_ solution, ScoreAnalysisFetchPolic
112124 var enterpriseService =
113125 TimefoldSolverEnterpriseService .loadOrFail (TimefoldSolverEnterpriseService .Feature .SCORE_ANALYSIS );
114126 var currentScore = (Score_ ) scoreDirectorFactory .getSolutionDescriptor ().getScore (solution );
115- var analysis = callScoreDirector (solution , solutionUpdatePolicy ,
127+ var analysis = callScoreDirector ("Solution analysis" , solution , solutionUpdatePolicy ,
116128 scoreDirector -> enterpriseService .analyze (scoreDirector .calculateScore (),
117129 scoreDirector .getConstraintMatchTotalMap (), fetchPolicy ),
118130 ConstraintMatchPolicy .match (fetchPolicy ), false );
@@ -134,7 +146,7 @@ public <In_, Out_> List<RecommendedAssignment<Out_, Score_>> recommendAssignment
134146 ScoreAnalysisFetchPolicy fetchPolicy ) {
135147 var enterpriseService =
136148 TimefoldSolverEnterpriseService .loadOrFail (TimefoldSolverEnterpriseService .Feature .RECOMMENDATIONS );
137- return callScoreDirector (
149+ return callScoreDirector ("Recommended assignment" ,
138150 solution , SolutionUpdatePolicy .UPDATE_ALL , enterpriseService .buildRecommender (solverFactory , solution ,
139151 evaluatedEntityOrElement , propositionFunction , fetchPolicy ),
140152 ConstraintMatchPolicy .match (fetchPolicy ), true );
0 commit comments