I encountered a problem, which is consistent with the problem on this link.
-> Optaplanner unable to remove ConstraintMatch
Exception:
org.optaplanner.core.api.score.constraint.ConstraintMatchTotal.removeConstraintMatch
I debugged, and both hashCode and Equals were rewritten, but errors were still reported.
Rule:
rule "scheduleFullTimeLimit"
when
$shiftList: ArrayList() from collect (
StaffAssignment(
shiftType != null
)
)
then
scoreHolder.addSoftConstraintMatch(kcontext, -1);
end
I used collect in my rules.
Is this a bug?
Beg your help
I am afraid that the problem here will be with the ArrayList. ArrayList's hashCode() will change with every change to the collection. Therefore, you will get the exact message you're getting - OptaPlanner is trying to undo something which does not exist.
You'll have to figure out how to do whatever you're doing without the ArrayList. At the very least, don't let the ArrayList be the final thing in the rule, because I believe that is what lands it in the constraint matches in the first place.
Related
When I use List() from collect (...) in the rule file , then Optaplanner unable to remove ConstraintMatch
then
$staff : StaffAssignment(shiftType != null)
$li : HashSet()
from collect (
TimeSetDto(timeSet != null) from $staff.getTimeSet()
)
then
Using collections in rules is often problematic with OptaPlanner, as the collection's hashCode() will change every time an object is added or removed.
This confuses OptaPlanner's constraint matching algorithm and leads to the exception you're seeing.
In OptaPlanner 8.3.0, we have made some changes that may (or may not) help solve the problem. In the meantime, there are two workarounds:
Disable constraint matching or
do not use collections in your rules.
I'm trying to use Drools backward chaining to find out which facts are needed to get an object inserted in the working memory.
In the following example, I expect to get the fact "go2".
rule "ins a"
when
String( this == "go2" )
then
insert(new A());
end
rule "Run"
when
then
insert(new String("go1"));
end
rule "Test isThereAnyA"
when
String( this == "go1" )
isThereAnyA(a;)
then
System.out.println( "you can get " + a );
end
query isThereAnyA (A a)
a := A()
end
I've been looking at examples in the official documentation
http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_single/index.html#d0e21289
but they show a different situation (the rules in those examples doesn't creates new fact)
From the chart
http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_single/index.html#d0e21240
I think it should work but I haven't found a way to specify a query that gives me the expected results.
Thank you in advance.
Short answer:
Unfortunately backward chaining can not be used for this purpose.
It will not give you "go2" in this case.
Long answer:
In Drools, Backward chaining (BC) is a way to query the WM in a goal-driven fashion, not a way to trace back the derivation graph of a normal forward chaining inference process.
BC allows rule "Test" to retrieve As through the query "isThereAnyA", and possibly invoke other queries, but will not allow to find the "production" link between "A" and "go2". The reason is that "when..then..insert.." does not create any link between the triggering facts and the asserted conclusion, and backward chaining will not change it.
What you could do with BC is this:
query isThereAnyA_InPresenceOfA_String( A a )
isThereAnyString( $s ; )
a := A()
end
query isThereAnyString( String $s )
$s := String( this == "go2" )
end
This will pick up As only if a String "go2" is (still) present. However you'll notice that the connection between a particular instance of A and a the particular String which led to its assertion is still missing.
To know exactly which objects led to the assertion of another object you may need a different approach. Options include:
make the connection explicit : new A( $s ) // $s bound to "go2"
use "insertLogical" to establish a dependency between "go2" and A, then query the TruthMaintenanceSystem
The TMS-based one would be my tentative choice, but it also depends on your exact requirements.
This use case is common, there may be other options, including a few which are experimental as they are being developed in 6.3, but I'd rather ask a few questions first.
That is: when do you need exactly to discover the facts - during the execution of the rules, or "offline"? Is it purely for auditing purposes, or does it impact your business logic? Can you have multiple rules asserting the "same" object?
Hope this helps
Davide
I had quite a big list of numbers. I needed to apply some operation on them, then take only those results that satisfy some condition. The list is sequential, so once I find the number that does not satisfy the condition, I can stop looking.
I wanted to avoid doing too much computation, so I moved on like in this example:
List(1,2,3,4,5).view.map(2 *).takeWhile(_ < 8)
But it gives me an exception:
java.lang.UnsupportedOperationException: SeqViewM(...).newBuilder
at scala.collection.TraversableViewLike$class.newBuilder(TraversableViewLike.scala:69)
at scala.collection.SeqViewLike$$anon$3.newBuilder(SeqViewLike.scala:77)
at scala.collection.IterableLike$class.takeWhile(IterableLike.scala:139)
at scala.collection.SeqViewLike$$anon$3.takeWhile(SeqViewLike.scala:77)
at scala.collection.SeqViewLike$$anon$3.takeWhile(SeqViewLike.scala:77)
Using Scala 2.9.0.1 (same behavior with 2.9.1). What is wrong here?
Looks like a bug. (File a bug report, if it's not already reported and/or fixed!)
In the meantime, you can use iterator as a workaround for this particular code:
List(1,2,3,4,5).iterator.map(2 *).takeWhile(8 >).toList
(drop the .toList if you're happy to end up with an iterator).
il.Emit(OpCodes.Callvirt, _compactBinaryReader_ReadObject);
this function is called and at a special condition a return value of 'null' is provided.
if that value is null i have to take a decision whether to jump on to a label or not
using after the method call
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Brfalse_S, DECISION);
gives me an exception "JIT Compiler encountered an internal limitation." when i call that function, the code builds correctly though.
tried OpCodes.Brfalse too.
what am i doing wrong ?
Found reasonS to the above problem,
one thing which should be understood that when an exception of
'CLR: Verification for Runtime Code Generation'
is thrown it means the code written is not in the correct format and when it is evaluated by the assembler it does not accept the written code, problem is usually because of stacks having extra values or less.
"JIT Compiler encountered an internal limitation." is thrown when at runtime it was expecting something else we provide something else in value or when stack has something else when something else was required.
In short, the later exception is thrown at runtime and the other is thrown when pre Run conditions are not met.
anyways i found the reason, i had some values still present on stack that i did not pop if Condition was met, so the POP OpCode did the trick, and by the way for me the Dup OpCode never worked out, it always pushes a null value on stack rather than duplicating the top most value.
this throws an exception, when the field does not exist:
reader.IsDbNull(reader.GetOrdinal("FieldName")) => bang
Why not return -1 ?
I'll try to guess here.
The common pattern for this method is to call GetOrdinal for column name and then call GetXXX() methods with given ordinal which is faster than do a search by column's name every time.
Therefore in case of exception here we fail fast and we can't ignore it. Wihtout exception we will try to find a column that doesn't exist and then try to find a field by given ordinal (without checking for -1 which is very easy to omit in this case) and only here we will realise that something went wrong few steps before (may be even too many steps before).