[rules-users] unsolved myth regarding transitive closure using insertlogical...

Ansgar Konermann ansgar.konermann at googlemail.com
Mon Feb 21 16:03:30 EST 2011


On 21.02.2011 04:11, Mark Proctor wrote:
> On 21/02/2011 03:03, Simon Chen wrote:
>    
>> On Sun, Feb 20, 2011 at 8:20 PM, Ansgar Konermann
>> <ansgar.konermann at googlemail.com>   wrote:
>>      
>>> On 19.02.2011 16:01, Simon Chen wrote:
>>>        
>>>> The example you gave seems to be the one-hop case. For the two-hop
>>>> case, we need something like this
>>>>
>>>> when
>>>>       edge(a, b), reach(b, c), not exists reach(a, c)
>>>> then
>>>>       insertLogical( reach(a,c) )
>>>>
>>>> So, where do you put your logical around? It should include both
>>>> edge(a,b) and reach(b,c), right?
>>>>
>>>> Another thought, can we have something like
>>>> testExistsAndInsertLogical() to replace insertLogical()? But this may
>>>> be buggy, as the conditions are all met, so the rule actually fired...
>>>>
>>>>          
>>> Hi,
>>>
>>> from my experience, insertLogical does exactly what
>>> testExistsAndInsertLogical would suggest. If the same object is already
>>> in the working memory, it keeps this object and does not insert another
>>> instance. This behaviour is not stated explicitly in the documentation,
>>> but I did a learning test a few weeks ago and IIRC it clearly showed
>>> this behaviour (at least for 5.0.1). -- I consider this behaviour a
>>> feature and would like it to be kept this way.
>>>        
>> I am using Drools 5.1.1, and I don't think insertLogical prevents
>> duplicates automatically. This also boils down to the question of how
>> Drools decides whether two objects are indeed the same. For strings
>> and integers, it is straightforward, but not much so for complex
>> objects. Is there a way to pass in a comparison function?
>>      
> InsertLogical operates on equality mode, that is determined by the
> pojo's equals() method implementation. If an object already exists that
> is equal, it will use that and the justification counter for that
> existing object is increased.
>
> Mark
>    
>>> With this, all which is necessary to implement transitive closure is to
>>> remove the contradicting part of the precondition to avoid oscillation.
>>> If it turns out that insertLogical does not perform a "does fact already
>>> exist" check and thus might potentially insert duplicates, put exists( )
>>> around the two preconditions and also use "exists( reach(x,y) )" to
>>> check whether y is reachable from x.
>>>        
>> I don't quite follow. Can you elaborate with an actual rule?
>>      

Easy case (insertLogical does not introduce duplicate objects):

when
      edge(a, b)
      reach(b, c)
then
      insertLogical( reach(a,c) )


If insertLogical did introduce duplicate objects, we'd need this:

when
      exists edge(a, b)
      exists reach(b, c)
then
      insertLogical( reach(a,c) )


Kind regards

Ansgar



More information about the rules-users mailing list