On 9 March 2011 04:59, Simon Chen <simonchennj@gmail.com> wrote:
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.

My statement about avoiding a mix of given and derived facts was
definitely exaggerating matters. But the representation of Link vs.
Reachable merits some consideration.
 

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?

No-loop is almost never satisfactory.

It's necessary to avoid duplications of Reachable. You can't add a "not" CE to
block this, but it's possible to configure against the insertion of equal facts.
For this, equals() and hashCode() must be implemented properly, and the
AssertBehaviorOption.EQUALITY must be set.

I have found this to work quite well:

public class Reachable {
  private String src;
  private String tgt;
  //...
    public boolean equals(Object obj) {
    if (this == obj) return true;
    if( ! (obj instanceof Reachable)) return false;
    Reachable other = (Reachable) obj;
    return other.src.equals( src ) &&  other.tgt.equals( tgt );
  }
}

public class Link extends Reachable {
  public Link( String src, String tgt ){
    super(src, tgt);
  }
}

Notice that this subclassing avoids the creation of Reachable for each Link. And I still think that computing the closure should be done by using Reachable only. Note the absence of no-loop!

rule deriveReachReach
when
    Reachable( $src: src, $mid: tgt )
    Reachable( src == $mid, $tgt: tgt != $src )
then
    insertLogical( new Reachable( $src, $tgt ));
end


  kbConfig.setOption( AssertBehaviorOption.EQUALITY );   // identical and equal not inserted
  kBase = KnowledgeBaseFactory.newKnowledgeBase( kbConfig );

Cheers
-W





 

Thanks.
-Simon