[rules-users] Negation semantics in Drools

Paul Fodor paul.i.fodor at gmail.com
Thu Apr 16 14:30:17 EDT 2009


On Thu, Apr 16, 2009 at 1:18 PM, Greg Barton <greg_barton at 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.fodor at gmail.com> wrote:
>
> > From: Paul Fodor <paul.i.fodor at gmail.com>
> > Subject: [rules-users] Negation semantics in Drools
> > To: "Rules Users List" <rules-users at 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 at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/rules-users
>
>
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20090416/128f4e94/attachment.html 


More information about the rules-users mailing list