[rules-users] Negation semantics in Drools
Paul Fodor
paul.i.fodor at gmail.com
Thu Apr 16 11:43:00 EDT 2009
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() + ").";
}
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20090416/bac9aeb0/attachment.html
More information about the rules-users
mailing list