[rules-dev] Changing a fact's hashCode causes rules not to fire

Mark Proctor mproctor at codehaus.org
Thu Jun 23 05:28:11 EDT 2011


On 23/06/2011 10:19, Wolfgang Laun wrote:
> Well, you are saying that if you are using references to fact objects 
> in combination with constraints comparing such a reference to some 
> other object any (overridden) hashCode method /*must not refer to 
> mutable fields*/ of that object.
hashCode method /*must not refer to mutable fields*/ of that object.
That's not a good idea really. Hashcode's should refer to fields that 
you constrain on, as a general good rule. and those fields are normally 
mutable.

I don't really know what more to say than...
Nested accessors are "black box" if you modify a nested accessor you 
must notify the root object(s) that are inserted into the engine.

If you want to write up some paragraphs talking people through how 
hashcode's and hashmap's work. Specifiically if you change the hashcode 
of an object that is in map you won't be able to find it in the map any 
more - which is what is happening to you. Notification effectively takes 
the root object out and put's it back in again, so it lives in the 
correct index.

This is why other engines don't support Objects as fields, you can only 
use values - strings, numbers etc. For them it's worse though, they have 
to use techniques like shadow facts otherwise they get memory corruption 
- but shadow facts only work on direct values, and cannot shadow objects 
and nested fields. If you tried to do this stuff in other engines they 
would just get corrupted. It's only because we do a tree-graph based 
rete network for assymetrical retract that we can allow you to do this 
without corruption, but you must still notify the engine.

Mark
>
> Certainly: this restriction should not hurt - I'm inclined to regard 
> mutable hashCode methods as "suspicious" anyway.
>
> But, nevertheless, it deserves a short paragraph in the "Expert" 
> manual, don't you think so?
>
> Cheers
> Wolfgang
>
>
>
> On 23 June 2011 10:50, Mark Proctor <mproctor at codehaus.org 
> <mailto:mproctor at codehaus.org>> wrote:
>
>     On 23/06/2011 09:32, Wolfgang Laun wrote:
>>     If I have
>>        class Type {
>>           int field;
>>           setField( int f ){ field = f; }
>>        }
>>
>>     and do
>>
>>        modify( $type ){ setField( 42 ) }
>>
>>     where is there a "nested accessor"?
>     $one: One()
>     $two: Two( $x: one == $one )
>
>     If you change a field on object "one". that field is a nested
>     accessor to Two.
>     one.field1 = "x"
>     is the same as doing
>     two.one.field1 = "x"
>
>     so to "two" changing the field of 1 is a nested accessor.
>
>     Think about how indexing works.
>     left == right
>
>     when two objects are == each other indexing creates a bucket for
>     the left and a bucket for the right. If you change the hashcode of
>     the one on the right, how will it find the bucket on the left?
>
>     Mark
>
>
>>
>>     -W
>>
>>     On 23 June 2011 10:24, Mark Proctor <mproctor at codehaus.org
>>     <mailto:mproctor at codehaus.org>> wrote:
>>
>>         On 23/06/2011 07:03, Wolfgang Laun wrote:
>>>         Eeek!
>>>
>>>         Assume this: A is a field of B is a field of C is a field of
>>>         D is a...
>>>
>>>         Object references remain the same, in all objects; I simply
>>>         modify A, and
>>>         "when you change [A] you are also changing [B], so I must
>>>         notify the
>>>         engine for [B]" but that's a field of C...  D... E... and so
>>>         on, until
>>>         'I' for infinity?!
>>>
>>>         _*/It's just a change in some fact object's hashCode that
>>>         causes this problem./*_
>>         If you don't want any indexing in your rule engine. If you
>>         want indexing, you have to notify the engine. Changes to
>>         nested accessors have always been invisible to the engine. If
>>         a nested access changes, you must notify the engine of the
>>         root fact.
>>
>>         Mark
>>
>>>
>>>         -W
>>>
>>>
>>>
>>>         On 22 June 2011 22:37, Mark Proctor <mproctor at codehaus.org
>>>         <mailto:mproctor at codehaus.org>> wrote:
>>>         > As One is a field of Two. When you change One you are also
>>>         changing Two, so
>>>         > you most notify the engine for Two too.
>>>         >
>>>         > MArk
>>>         > On 22/06/2011 14:37, Wolfgang Laun wrote:
>>>         >
>>>         > To avoid misunderstandings: yes, equals() is written
>>>         according to hashCode,
>>>         > i.e., according to the usual Java conventions.
>>>         >
>>>         > If
>>>         >
>>>         >    - an object of class Two contains a member of class
>>>         One, and
>>>         >    - one object Two and one object One are facts, and
>>>         >    - a rule modifies One, changing its hashCode
>>>         >
>>>         > then
>>>         >
>>>         >    another rule containing the patterns
>>>         >    $one: One()
>>>         >    $two: Two( $x: one == $one )
>>>         >
>>>         > does NOT fire (any more).
>>>         >
>>>         > If you use the constraint
>>>         >    one == $one || != $one
>>>         > the rule will fire, and you can observe that hashCode
>>>         results for $one and
>>>         > $x are the same and that $one.equals( $x ) returns true.
>>>         >
>>>         > Reproduced using 5.1.1 and 5.2.x
>>>         >
>>>         > -W
>>>         >
>>>         >
>>>         >
>>>         >
>>>         > _______________________________________________
>>>         > rules-dev mailing list
>>>         > rules-dev at lists.jboss.org <mailto:rules-dev at lists.jboss.org>
>>>         > https://lists.jboss.org/mailman/listinfo/rules-dev
>>>         >
>>>         >
>>>         > _______________________________________________
>>>         > rules-dev mailing list
>>>         > rules-dev at lists.jboss.org <mailto:rules-dev at lists.jboss.org>
>>>         > https://lists.jboss.org/mailman/listinfo/rules-dev
>>>         >
>>>         >
>>>
>>>
>>>         _______________________________________________
>>>         rules-dev mailing list
>>>         rules-dev at lists.jboss.org  <mailto:rules-dev at lists.jboss.org>
>>>         https://lists.jboss.org/mailman/listinfo/rules-dev
>>
>>
>>         _______________________________________________
>>         rules-dev mailing list
>>         rules-dev at lists.jboss.org <mailto:rules-dev at lists.jboss.org>
>>         https://lists.jboss.org/mailman/listinfo/rules-dev
>>
>>
>>
>>     _______________________________________________
>>     rules-dev mailing list
>>     rules-dev at lists.jboss.org  <mailto:rules-dev at lists.jboss.org>
>>     https://lists.jboss.org/mailman/listinfo/rules-dev
>
>
>     _______________________________________________
>     rules-dev mailing list
>     rules-dev at lists.jboss.org <mailto:rules-dev at lists.jboss.org>
>     https://lists.jboss.org/mailman/listinfo/rules-dev
>
>
>
> _______________________________________________
> rules-dev mailing list
> rules-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-dev/attachments/20110623/7bc6414e/attachment-0001.html 


More information about the rules-dev mailing list