Hi Michael,


Michael Neale schrieb:
Add this as your first condition:
         <java:condition>System.identityHashCode(Y) >
System.identityHashCode (X)</java:condition>

  
This rule does not ensure to eliminate dublicates. Using this rule causes more problems, since the order of the Facts in the memory does not tell anyhing about the information in the Facts.

A possible solution to prevent Facts dublication would be to save Facts in a HashSet. Drawback: you need to specify hashcodes

this is how my rule looks now (bold areas are new code):
    <rule name="Generic TransLink Rule">

        <parameter identifier="X">
            <class>transitivity2.Triple</class>
        </parameter>
        <parameter identifier="Y">
            <class>transitivity2.Triple</class>
        </parameter>
        <parameter identifier="linkName">
            <class>java.lang.String</class>
        </parameter>
        <parameter identifier="set">
            <class>java.util.Set</class>
        </parameter>

   
        <java:condition>Y.getResource().equals(X.getObject())</java:condition>
       
        <java:consequence>
             Triple newTriple = new Triple();
             newTriple.setResource(X.getResource());
             newTriple.setProperty(linkName);
             newTriple.setObject(Y.getObject());
            
              if(!set.contains(newTriple)){
            
                 set.add(newTriple);
                 drools.assertObject(newTriple);
               }
        </java:consequence>
    </rule>


this are the results I get know (Heap @ 512MB):
(Input-depth, result in ms)
(20, 400)
(30, 1078)
(40, 2235)
(50, 4766)
(60, 10360)
(70, 17828)
(80, 31687)
at 90 Triples I was bored to wait

See @attachment for complete Code. (you will need Jakarta Commons Lang, for using the HashcodeBuilder class)

Without using a HashSet, I got a OutOfMemory exception @ 10 Triples. Now even 80 work but from my point of view, the response times are far from good (in this kind of scenario). I dont know what kind of datastructure you guys use @ Drools to collect your Facts....but maybe it could be worth trying to use as HashSet (like said, as an optinal feature). Sure people will need to setup hashCode() but I think this would be a cheap price to pay...for doing Object-Rule mapping effeciently with no Fact dublications.

best regards,
Andreas

package transitivity2;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.drools.FactHandle;
import org.drools.RuleBase;
import org.drools.WorkingMemory;
import org.drools.io.RuleBaseLoader;


public class Main {


  /**
   * @param args
   */
  public static void main(String[] args) throws Exception{

    
    RuleBase base = RuleBaseLoader.loadFromInputStream(Triple.class
        .getResourceAsStream("rules.xml"));
    WorkingMemory memory = base.newWorkingMemory();
 
    //set here the linkName
    String linkName = "subClassOf";
    
    //set here the list depth
    int triplesCount = 40;
    
    Set triplesSet = new HashSet();
    
    List<Triple> tripleList = new ArrayList<Triple>();
    for (int i = 1; i <=triplesCount; i++) {
      
      Triple t = new Triple();
      t.setResource(String.valueOf(i-1));
      t.setProperty(linkName);
      t.setObject(String.valueOf(i));
      
      tripleList.add(t);
      triplesSet.add(t);
    }
    

    // hold time
    long time = System.currentTimeMillis();
    
    //assert all Triples into WorkingMemory   
    for (Triple t : tripleList) {
      FactHandle handle = memory.assertObject(t);
    }

    memory.assertObject(triplesSet);
    memory.assertObject(linkName);
    memory.fireAllRules();
 
    //Display calculation time:
    System.out.println("Trans-calculation: 
"+(System.currentTimeMillis()-time)+" ms");
    

    //Display all Triples. Old + new infered (over transitivity)
    List objects = memory.getObjects(Triple.class);
    System.out.println("Triples count: "+objects.size());
    for (Object object : objects) {
      
      Triple currentTriple = (Triple)object;
      System.out.println(currentTriple);
    }
 
  }//end main

  
  
  
}//end class
<rule-set name="cheese rules" xmlns="http://drools.org/rules";
	xmlns:java="http://drools.org/semantics/java";
	xmlns:xs="http://www.w3.org/2001/XMLSchema-instance";
	xs:schemaLocation="http://drools.org/rules rules.xsd
    				   http://drools.org/semantics/java java.xsd">

	<import>java.lang.String</import>
	<import>java.util.Set</import>
	<import>java.util.HashSet</import>
	<import>transitivity2.Triple</import>


	<rule name="Generic TransLink Rule">

		<parameter identifier="X">
			<class>transitivity2.Triple</class>
		</parameter>
		<parameter identifier="Y">
			<class>transitivity2.Triple</class>
		</parameter>
		<parameter identifier="linkName">
			<class>java.lang.String</class>
		</parameter>
		<parameter identifier="set">
			<class>java.util.Set</class>
		</parameter>
	
		<java:condition>Y.getResource().equals(X.getObject())</java:condition>
		
		<java:consequence>
		 	Triple newTriple = new Triple();
		 	newTriple.setResource(X.getResource());
		 	newTriple.setProperty(linkName);
		 	newTriple.setObject(Y.getObject());
		 	
		  	if(!set.contains(newTriple)){ 
		 	
		 		set.add(newTriple);
		 		drools.assertObject(newTriple);
		   	} 
		</java:consequence>
	</rule>
	

</rule-set>
package transitivity2;


import org.apache.commons.lang.builder.HashCodeBuilder;


public class Triple {


  private String resource;

  private String property;

  private String object;


  public String getObject() {

    return this.object;
  }


  public void setObject(String object) {

    this.object = object;
  }


  public String getProperty() {

    return this.property;
  }


  public void setProperty(String property) {

    this.property = property;
  }


  public String getResource() {

    return this.resource;
  }


  public void setResource(String resource) {

    this.resource = resource;
  }


  public String toString() {

    return "<" + resource + "> <" + property + "> <" + object + ">";
  }


  public boolean equals(Object o) {

    if (o == null || o.getClass() != this.getClass())
      return false;

    Triple other = (Triple) o;
    return this.getResource() == other.getResource()
        && this.getProperty() == other.getProperty()
        && this.getObject() == other.getObject();
  }


  public int hashCode() {

    return new 
HashCodeBuilder().append(this.getResource()).append(this.getProperty())
        .append(this.getObject()).toHashCode();
  }

}

Reply via email to