[rules-users] Re: transitive closure

Paul Fodor paul.i.fodor at gmail.com
Thu Jul 3 16:51:59 EDT 2008


How can I check if an instance was not already inserted?

For instance, my transitive closure works for non-cycled data, but it
re-derives the same relations for cycled data.

TransitiveClosure.drl:
package org.drools.examples

import org.drools.examples.TransitiveClosureExample.Edge;
import org.drools.examples.TransitiveClosureExample.Reach;

rule "reachDirect"
    salience 10
    when
        e : Edge(s1 : source, t1 : target)
//        not( exists( Reach(source == s1, target == t1) ) )
    then
        insertLogical( new Reach(e.getSource(),e.getTarget()) );
        System.out.println( "Reach " + e.getSource() + "," + e.getTarget() );
end

rule "reachIndirect"
    salience 10
    when
        e : Edge(s1 : source, t1 : target)
        r : Reach(t2 : target, source == t1 )
//        not( exists( Reach(source == s1, target == t2) ) )
    then
        insertLogical( new Reach(e.getSource(),r.getTarget()) );
        System.out.println( "Reach " + e.getSource() + "," + r.getTarget() );
end

TransitiveClosureExample.java:
package org.drools.examples;
import java.io.InputStreamReader;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.StatefulSession;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.compiler.PackageBuilder;
import org.drools.compiler.PackageBuilderConfiguration;

public class TransitiveClosureExample {
    public static void main(final String[] args) throws Exception {
        PackageBuilderConfiguration conf = new PackageBuilderConfiguration();
        final PackageBuilder builder = new PackageBuilder( conf );
        builder.addPackageFromDrl( new InputStreamReader(
TransitiveClosureExample.class.getResourceAsStream(
"TransitiveClosure.drl" ) ) );
        final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
        ruleBase.addPackage( builder.getPackage() );
        final StatefulSession session = ruleBase.newStatefulSession();
        final WorkingMemoryFileLogger logger = new
WorkingMemoryFileLogger( session );
        logger.setFileName( "log/transitiveClosure" );

        final Edge edgeAB = new Edge( "a","b" );
        final Edge edgeBC = new Edge( "b","c" );
        final Edge edgeCD = new Edge( "c","d" );
        final Edge edgeDA = new Edge( "d","a" );

        session.insert( edgeAB );
        session.insert( edgeBC );
        session.insert( edgeCD );
        session.insert( edgeDA );

        session.fireAllRules();
        logger.writeToDisk();
        session.dispose();
    }

    public static class Edge {
        private String source;
        private String target;
        public Edge() {}
        public Edge(String source, String target) {
            super();
            this.source = source;
            this.target = target;
        }
        public String getSource() {
            return source;
        }
        public String getTarget() {
            return target;
        }
    }

    public static class Reach {
        private String source;
        private String target;
        public Reach() {}
        public Reach(String source, String target) {
            super();
            this.source = source;
            this.target = target;
        }
        public void setSource(String source) {
            this.source = source;
        }
        public String getSource() {
            return source;
        }
        public void setTarget(String target) {
            this.target = target;
        }
        public String getTarget() {
            return target;
        }
    }
}

Please tell me if you have any idea.
Thanks,
Paul Fodor



More information about the rules-users mailing list