On Thu, Apr 16, 2009 at 1:18 PM, Greg Barton <greg_bar...@yahoo.com> wrote:
> > This is not a problem with negation. I don't think you understand rule > conflict resolution. > > Here's your rule: > > rule "direct" > when > m : Move(x : first, y : second) > not Win(first == y) > then > insert(new Win(m.getFirst())); > end > > This rule, regardles of whether it uses negation, will be affected by fact > insertion order. This is because the first condition will match on any Move > in working memory. When all of the potential firings of this rule are put > on the agenda, which will initially be one for each Move in working memory, > one must be selected to fire. The order of fact insertion (recency) is one > of the ways Drools resolves this by default. Thank you. I see. > If you don't want that behavior you can change it by using a different > conflict resolver instance. See classes in the package org.drools.conflict: > > > https://hudson.jboss.org/hudson/job/drools/lastSuccessfulBuild/artifact/trunk/target/javadocs/unstable/drools-core/org/drools/conflict/package-summary.html Or define your own. That is very dificult task. The win-nowin test was just an example of use of the default negation. My requirement covers stratified or non-stratified logic programs, and not one example in particular. I don't really think that it is possible to implement a general "rule conflict resolution" resolver for default negation. This is hard in production rule systems. Paul. > You can install a new one by calling either of these methods on your > RuleBaseConfiguration: > > setProperty("drools.conflictResolver", <resolver class name>) > > or > > setConflictResolver(<an instance of ConflictResolver>) > > --- On Thu, 4/16/09, Paul Fodor <paul.i.fo...@gmail.com> wrote: > > > From: Paul Fodor <paul.i.fo...@gmail.com> > > Subject: [rules-users] Negation semantics in Drools > > To: "Rules Users List" <rules-users@lists.jboss.org> > > Date: Thursday, April 16, 2009, 10:43 AM > > Dear Sir, > > > > I found a problem with negation in Drools when changing the > > order of the > > facts in the database also changes the final model. > > Consider the classic win-nowin problem encoded in Drools as > > follows: > > > > win.drl: > > > > package tests; > > import tests.Test.Win; > > import tests.Test.Move; > > rule "direct" > > when > > m : Move(x : first, y : second) > > not Win(first == y) > > then > > insert(new Win(m.getFirst())); > > end > > > > With two moves in the database: move(1,2) and move(2,3), > > for one order of the facts in the input file we get one > > result: win(2), > > while for the other order (i.e., move(2,3) and move(1,2)) > > we get 2 results: > > win(1) and win(2). > > > > For win_upper1_drools.drools: > > > java tests.Test win_upper1_drools.drools win.drl > > result > > reading rulefile: win.drl ... > > reading datafile: win_upper1_drools.drools ... > > computing cputime: 0.0 > > computing walltime: 0.0030 > > Derived facts in memory:move(1, 2). > > win(2). > > move(2, 3). > > 3 > > > > For win_upper2_drools.drools: > > > java tests.Test win_upper2_drools.drools win.drl > > result > > reading rulefile: win.drl ... > > reading datafile: win_upper2_drools.drools ... > > computing cputime: 0.0 > > computing walltime: 0.0040 > > Derived facts in memory:win(1). > > win(2). > > move(1, 2). > > move(2, 3). > > 4 > > > > I attached all the sources used in these tests in the > > email. This example is > > locally stratified. I am using the latest released version > > of Drools. > > > > Regards, > > Paul Fodor > > > > win.drl: > > > > package tests; > > import tests.Test.Win; > > import tests.Test.Move; > > rule "direct" > > when > > m : Move(x : first, y : second) > > not Win(first == y) > > then > > insert(new Win(m.getFirst())); > > end > > > > > > win_upper1_drools.drools: > > > > move > > 1 > > 2 > > move > > 2 > > 3 > > > > win_upper2_drools.drools: > > > > move > > 2 > > 3 > > move > > 1 > > 2 > > > > Test.java: > > > > package tests; > > import java.io.*; > > import java.io.InputStreamReader; > > import org.drools.RuleBase; > > import org.drools.RuleBaseFactory; > > import org.drools.StatefulSession; > > import org.drools.compiler.PackageBuilder; > > import org.drools.FactHandle; > > import java.util.Iterator; > > import java.lang.management.ManagementFactory; > > import java.lang.management.ThreadMXBean; > > public class Test { > > public static void main (String args[]) { > > if (args.length < 3) { > > usage(); > > } > > long starttime_cpu, endtime_cpu, starttime_sys, > > endtime_sys; > > double cputime, walltime; > > ThreadMXBean tb_cpu = ManagementFactory.getThreadMXBean(); > > // create rulebase > > try { > > FileWriter output = new FileWriter(args[2]); > > BufferedWriter bufWrite = new BufferedWriter(output); > > bufWrite.write(args[0] + "\n"); > > bufWrite.flush(); > > System.out.println("reading rulefile: " + > > args[1] + " ..."); > > Reader source = new > > InputStreamReader(Test.class.getResourceAsStream(args[1])); > > final PackageBuilder builder = new PackageBuilder(); > > builder.addPackageFromDrl(source); > > if (builder.hasErrors()) { > > System.out.println(builder.getErrors().toString()); > > System.exit(0); > > } > > final RuleBase ruleBase = > > RuleBaseFactory.newRuleBase(); > > ruleBase.addPackage(builder.getPackage()); > > final StatefulSession session = > > ruleBase.newStatefulSession(); > > // loading datafile > > System.out.println("reading datafile: " + > > args[0] + " ..."); > > FileReader input = new FileReader(args[0]); > > starttime_sys = System.nanoTime(); > > starttime_cpu = tb_cpu.getCurrentThreadCpuTime(); > > BufferedReader bufRead = new BufferedReader(input); > > String first, second, line = bufRead.readLine(); > > while (line != null) { > > if (line.compareTo("move") == 0) { > > first = bufRead.readLine(); > > second = bufRead.readLine(); > > session.insert(new Move(first, second)); > > } > > else if (line.compareTo("par") == 0) { > > first = bufRead.readLine(); > > second = bufRead.readLine(); > > session.insert(new ClassPar(first, second)); > > } > > else if (line.compareTo("sib") == 0) { > > first = bufRead.readLine(); > > second = bufRead.readLine(); > > session.insert(new ClassSib(first, second)); > > } > > line = bufRead.readLine(); > > } > > endtime_cpu = tb_cpu.getCurrentThreadCpuTime(); > > endtime_sys = System.nanoTime(); > > cputime = (endtime_cpu - starttime_cpu) * 1e-9; > > cputime = Math.round(cputime * 1000) * 1e-3; > > walltime = (endtime_sys - starttime_sys) * 1e-9; > > walltime = Math.round(walltime * 1000) * 1e-3; > > bufWrite.write("loading cputime: " + cputime > > + "\n"); > > bufWrite.write("loading walltime: " + > > walltime + "\n"); > > bufWrite.flush(); > > System.out.println("loading cputime: " + > > cputime); > > System.out.println("loading walltime: " + > > walltime); > > /* > > System.out.print("Facts in memory:"); > > long count = 0; > > for (Iterator it = session.iterateFactHandles(); > > it.hasNext(); ) { > > FactHandle factHandle = (FactHandle) it.next(); > > count ++; > > //System.out.println(session.getObject(factHandle)); > > } > > System.out.println(count); > > */ > > // computing > > System.out.println("calculating ..."); > > starttime_sys = System.nanoTime(); > > starttime_cpu = tb_cpu.getCurrentThreadCpuTime(); > > session.fireAllRules(); > > endtime_cpu = tb_cpu.getCurrentThreadCpuTime(); > > endtime_sys = System.nanoTime(); > > cputime = (endtime_cpu - starttime_cpu) * 1e-9; > > cputime = Math.round(cputime * 1000) * 1e-3; > > walltime = (endtime_sys - starttime_sys) * 1e-9; > > walltime = Math.round(walltime * 1000) * 1e-3; > > bufWrite.write("computing cputime: " + > > cputime + "\n"); > > bufWrite.write("computing walltime: " + > > walltime + "\n"); > > bufWrite.flush(); > > System.out.println("computing cputime: " + > > cputime); > > System.out.println("computing walltime: " + > > walltime); > > System.out.print("Derived facts in > > memory:"); > > long count1 = 0; > > for (Iterator it = session.iterateFactHandles(); > > it.hasNext(); ) { > > FactHandle factHandle = (FactHandle) it.next(); > > count1 ++; > > System.out.println(session.getObject(factHandle)); > > } > > System.out.println(count1); > > bufWrite.close(); > > session.dispose(); > > } catch (Exception e) { > > System.out.println("Exception encountered when > > computing:"); > > System.out.println(e); > > System.exit(0); > > } > > } > > static void usage() { > > System.out.println("usage:"); > > System.out.println("java Test <data_file> > > <rule_file> <result_file>"); > > System.exit(0); > > } > > public static class General { > > private String first; > > private String second; > > public General() {} > > public General(String firstIn, String secondIn) { > > this.first = firstIn; > > this.second = secondIn; > > } > > public String getFirst() { > > return this.first; > > } > > public String getSecond() { > > return this.second; > > } > > } > > public static class Move extends General { > > public Move() { > > super(); > > } > > public Move(String firstIn, String secondIn) { > > super(firstIn, secondIn); > > } > > public String toString() { > > return "move(" + this.getFirst() + ", > > " + this.getSecond() + ")."; > > } > > } > > public static class Win { > > private String first; > > public Win() {} > > public Win(String firstIn) { > > this.first = firstIn; > > } > > public String getFirst() { > > return this.first; > > } > > public String toString() { > > return "win(" + this.getFirst() + > > ")."; > > } > > } > > } > > _______________________________________________ > > rules-users mailing list > > rules-users@lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/rules-users > > > > _______________________________________________ > rules-users mailing list > rules-users@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/rules-users >
_______________________________________________ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users