Nov 01, 2005

[Library] Drools にチャレンジ

Drools とは

Drools は、 Charles Forgy's Rete algorithm をベースにした codehaus 謹製ルールエンジン。 JSR 94 にも準拠している。

Drools
http://drools.org/
Drools のサンプルコード
http://drools.org/Tutorials+and+Examples

Drools の実行環境構築

  1. Drools(drools-core-2.1.jar, drools-base-2.1.jar, drools-java-2.1.jar, drools-jsr94-2.1.jar, drools-io-2.1.jar, drools-smf-2.1.jar) をクラスパスに追加。
  2. その他必要なライブラリ (commons-logging-1.0.4.jar, jsr94-1.1.jar, jsr94-tck-1.1.jar, xercesImpl-2.6.2.jar, xml-apis-1.0b2.jar, antlr-2.7.5.jar, janino-2.3.8.jar) をクラスパスに追加

サンプルコード

Codelet.java (ここで使用している Rule は、Drools で公開されているサンプル)

package jp.in_vitro.codelets.drools;

import java.io.IOException;
import java.io.InputStream;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

import javax.rules.ConfigurationException;
import javax.rules.InvalidRuleSessionException;
import javax.rules.ObjectFilter;
import javax.rules.RuleExecutionSetNotFoundException;
import javax.rules.RuleRuntime;
import javax.rules.RuleServiceProvider;
import javax.rules.RuleServiceProviderManager;
import javax.rules.RuleSessionCreateException;
import javax.rules.RuleSessionTypeUnsupportedException;
import javax.rules.StatelessRuleSession;
import javax.rules.admin.RuleAdministrator;
import javax.rules.admin.RuleExecutionSet;
import javax.rules.admin.RuleExecutionSetCreateException;
import javax.rules.admin.RuleExecutionSetRegisterException;

import org.drools.jsr94.rules.RuleServiceProviderImpl;

public class Codelet {

    public Codelet() throws ConfigurationException {
        super();

        this.initializeRuleEngine();

    }

    public static void main(final String[] args) throws Exception {

        Codelet me = new Codelet();
        me.execute();
    }

    public void execute() throws RuleExecutionSetCreateException,
            RuleExecutionSetRegisterException, ConfigurationException,
            RemoteException, IOException, RuleSessionTypeUnsupportedException,
            RuleSessionCreateException, RuleExecutionSetNotFoundException,
            InvalidRuleSessionException {

        String uri = "res://sample.drl";
        String resource = "/"
                + Codelet.class.getPackage().getName().replaceAll("\\.", "/")
                + "/sample.drl";

        InputStream is = null;
        try {
            is = Codelet.class.getResourceAsStream(resource);
            this.loadRuleExecutionSet(uri, is);
        } finally {
            if (is != null) {
                is.close();
            }
        }

        // Fibonacci は下記のサンプルをそのまま利用。
        // http://drools.org/Fibonacci+Example
        List facts = new ArrayList();
        facts.add(new Fibonacci(50));
        List conclusions = this.executeRuleExecutionSet(uri, facts, null);
        for (Object conclusion : conclusions) {
            System.out.println("" + conclusion);
        }
    }

    protected void initializeRuleEngine() throws ConfigurationException {
        RuleServiceProviderManager.registerRuleServiceProvider(
                RuleServiceProviderImpl.class.getName(),
                RuleServiceProviderImpl.class);
    }

    protected RuleServiceProvider prepareRuleServiceProvider()
            throws ConfigurationException {
        RuleServiceProvider provider = RuleServiceProviderManager
                .getRuleServiceProvider(RuleServiceProviderImpl.class.getName());

        return provider;
    }

