package org.drools.examples.benchmarks.waltz;
/*
* $Id: WaltzBenchmark.java,v 1.4 2005/12/30 05:38:32 michaelneale Exp $
*
* Copyright 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 registered trademark of The Werken Company.
*
* 5. Due credit should be given to The Werken Company.
* (http://drools.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.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import org.drools.DroolsException;
import org.drools.FactException;
import org.drools.RuleBase;
import org.drools.WorkingMemory;
import org.drools.conflict.ComplexityConflictResolver;
import org.drools.conflict.CompositeConflictResolver;
import org.drools.conflict.LoadOrderConflictResolver;
import org.drools.examples.benchmarks.waltz.model.Line;
import org.drools.examples.benchmarks.waltz.model.Stage;
import org.drools.io.ReteDumper;
import org.drools.io.RuleBaseLoader;
import org.drools.io.RuleSetLoader;
import org.drools.spi.ConflictResolver;
import org.xml.sax.SAXException;
/**
* A Drools implementation of the Waltz benchmark,
* a part of the OPS5 Benchmark Suite available at:<br/>
* http://www.cs.utexas.edu/ftp/pub/ops5-benchmark-suite/<br/>
* ftp://ftp.cs.utexas.edu/pub/ops5-benchmark-suite/
*/
public class WaltzBenchmark
{
/**
* The DRL file contains the Drools implementation
* of the Waltz rules.
*/
private static final String DRL_FILE = "waltz.drl";
/**
* A GraphViz DOT file created to show the resulting Rete Graph
* generated by the DRL rules.
*/
private static final String DOT_FILE = "waltz.dot";
/**
* List of org.drools.examples.benchmarks.waltz.model.* objects
* read from the provided *.dat data file and to be asserted into the
* WorkingMemory.
*/
private List inputObjects;
/**
* The <code>WorkingMemory</code> generated by the rules in the DRL file.
*/
private WorkingMemory workingMemory;
/**
* Creates a new <code>WaltzBenchmark</code> object and executes its
* <code>run</code> method.
*
* @param args if an argument is provided,
* it is used as the name of the *.dat data file to use.
*/
public static void main(String[] args) throws DroolsException,
IOException,
SAXException
{
String datFile = "waltz0.dat";
if ( args.length > 0 )
{
datFile = args[0];
}
WaltzBenchmark benchmark = new WaltzBenchmark( datFile );
long start = System.currentTimeMillis();
benchmark.run();
System.out.println( "Elapsed time: " + (System.currentTimeMillis() - start) + " ms" );
}
/**
* Read the DRL and DAT files, output the Rete to a DOT file,
* and initialize a <code>WorkingMemory</code>.
*
* @param datFile the input data file
*/
public WaltzBenchmark(String datFile) throws DroolsException,
IOException,
SAXException
{
System.out.println( "Loading DRL: " + DRL_FILE + "..." );
RuleSetLoader ruleSetLoader = new RuleSetLoader();
ruleSetLoader.addFromUrl( WaltzBenchmark.class.getResource( DRL_FILE ) );
RuleBaseLoader ruleBaseLoader = new RuleBaseLoader( new CompositeConflictResolver( new ConflictResolver[]{ComplexityConflictResolver.getInstance(), LoadOrderConflictResolver.getInstance()} ) );
ruleBaseLoader.addFromRuleSetLoader( ruleSetLoader );
RuleBase ruleBase = ruleBaseLoader.buildRuleBase();
File dotFile = new File( DOT_FILE );
System.out.println( "Creating DOT: " + dotFile.getCanonicalPath() + "..." );
new ReteDumper( ruleBase ).dumpReteToDot( new PrintStream( new FileOutputStream( dotFile ) ) );
this.workingMemory = ruleBase.newWorkingMemory();
this.workingMemory.addEventListener( new WaltzWMEL() );
System.out.println( "Reading DAT: " + datFile + "..." );
this.inputObjects = getInputObjects( this.getClass().getResourceAsStream( datFile ) );
}
/**
* Assert the facts and fire the rules.
*/
public void run() throws FactException
{
System.out.println( "Asserting initial objects..." );
for ( Iterator i = this.inputObjects.iterator(); i.hasNext(); )
{
this.workingMemory.assertObject( i.next() );
}
System.out.println( "Firing all rules..." );
this.workingMemory.fireAllRules();
}
/**
* Convert the facts from the <code>InputStream</code> to a list of
* objects.
*/
private static List getInputObjects(InputStream inputStream) throws IOException
{
List list = new ArrayList();
BufferedReader br = new BufferedReader( new InputStreamReader( inputStream ) );
String line = null;
while ( (line = br.readLine()) != null )
{
if ( line.trim().length() == 0 || line.trim().startsWith( ";" ) )
{
continue;
}
StringTokenizer st = new StringTokenizer( line,
"() " );
String make = st.nextToken();
if ( !"make".equals( make ) )
{
throw new IOException( "expected 'make' in: " + line );
}
String type = st.nextToken();
if ( "line".equals( type ) )
{
if ( !"^p1".equals( st.nextToken() ) )
{
throw new IOException( "expected '^p1' in: " + line );
}
int p1 = Integer.parseInt( st.nextToken() );
if ( !"^p2".equals( st.nextToken() ) )
{
throw new IOException( "expected '^p2' in: " + line );
}
int p2 = Integer.parseInt( st.nextToken() );
list.add( new Line( p1,
p2 ) );
}
if ( "stage".equals( type ) )
{
if ( !"^value".equals( st.nextToken() ) )
{
throw new IOException( "expected '^value' in: " + line );
}
list.add( new Stage( st.nextToken() ) );
}
}
inputStream.close();
return list;
}
}