Hi,
 I am conducting a test of Jess where I am inserting 10,000 rules -
each matching a particular modulus of a prime number and then calling
code to aggregate prime roots of those numbers being matched. The test
submits 100 random numbers one by one - each matching against one of
the 10,000 rules - and the result is timed. It is a test I grabbed
from one of the tests in the drools package which basically stress
tests the rule engine and outputs timing results. I am doing this to
compare the total computation time between Drools and Jess - and Jess
is about 6 times slower, but I think the problem may not be Jess
itself but either how my rules are constructed or some problem where
Jess isn't flushing the I/O stream properly.

Of particular note are the prepareConstructs() method where the rules
are being built, and the execute() method where the rule engine is
iteratively being invoked.

I am attaching an executable Jar file which can be run via the
command: java -jar primeNumTest.jar  -or- java -cp primeNumTest.jar
PrimeFactorsTest

Also, I am attaching the two java source files to this message.
Program flow is pretty easy to follow looking at the "main" method in
PrimeFactorsTest.java.

I am very interested in using Jess and am evaluating its usage for my
company, but this initial test presents some problems...

Can anyone take a look at this and maybe tell me or point to what the
problem may be?

I'm a first-time majordomo user, and I seem to have a problem with
posting (I guess
you can't use attachments?) So I'm posting the 2 java source files inline below,
which can be compiled and run against jess.jar

Thanks ahead of time,
David

====================



import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Random;

import jess.JessException;
import jess.Rete;
import jess.Value;


/**
 * By default, creates 10,000 rules each matching a single prime number -
 * then inserts 100 random integers into the engine and collects those
 * rules which have fired, and all their roots outputting the timing
 * for each stage and each calculation.
 *
 * See the main() method (at the bottom) for program flow.
 *
 * @author David Ray
 */
public class PrimeFactorsTest
{
   private long seed;
   private long start;
   private long total;
   private int numRules;
   private int[] primes;
   private int[] randomNumbers;
   private Rete rete;
   private static long[] timepoint = new long[2];

       PrimeFactorsTest(int seed)
       {
               this.seed = seed;
               this.rete = new Rete();
       }

       /**
        * Generates "numFacts" number of random numbers.
        *
        * @param numFacts
        */
       public void createRandomNums(int numFacts)
       {
               System.out.println("Generating random number knowledge...");
           Random rand = new Random(seed);
           randomNumbers = new int[numFacts];
           start = System.currentTimeMillis();
           for(int i = 0;i < numFacts;i++) {
             int nextRand = rand.nextInt(primes[numRules - 1])  + 1;
             if(nextRand < 1) {--i; continue;}
             randomNumbers[i] = nextRand;
           }
           total = (System.currentTimeMillis() - start);
           System.out.println("Generated "+numFacts+" random numbers in
["+total+" msecs.]");
       }

       /**
        * Inserts a "Jess" formatted command into the Jess Rete engine.
        *
        * @param statement
        * @return      Value   A jess.Value object representing the
result obtained
        *                                      from executing the
specified statement.
        */
       public Value insertStatement(String statement)
       {
               Value retVal = null;
               try {
                       retVal  = rete.eval(statement);
           }catch(JessException e) {
               e.printStackTrace();
           }
           return retVal;
       }

       /**
        * Inserts 10,000 rules into the working memory - each representing
        * a "pattern" which will only activate if the LHS is true (meaning
        * that the unique prime number correlated with each rule is a prime
        * root of the asserted random number).
        */
       public void prepareConstructs()
       {
               /////////////////////////////////////////////
               //Used for debugging
               //String statement = "(watch all)";
               //insertStatement(statement);

               System.out.println("-----------------------");

               System.out.println("Creating New RuleBase...");
           start = System.currentTimeMillis();

               String statement = "(deftemplate RandomNumber (declare
(from-class
RandomNumber)))";
               insertStatement(statement);

               for(int divisor : primes)
               {
                       statement = "(defrule modulus"+divisor+
                               " (RandomNumber (value ?x))" +
                               " (test (eq 0 (mod ?x "+divisor+")))"+
                               "=>"+
                               "(call ?a extractRoots "+divisor+"))";

                       insertStatement(statement);
               }

               total = (System.currentTimeMillis() - start) / 1000;
           System.out.println("Created new RuleBase with "+numRules+" rules
in ["+total+" secs.]");
       }

       /**
        * Binds a new RandomNumber object containing a unique random
        * number. Then adds the random number fact causing the matching
        * rules to activate. Following this, "run" is called to actually
        * fire the rules. The "bound" RandomNumber (and the contained
        * prime roots) are then printed out and "retract" is called to
        * "clear" the working memory of the last fact and the process
        * then continues until all RandomNumbers have been processed.
        */
       public void execute()
       {
               System.out.println("-----------------------");
               System.out.println("Starting test...");
           total = 0;

           stopwatch(0);

           for(int randNum : randomNumbers)
               {
               stopwatch( 1 );

                       String statement = "(bind ?a (new RandomNumber
"+randNum+"))";
                       insertStatement(statement);

                       //Add a Fact causing Activation to happen here.
                       statement = "(add ?a)";
                       insertStatement(statement);

                       //Rule Fire happens here.
                       statement = "(run)";
                       insertStatement(statement);

                       statement = "(printout t (call ?a toString) :
"+stopwatch( 1 )+" crlf)";
                       insertStatement(statement);

                       statement = "(retract 1)";
                       insertStatement(statement);
               }

           System.out.println("Total Engine Time: " + stopwatch(0));
       }

       /**
        * Reads a file containing "numRules" number of prime numbers into
        * an array which is later used to generate a unique rule for each
        * prime number.
        *
        * @param numRules
        */
       public void loadPrimeList(int numRules)
       {
           this.numRules = numRules;
           BufferedReader buf = null;
           try {
                 buf = new BufferedReader(
                   new InputStreamReader(

getClass().getClassLoader().getResourceAsStream("1100000-primes.txt")));
                 String line = null;
                 int count = 0;
                 System.out.println("Reading "+numRules+" Prime Numbers");
                 start = System.currentTimeMillis();
                 primes = new int[numRules];
                 while((line = buf.readLine()) != null && ((count) <
numRules)) {
                   primes[count++] = Integer.parseInt(line.trim());
                 }
                 total = (System.currentTimeMillis() - start);
                 System.out.println("Read "+primes.length+" Prime Numbers
["+total+" msecs.]");
           }
           catch(Exception e) { e.printStackTrace(); }
           finally {
             try { buf.close(); }catch(Exception ignore) {}
           }
       }

       /**
        * Returns and records time points specified by the index "i"
        * passed in.
        *
        * @param i
        * @return message      A formatted String containing the
specified time point.
        */
       private static String stopwatch(int i)
       {
       long now = System.currentTimeMillis( );
           String message = " [" + ( now - timepoint[i] )  + " msecs]";
           timepoint[i] = now;
           return message;
       }

       public static void main(String[] args)
       {
               int seed = 0;
               int numRules = 10000;
               int numFacts = 100;

               if(args != null && args.length == 3) {
                       seed = Integer.parseInt(args[2]);
                       numRules = Integer.parseInt(args[0]);
                       numFacts = Integer.parseInt(args[1]);
               }

               PrimeFactorsTest pft = new PrimeFactorsTest(seed);
           System.out.println("Number of Rules: "+numRules);
           System.out.println("Number of Facts: "+numFacts);
           System.out.println("Random Seed: "+seed);

           pft.loadPrimeList(numRules);
           pft.createRandomNums(numFacts);

               pft.prepareConstructs();
               pft.execute();
       }
}

===================



import java.util.ArrayList;
import java.util.List;

/**
 * Stores a random integer value and can extract and store multiples of
 * a specified prime root correlated to the original initialized value.
 *
 * @author davidray
 */
public class RandomNumber {

       Integer value;
       int quotient = 1;
       List<Integer> primeList = new ArrayList<Integer>();

       public RandomNumber() {}

       public RandomNumber(Integer number)
       {
               this.value = number;
               this.quotient = number.intValue();
       }

       /**
        * Operates on this <code>RandomNumber</code>'s value using the
        * specified prime root by extracting the greatest number of the
        * specified prime root, saving each root in a list of roots.
        *
        * @param primeRoot
        */
       public void extractRoots(Integer primeRoot)
       {
               quotient = value.intValue();
               int pFactor = primeRoot.intValue();
               do {
                       primeList.add(primeRoot);
                       quotient = quotient / pFactor;
               } while(quotient % pFactor == 0);
       }

       /**
        * Returns the original value with which this
<code>RandomNumber</code> was
        * initialized.
        *
        * @return Integer      the original value.
        */
       public Integer getValue()
       {
               return value;
       }

       @Override
       public int hashCode() {
               final int prime = 31;
               int result = 1;
               result = prime * result + ((value == null) ? 0 :
value.hashCode());
               return result;
       }

       @Override
       public boolean equals(Object obj) {
               if (this == obj)
                       return true;
               if (obj == null)
                       return false;
               if (getClass() != obj.getClass())
                       return false;
               RandomNumber other = (RandomNumber) obj;
               if (value == null) {
                       if (other.value != null)
                               return false;
               } else if (!value.equals(other.value))
                       return false;
               return true;
       }

       @Override
       public String toString()
       {
               return "Number ("+value+")  Prime Numbers: "+primeList;
       }
}

=======================


--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [email protected]'
in the BODY of a message to [email protected], NOT to the list
(use your own address!) List problems? Notify [email protected].
--------------------------------------------------------------------

Reply via email to