drools サンプルプログラム2

集合の中から条件にマッチするものを抽出する。

  • プログラムの概要
    • サンプルプログラム1と同様のFactを利用します。与えられたファクトのなかから年齢が一番高い人と低い人の名前と年齢を出力するプログラムです。
  • 実行プログラム(MaxAge.java)
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public class MaxAge {

	public static final void main(String[] args) {
		try {
			KnowledgeBase kbase = readKnowledgeBase();
			StatefulKnowledgeSession ksession = kbase
					.newStatefulKnowledgeSession();
			KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
					.newFileLogger(ksession, "test");
			
			ksession.insert(new Profile("uzr",31));
			ksession.insert(new Profile("hoge",19));
			ksession.insert(new Profile("moge",25));
			ksession.insert(new Profile("huga",23));
			ksession.fireAllRules();
			
			logger.close();
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}

	private static KnowledgeBase readKnowledgeBase() throws Exception {
		
		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
				.newKnowledgeBuilder();
		
		kbuilder.add(ResourceFactory.newClassPathResource("sample2/MaxAge.drl"),
				ResourceType.DRL);

		KnowledgeBuilderErrors errors = kbuilder.getErrors();
		if (errors.size() > 0) {
			for (KnowledgeBuilderError error : errors) {
				System.err.println(error);
			}
			throw new IllegalArgumentException("Could not parse knowledge.");
		}
		
		KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
		kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
		
		return kbase;
	}
}
  • ルール(MaxAge.dsl)
    • forall・・・は全てのファクトはmaxage以下の年齢であることを現します。→forall
rule "年齢が一番高い人を抽出するルール"
	when
            memMaxAge:Profile(maxage:age)
            forall(Profile(age<=maxage))
	then
        System.out.println("年齢が一番高いのは"
		  + memMaxAge.getName()
		  + "さんで、年齢は" + memMaxAge.getAge() + "歳です"); 
end

rule "年齢が一番低い人を抽出するルール"
    when
            memMinAge:Profile(minage:age)
            forall(Profile(age>=minage))
    then
        System.out.println("年齢が一番低いのは"
          + memMinAge.getName()
          + "さんで、年齢は" + memMinAge.getAge() + "歳です"); 
end
  • 実行結果
年齢が一番低いのはhogeさんで、年齢は19歳です
年齢が一番高いのはuzrさんで、年齢は31歳です

ひとつのルールに対して結果が二つ返ってきたらどうなるのでしょう。hogehogeさん19歳をファクトとして追加して実行してみた結果がこちら。

年齢が一番低いのはhogehogeさんで、年齢は19歳です
年齢が一番低いのはhogeさんで、年齢は19歳です
年齢が一番高いのはuzrさんで、年齢は31歳です