[rules-users] not sure if this is a bug of drools or my bad usage...

Simon Chen simonchennj at gmail.com
Tue Mar 8 22:59:42 EST 2011


Hi Wolfgang,

First, your rules work...

But for the second rule, I replaced the first Reachable() in the when
clause to Link(), and the result is still correct. Only if I remove
"no-loop true", the issue I had appeared.

So, I understand how "no-loop true" in this case helps to make the
result correct. But, do you see any scenarios where "no-loop" can
cause incorrect results? For example, not enough number of recursions?

Thanks.
-Simon

2011/3/8 Wolfgang Laun <wolfgang.laun at gmail.com>:
> I think there is some fundamental error in deriving truths from givens and
> other derived facts that are then interpreted as given truths, and,
> moreover, with subtly varying semantics. In terms of graph theory:
> reachability is based on (directed) edges, but it does not establish
> additional edges.
>
> Deriving Reachability should be done by:
>
> rule deriveLink
> when
>     Link( $a: a, $b: b )
> then
>     insertLogical(new Reachable($a,$b));
>     System.out.println( "ins reach " + $a + " " + $b );
> end
>
> rule deriveReachReach
> no-loop true
> when
>     Reachable( $a: a, $b: b )
>     Reachable( a == $b, $c: b != $a )
> then
>     insertLogical(new Reachable($a,$c));
> end
>
> Ideally, I would like to use
>    not Reachable(a == $a, b == $c)
> instead of the (last resort) no-loop in the second rule, but Drools' truth
> maintenance is incomplete: it does not let your define the logical
> dependency on part of the condition (i.e., excluding the CE "not" in this
> case).
>
> -W
>
>
>
>
>
>
> On 8 March 2011 05:49, Simon Chen <simonchennj at gmail.com> wrote:
>>
>> What I had is a very simplified version of how calculating transitive
>> closure could go wrong...
>>
>> Let's say we have two rules:
>> rule 1
>> when
>>  link(a,b)
>> then
>>  insertLogical(new reachable(a,b))
>>
>> rule 2
>> when
>>  link(a,b) reachable(b,c)
>> then
>>  insertLogical(new reachable(a,c))
>>
>> Let's say, I have link(a,b), link(b,c), link(b,a), link(c,b). So,
>> we'll have reachable(a,b), reachable(b,c), reachable(a,c), etc. But,
>> after I retract link(a,b) and link(b,a), guess what, reachable(c,a)
>> still exists! This doesn't sound right to me.
>>
>> But in Drools, this is possible, because we have:
>> reachable(c,a) <- link(c,b), reachable(b,a)
>> reachable(b,a) <- link(b,c), reachable(c,a)
>>
>> The problem here is that we actually inserted reachable(b,a) multiple
>> times: first supported by link(b,a) and rule 1, and secondly by
>> link(b,c) and reachable(c,a) and rule 2. When reachable(b,a) was
>> inserted the second time, link(b,c) and reachable(c,a) become the
>> additional supporting condition - maintained by the truth maintenance
>> system. So, even if link(b,a) is retracted, reachable(b,a) still
>> exists further supporting reachable(c,a).
>>
>> Is it clearer?
>>
>> Thanks.
>> -Simon
>>
>> 2011/3/7 Edson Tirelli <ed.tirelli at gmail.com>:
>> >
>> >    Simon,
>> >    The behavior seems correct to me as B is justified by either A or C
>> > (or
>> > both). Of course, from the initial state, A is required for C to first
>> > exist, but once it starts to exist, your rules say that B and C justify
>> > each
>> > other and so both remain in memory.
>> >    This is design as intended, but do you think that is wrong?
>> >    Edson
>> >
>> > 2011/3/7 Simon Chen <simonchennj at gmail.com>
>> >>
>> >> Hi all,
>> >>
>> >> An interesting finding:
>> >>
>> >> I have three simple rules:
>> >> rule "A2B"
>> >>        when
>> >>                A()
>> >>        then
>> >>                insertLogical(new B());
>> >> end
>> >> rule "B2C"
>> >>        when
>> >>                B()
>> >>        then
>> >>                insertLogical(new C());
>> >> end
>> >> rule "C2B"
>> >>        when
>> >>                C()
>> >>        then
>> >>                insertLogical(new B());
>> >> end
>> >>
>> >> Basically, once we have an A(), we'll logically insert a B(). Once we
>> >> have a B(), we'll logically insert a C(). Once we have a C(), we'll
>> >> logically insert a B().
>> >>
>> >> So, I first insert an A(), print all the objects. Retract A(), and
>> >> print all the objects. Here's what I got:
>> >> com.sample.B at 42
>> >> com.sample.C at 43
>> >> com.sample.A at 548997d1
>> >> after retract!
>> >> com.sample.B at 42
>> >> com.sample.C at 43
>> >>
>> >> So, B() and C(), which should be logically depend on A(), somehow are
>> >> not retracted. The problem I see is the truth maintenance system allow
>> >> B() and C() to depend on each other, thus not affected by losing A().
>> >>
>> >> Is this a bug or my bad usage?
>> >>
>> >> Thanks.
>> >> -Simon
>> >> _______________________________________________
>> >> rules-users mailing list
>> >> rules-users at lists.jboss.org
>> >> https://lists.jboss.org/mailman/listinfo/rules-users
>> >
>> >
>> >
>> > --
>> >   Edson Tirelli
>> >   JBoss Drools Core Development
>> >   JBoss by Red Hat @ www.jboss.com
>> >
>> > _______________________________________________
>> > rules-users mailing list
>> > rules-users at lists.jboss.org
>> > https://lists.jboss.org/mailman/listinfo/rules-users
>> >
>> >
>>
>> _______________________________________________
>> rules-users mailing list
>> rules-users at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-users
>
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
>




More information about the rules-users mailing list