[rules-users] Re: not exists / forall(not) logically equivalent, behave differently

tim tim timbaermannextra at googlemail.com
Wed Oct 8 12:51:28 EDT 2008


edson,

thanks a lot for your answer.

now i came to a new problem.

i stated the rule as you said:

  rule "no dog without a tail"
        when
            $dog :Dog()
             not( Tail(dog == $dog) )
        then
       // fire rule
    end

but now, if i do
 workingMemory.insert(dog);
 workingMemory.insert(dog.getTail());
 workingMemory.fireAllRules();

 modifyRetract(dogHandle);
 dog.changeHashCode(); // do something that changes the hashCode of the dog
 modifyInsert(dogHandle);

workingMemory.fireAllRules();

in the second fireAllRules() the rule fires, even though there is a
tail for the dog.

am i not allowed to do an opperation that changes the hashCode of the
modified object between the
modifyRetract() and modifyInsert() ?

should i totally retract the object, and insert it again instead?

thank you, tim


> I believe there is an open ticket for a bug when using "not(exists())" in 5.0. I did not investigated yet, but I believe this is a regression in the new asymmetric matching algorithm in 5.0. Anyway, we will fix it before releasing the final version.
>
>    Meantime, just use:
>
>not( Tail(dog == $dog) )
>
>    Since the "exists" is redundant there because "not" is the existential operator, not the "boolean" operator.
>
>    []s
>    Edson

2008/10/6 tim tim <timbaermannextra at ...>

    hello there,

    i have a rule, that should fire, when a required part of a whole is missing.
    lets say the whole is a dog, and the required part the tail.
    then the rule should fire, when there is a dog without a tail.

    i stated the rule in two logically equivalent ways.

    1) when we have a dog, and all existing tails belong to other
peoples dogs, the rule should fire:

    rule "no dog without a tail; forall"
        when
            $dog :Dog()
            forall($t : Tail()
                    Tail(dog != $dog))
        then
       // fire rule
    end


    2) when we have a dog and no tail exists that belongs to this dog
the rule should fire:

    rule "no dog without a tail; not exists"
        when
            $dog :Dog()
            not( exists( Tail(dog == $dog)))
        then
       // fire rule
    end


    and they really do behave similar, but not the same..
    workingMemory.insert(dog);
    workingMemory.insert(dog.getTail());
    workingMemory.fireAllRules();

    // here both did not fire, but when i go on:

    workingMemory.modifyRetract(dogHandle)
    workingMemory.modifyInsert(dogHandle, dog)
    workingMemory.fireAllRules();
    // now the not(exists(..)) version did fire, whereas the
forall(..) version did not.


    of course both rules should not have fired, nothing changed for
the dogs relationship
    with its tail.

    i am using the 5.0.0.snapshot version of drools but i can not
imagine that this is an
    unknown bug, as this is rather basic predicate logic.
    what am i missing?

    best, tim



More information about the rules-users mailing list