Package org.drools.examples.primefactors

Source Code of org.drools.examples.primefactors.PrimeFactors

package org.drools.examples.primefactors;

/*
* $Id: PrimeFactors.java,v 1.7 2005/02/04 02:13:37 mproctor Exp $
*
* Copyright 2004-2004 (C) The Werken Company. All Rights Reserved.
*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "drools" must not be used to endorse or promote products derived
* from this Software without prior written permission of The Werken Company.
* For written permission, please contact bob@werken.com.
*
* 4. Products derived from this Software may not be called "drools" nor may
* "drools" appear in their names without prior written permission of The Werken
* Company. "drools" is a trademark of The Werken Company.
*
* 5. Due credit should be given to The Werken Company. (http://werken.com/)
*
* THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE WERKEN COMPANY OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.zip.GZIPInputStream;

import org.drools.RuleBase;
import org.drools.RuleBaseBuilder;
import org.drools.WorkingMemory;
import org.drools.io.RuleSetReader;
import org.drools.rule.Declaration;
import org.drools.rule.Rule;
import org.drools.rule.RuleSet;
import org.drools.semantics.base.ClassObjectType;

public class PrimeFactors
{
    /** A list of the first X primes. */
    private static final String          PRIMES_FILE   = "primes.txt.gz";

    /** . */
    private static final String          DRL_FILE      = "primes.java.drl";

    /** . */
    private static final ClassObjectType numberType    = new ClassObjectType( Number.class );

    /** Default number of numberOfRules. */
    private static int                   numberOfRules = 100;

    /** Default number of numberOfFacts. */
    private static int                   numberOfFacts = 1000;

    /** Default random seed. */
    private static long                  randomSeed    = 0;

    /** Set this to true to generate additional output. */
    private static boolean               verbose       = false;

    /** An array of the first X prime numbers. */
    private static int[]                 primes;

    /** Used for recording elapsed time measurements. */
    private static long[]                timepoint     = new long[2];

    /**
     * The main method where all the magic happens.
     */
    public static void main(String[] args) throws Exception
    {
        // Parse input arguments:
        // - Number of Rules (args[0])
        if ( args.length > 0 )
        {
            numberOfRules = Integer.parseInt( args[0] );
        }
        if ( numberOfRules < 1 )
        {
            System.out
                      .println( "Please enter a number creater than 0 for the number of rules" );
            return;
        }
        System.out.println( "Number of Rules: " + numberOfRules );

        // - Number of Facts (args[1])
        if ( args.length > 1 )
        {
            numberOfFacts = Integer.parseInt( args[1] );
        }
        if ( numberOfFacts < 0 )
        {
            System.out
                      .println( "Please enter a positive value for the number of facts." );
            return;
        }
        System.out.println( "Number of Facts: " + numberOfFacts );

        // - Random Seed (args[2])
        if ( args.length > 2 )
        {
            randomSeed = Long.parseLong( args[2] );
        }
        if ( -1 == randomSeed )
        {
            randomSeed = System.currentTimeMillis( );
        }
        System.out.println( "Random Seed: " + randomSeed );

        // - Verbose Output (args[3])
        if ( args.length > 3 )
        {
            verbose = Boolean.valueOf( args[3] ).booleanValue( );
        }
        System.out.println( "Verbose Output: " + verbose );

        // Dynamically construct rules based on Array of prime numbers
        RuleSet ruleSet = new RuleSet( "Find Prime Number" );

        verbose( "" );
        verbose( "Reading " + numberOfRules + " primes..." );
        stopwatch( 0 );
        readPrimes( );
        verbose( "Read " + numberOfRules + " primes" + stopwatch( 0 ) );

        verbose( "Creating " + numberOfRules + " rules..." );
        for ( int i = 0; i < numberOfRules; i++ )
        {
            Rule rule = new Rule( "Factor by " + primes[i] );

            Declaration numberDecl = rule.addParameterDeclaration( "number", numberType );
            rule.addCondition( new FactorCondition( numberDecl, primes[i] ) );
            rule.setConsequence( new FactorConsequence( numberDecl, primes[i] ) );
            ruleSet.addRule( rule );
        }
        verbose( "Created " + numberOfRules + " rules" + stopwatch( 0 ) );

        // Build the RuleSets.
        verbose( "Building RuleBase with " + numberOfRules + " rules..." );
        RuleBaseBuilder builder = new RuleBaseBuilder( );
        builder.addRuleSet( ruleSet );
        builder.addRuleSet( new RuleSetReader( ).read( PrimeFactors.class.getResource( DRL_FILE ) ) );
        RuleBase ruleBase = builder.build( );
        verbose( "Built RuleBase with " + numberOfRules + " rules"
                 + stopwatch( 0 ) );

        // Determine random set of Facts to assert
        verbose( "Generating " + numberOfFacts + " random numbers to assert..." );
        Random random = new Random( randomSeed );
        int[] factValues = new int[numberOfFacts];
        for ( int i = 0; i < numberOfFacts; i++ )
        {
            factValues[i] = random.nextInt( primes[numberOfRules - 1] ) + 1;
            if ( factValues[i] < 1 )
            {
                // Random() should only return numbers greater than or equal to
                // 1
                System.out.println( "Programmer Error: factValues[" + i + "]="
                                    + factValues[i] );
                return;
            }
        }
        primes = null; // Free up unused memory
        verbose( "Generated " + numberOfFacts + " random numbers to assert"
                 + stopwatch( 0 ) );

        // Example 1
        System.out.println( );
        System.out
                  .println( "== Example #1 ========================================" );
        System.out.println( "foreach Number {" );
        System.out.println( "    new WorkingMemory();" );
        System.out.println( "    assertObject();" );
        System.out.println( "    fireAllRules();" );
        System.out.println( "}" );
        System.out
                  .println( "======================================================" );
        List results = new LinkedList( );
        stopwatch( 0 );
        for ( int i = 0; i < numberOfFacts; i++ )
        {
            stopwatch( 1 );
            WorkingMemory workingMemory = ruleBase.newWorkingMemory( );

            Number fact = new Number( factValues[i] );
            workingMemory.assertObject( fact );
            workingMemory.fireAllRules( );
            results.addAll( workingMemory.getObjects( ) );

            verbose( fact + ":" + stopwatch( 1 ) );
        }

        System.out.println( "Total time:" + stopwatch( 0 ) );
        validate( results );

        // Example 2
        System.out.println( );
        System.out
                  .println( "== Example #2 ========================================" );
        System.out.println( "new WorkingMemory();" );
        System.out.println( "foreach Number {" );
        System.out.println( "    assertObject();" );
        System.out.println( "    fireAllRules();" );
        System.out.println( "}" );
        System.out
                  .println( "======================================================" );
        WorkingMemory workingMemory = ruleBase.newWorkingMemory( );

        stopwatch( 0 );
        for ( int i = 0; i < numberOfFacts; i++ )
        {
            stopwatch( 1 );

            Number fact = new Number( factValues[i] );
            workingMemory.assertObject( fact );
            workingMemory.fireAllRules( );

            verbose( fact + ":" + stopwatch( 1 ) );
        }

        System.out.println( "Total time:" + stopwatch( 0 ) );
        validate( workingMemory.getObjects( ) );

        // Example 3
        System.out.println( );
        System.out
                  .println( "== Example #3 ========================================" );
        System.out.println( "new WorkingMemory();" );
        System.out.println( "foreach Number {" );
        System.out.println( "    assertObject();" );
        System.out.println( "}" );
        System.out.println( "fireAllRules()" );
        System.out
                  .println( "======================================================" );
        workingMemory = ruleBase.newWorkingMemory( );

        verbose( "Asserting " + numberOfFacts + " facts..." );
        stopwatch( 0 );

        for ( int i = 0; i < numberOfFacts; i++ )
        {
            workingMemory.assertObject( new Number( factValues[i] ) );
        }
        verbose( "Firing all rules..." );
        workingMemory.fireAllRules( );

        if ( verbose )
        {
            for ( Iterator i = workingMemory.getObjects( ).iterator( ); i.hasNext(); )
            {
                System.out.println( i.next( ) );
            }
        }

        System.out.println( "Total time:" + stopwatch( 0 ) );
        validate( workingMemory.getObjects( ) );
    }

    /**
     * Reads (optionally GZipped) file of prime numbers, one prime per line.
     */
    private static void readPrimes()
    {
        primes = new int[numberOfRules];
        try
        {
            BufferedReader br = new BufferedReader( new InputStreamReader( new GZIPInputStream(
                    PrimeFactors.class.getResource( PRIMES_FILE ).openStream() ) ) );

            String line;
            for ( int i = 0; i < numberOfRules; i++ )
            {
                if ( null == ( line = br.readLine( ) ) )
                {
                    throw new IOException( PRIMES_FILE + " only contained " + i
                                           + " primes" );
                }
                primes[i] = Integer.parseInt( line );
            }
        }
        catch ( IOException e )
        {
            throw new RuntimeException( "Cannot access " + PRIMES_FILE
                                        + " properly: " + e.getMessage( ) );
        }
    }

    /**
     * Validates that the product of the factors of each Number in the list
     * equals the number itself.
     */
    private static void validate(List objects)
    {
        for ( Iterator i = objects.iterator( ); i.hasNext( ); )
        {
            int product = 1;
            Number number = ( Number ) i.next( );

            if ( 1 != number.getQuotient( ) )
            {
                throw new RuntimeException( "Error: Quotient != 1: " + number );
            }

            for ( Iterator j = number.getFactors( ).iterator( ); j.hasNext( ); )
            {
                int factor = ( ( Integer ) j.next( ) ).intValue( );
                product *= factor;
            }

            if ( number.getValue( ) != product )
            {
                throw new RuntimeException(
                                            "Error: Product of factors doesn't equal number: "
                                                                                                                                                                                + number );
            }
        }
    }

    private static String stopwatch(int i)
    {
        long now = System.currentTimeMillis( );
        String message = " [" + ( now - timepoint[i] ) / 1000 + " secs]";
        timepoint[i] = now;
        return message;
    }

    /**
     * Helper method for printing out verbose messages.
     */
    private static void verbose(String message)
    {
        if ( verbose )
        {
            System.out.println( message );
        }
    }
}
TOP

Related Classes of org.drools.examples.primefactors.PrimeFactors

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.