<div> </div>
<div> You will have to use regular insert() instead of insertLogical(). This is because:</div>
<div> </div>
<div>rule "reachDirect"<br> salience 10<br> when<br> e : Edge(s1 : source, t1 : target)<br> not( Reach(source == s1, target == t1) )<br> then<br> insertLogical( new Reach(e.getSource(),e.getTarget()) );<br>
System.out.println( "Reach " + e.getSource() + "," + e.getTarget() );<br>end<br> </div>
<div> Is initially true, but once the consequence is executed, the insert(new Reach()) will cause the pattern "not(Reach(...))" to become false and so the object is retracted, causing the recursion.</div>
<div> </div>
<div> []s</div>
<div> Edson<br><br> </div>
<div><span class="gmail_quote">2008/7/3, Paul Fodor <<a href="mailto:paul.i.fodor@gmail.com">paul.i.fodor@gmail.com</a>>:</span>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">On Thu, Jul 3, 2008 at 3:56 PM, Paul Fodor <<a href="mailto:paul.i.fodor@gmail.com">paul.i.fodor@gmail.com</a>> wrote:<br>
> Dear Sir,<br>><br>> I am new to Drools and I want to ask how can I implement the classical<br>> transitive closure in Drools. For instance we have a bunch of facts<br>> edge/2 and the transitive closure:<br>
><br>> reach(X,Y):- edge(X,Y).<br>> reach(X,Y):- edge(X,Z),reach(Z,Y).<br><br>My current version looks like the following, but it never terminates.<br>It re-derives reach(c,c) forever.<br><br>TransitiveClosure.drl :<br>
package org.drools.examples<br><br>import org.drools.examples.TransitiveClosureExample.Edge;<br>import org.drools.examples.TransitiveClosureExample.Reach;<br><br>rule "reachDirect"<br> salience 10<br> when<br>
e : Edge(s1 : source, t1 : target)<br> not( Reach(source == s1, target == t1) )<br> then<br> insertLogical( new Reach(e.getSource(),e.getTarget()) );<br> System.out.println( "Reach " + e.getSource() + "," + e.getTarget() );<br>
end<br><br>rule "reachIndirect"<br> salience 10<br> when<br> e : Edge(s1 : source, t1 : target)<br> r : Reach(t2 : target, source == t1 )<br> not( Reach(source == s1, target == t2) )<br> then<br>
insertLogical( new Reach(e.getSource(),r.getTarget()) );<br> System.out.println( "Reach " + e.getSource() + "," + r.getTarget() );<br>end<br><br>TransitiveClosureExample.java :<br><br>package org.drools.examples;<br>
import java.io.InputStreamReader;<br>import org.drools.RuleBase;<br>import org.drools.RuleBaseFactory;<br>import org.drools.StatefulSession;<br>import org.drools.audit.WorkingMemoryFileLogger;<br>import org.drools.compiler.PackageBuilder;<br>
import org.drools.compiler.PackageBuilderConfiguration;<br><br>public class TransitiveClosureExample {<br> public static void main(final String[] args) throws Exception {<br> PackageBuilderConfiguration conf = new PackageBuilderConfiguration();<br>
final PackageBuilder builder = new PackageBuilder( conf );<br> builder.addPackageFromDrl( new InputStreamReader(<br>TransitiveClosureExample.class.getResourceAsStream(<br>"TransitiveClosure.drl" ) ) );<br>
final RuleBase ruleBase = RuleBaseFactory.newRuleBase();<br> ruleBase.addPackage( builder.getPackage() );<br> final StatefulSession session = ruleBase.newStatefulSession();<br> final WorkingMemoryFileLogger logger = new<br>
WorkingMemoryFileLogger( session );<br> logger.setFileName( "log/transitiveClosure" );<br><br> final Edge edgeAB = new Edge( "a","b" );<br> final Edge edgeBC = new Edge( "b","c" );<br>
final Edge edgeCD = new Edge( "c","d" );<br><br> session.insert( edgeAB );<br> session.insert( edgeBC );<br> session.insert( edgeCD );<br><br> session.fireAllRules();<br>
logger.writeToDisk();<br> session.dispose();<br> }<br><br> public static class Edge {<br> private String source;<br> private String target;<br> public Edge() {}<br> public Edge(String source, String target) {<br>
super();<br> this.source = source;<br> this.target = target;<br> }<br> public String getSource() {<br> return source;<br> }<br> public String getTarget() {<br>
return source;<br> }<br> }<br><br> public static class Reach {<br> private String source;<br> private String target;<br> public Reach() {}<br> public Reach(String source, String target) {<br>
super();<br> this.source = source;<br> this.target = target;<br> }<br> public void setSource(String source) {<br> this.source = source;<br> }<br> public String getSource() {<br>
return source;<br> }<br> public void setTarget(String target) {<br> this.target = target;<br> }<br> public String getTarget() {<br> return target;<br> }<br> }<br>
}<br><br>Any sugestion?<br><br>Regards,<br>Paul Fodor<br>_______________________________________________<br>rules-users mailing list<br><a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br><a href="https://lists.jboss.org/mailman/listinfo/rules-users">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</blockquote></div><br><br clear="all"><br>-- <br> Edson Tirelli<br> JBoss Drools Core Development<br> Office: +55 11 3529-6000<br> Mobile: +55 11 9287-5646<br> JBoss, a division of Red Hat @ <a href="http://www.jboss.com">www.jboss.com</a>