The correct behaviour of logic assertions is fully commented in
WorkingMemoryImpl.
http://anonsvn.labs.jboss.com/labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/WorkingMemoryImpl.java
But can be summaries, taken from the comments. STATED means it was
asserted normally, not logically
-check if the object already exists in the WM
-return if the handle exists and this is a logical assertion
-return if we have a handle and this STATED fact was previously STATED
When !logical
-If this stated assertion already has justifications then we need to cancel them
else
-This object is already STATED, we cannot make it justifieable
so doing assertLogical on objects that are "equals" does nothing, "equals"
objects can only be logically asserted once.
Normally Asserting, which we call "stating", a previously logically asserted and
"equals" object will cancel the logical assertion
If anyone wants to confirm all this and do a details write up for the manual,
it would be very much appreciated :)
Mark
Russ Egan wrote:
Such behavior sounds like it might be useful, but isn't this due to a
lack of support in drools for expressing the re-assertion of a fact?
drools current behavior seems correct to me. There just isn't any
mechanism for expressing the "backing" of an existing fact.
In your example, I would expect drools to do just what it does. Only
the second rule is asserting a fact. The second rule is just testing
for a fact's existence, not re-asserting the fact. Maybe a more
illustrative example would be:
rule "assert fact"
when
Integer()
then
assertLogical(new Fact());
end
rule "reassert fact"
when
Float()
f : Fact()
then
assertLogical(f);
end
Thus, the fact wouldn't be auto-retracted until both the int and the
float were retracted. This looks like it could very difficult to
debug though.
Hello Juergen,
A logically asserted object seems to be retracted only when the
fact(s) leading to its inital assertion are invalid/retracted. Even if
the depended object is "backed" by some other rule/facts.
so in the following example:
1 => A
2 => A
As soon, as 1 is asserted, A is asserted. When 2 is asserted, the
truth of A is "backed" but nothing happens as A is already asserted
(in terms of memory management, the reference counter would increase i
guess).
When 1 becomes false and is retracted, the truth of A is still given
by 2 => A and A should not be retracted (which it is). Only if 2 also
becomes false and is retracted, A should be retracted too.
Gets even more interesting if a fact is backed by itself after inital
assertion: A => A
Without this behaviour logical assertion are not useful in my opinion.
Checked it with JESS which does it properly.
Will it change in the future, and probably already for 3.0?
Juergen.
Example:
--------
DRL:
----
rule "1"
when
s : String()
then
System.out.println("s=" + s);
end
rule "2"
when
i : Integer()
then
System.out.println("i=" + i);
assertLogical("A");
end
Java:
-----
FactHandle h = workingMemory.assertObject(new Integer(1));
workingMemory.fireAllRules();
workingMemory.assertObject(new Integer(2));
workingMemory.fireAllRules();
workingMemory.retractObject(h); // A will be retracted, but should not
workingMemory.fireAllRules();
List l = workingMemory.getObjects();
System.out.println(l);