    protected void loadRuleExecutionSet(final String uri, final InputStream is)
            throws ConfigurationException, RuleExecutionSetCreateException,
            RemoteException, IOException, RuleExecutionSetRegisterException {
        RuleServiceProvider provider = this.prepareRuleServiceProvider();
        RuleAdministrator administrator = provider.getRuleAdministrator();

        RuleExecutionSet ruleSet = administrator
                .getLocalRuleExecutionSetProvider(null).createRuleExecutionSet(
                        is, null);
        administrator.registerRuleExecutionSet(uri, ruleSet, null);
    }

    protected List executeRuleExecutionSet(final String uri, final List facts,
            final ObjectFilter filter) throws ConfigurationException,
            RuleSessionTypeUnsupportedException, RuleSessionCreateException,
            RuleExecutionSetNotFoundException, RemoteException,
            InvalidRuleSessionException {

        RuleServiceProvider provider = this.prepareRuleServiceProvider();
        RuleRuntime runtime = provider.getRuleRuntime();
        StatelessRuleSession session = null;
        List conclusions = null;
        try {
            session = (StatelessRuleSession) runtime.createRuleSession(uri,
                    null, RuleRuntime.STATELESS_SESSION_TYPE);

            conclusions = session.executeRules(facts, filter);
        } finally {
            if (session != null) {
                session.release();
            }
        }

        return conclusions;
    }
}
sample.drl (ここで使用している Rule は、Drools で公開されているサンプル)
<?xml version="1.0"?>
<rule-set name="fibonacci"
          xmlns="http://drools.org/rules"
          xmlns:java="http://drools.org/semantics/java"
          xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
          xs:schemaLocation="http://drools.org/rules rules.xsd
                             http://drools.org/semantics/java java.xsd">
  
  <java:import>jp.in_vitro.codelets.drools.Fibonacci</java:import>
  
  <rule name="Recurse" salience="10">
    <parameter identifier="f">
      <class>Fibonacci</class>
    </parameter>
    <java:condition>f.getValue() == -1</java:condition>
    <java:consequence>
      System.err.println( "recurse for " + f.getSequence() );
      drools.assertObject( new Fibonacci( f.getSequence() - 1 ) );
    </java:consequence>
  </rule>
  
  <rule name="Bootstrap 1" salience="20">
    <parameter identifier="f">
      <class>Fibonacci</class>
    </parameter>

    <java:condition>f.getSequence() == 1</java:condition>
    <java:condition>f.getValue() == -1</java:condition>
    <java:consequence>
      f.setValue( 1 );
      System.err.println( f.getSequence() + " == " + f.getValue() );
      drools.modifyObject( f );
    </java:consequence>
  </rule>
  
  <rule name="Bootstrap 2">
    <parameter identifier="f">
      <class>Fibonacci</class>
    </parameter>
    <java:condition>f.getSequence() == 2</java:condition>
    <java:condition>f.getValue() == -1</java:condition>
    <java:consequence>
      f.setValue( 1 );
      System.err.println( f.getSequence() + " == " + f.getValue() );
      drools.modifyObject( f );
    </java:consequence>
  </rule>
  
  <rule name="Calculate">
    <parameter identifier="f1">
      <java:class>Fibonacci</java:class>
    </parameter>
    <parameter identifier="f2">
      <java:class>Fibonacci</java:class>
    </parameter>
    <parameter identifier="f3">
      <java:class>Fibonacci</java:class>
    </parameter>
    <java:condition>f2.getSequence() == (f1.getSequence() + 1)</java:condition>
    <java:condition>f3.getSequence() == (f2.getSequence() + 1)</java:condition>
    <java:condition>f1.getValue() != -1</java:condition>
    <java:condition>f2.getValue() != -1</java:condition>
    <java:condition>f3.getValue() == -1</java:condition>
    <java:consequence>
      f3.setValue( f1.getValue() + f2.getValue() );
      System.err.println( f3.getSequence() + " == " + f3.getValue() );
      drools.modifyObject( f3 );
      drools.retractObject( f1 );
    </java:consequence>
  </rule>

</rule-set>

Posted in Library | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |